Core/Serialization: Add bit serialization
Former-commit-id: dbaf3a2d40a85955b4d48efba72a5df9d92d0eb1
This commit is contained in:
parent
c93e4e901e
commit
7f220ce48c
|
|
@ -80,14 +80,33 @@ namespace Nz
|
||||||
|
|
||||||
inline bool Serialize(SerializationContext& context, bool value)
|
inline bool Serialize(SerializationContext& context, bool value)
|
||||||
{
|
{
|
||||||
///TODO: Handle bits writing (Serializing 8 bits should only use one byte)
|
if (context.currentBitPos == 8)
|
||||||
UInt8 buffer = (value) ? 1 : 0;
|
{
|
||||||
return context.stream->Write(&buffer, 1) == 1;
|
context.currentBitPos = 0;
|
||||||
|
context.currentByte = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
context.currentByte |= 1 << context.currentBitPos;
|
||||||
|
|
||||||
|
if (++context.currentBitPos >= 8)
|
||||||
|
return Serialize<UInt8>(context, context.currentByte);
|
||||||
|
else
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value)
|
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value)
|
||||||
{
|
{
|
||||||
|
// Flush bits if a writing is in progress
|
||||||
|
if (context.currentBitPos != 8)
|
||||||
|
{
|
||||||
|
context.currentBitPos = 8;
|
||||||
|
|
||||||
|
if (!Serialize<UInt8>(context, context.currentByte))
|
||||||
|
NazaraWarning("Failed to flush bits");
|
||||||
|
}
|
||||||
|
|
||||||
if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness())
|
if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness())
|
||||||
SwapBytes(&value, sizeof(T));
|
SwapBytes(&value, sizeof(T));
|
||||||
|
|
||||||
|
|
@ -98,14 +117,20 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NazaraAssert(value, "Invalid data pointer");
|
NazaraAssert(value, "Invalid data pointer");
|
||||||
|
|
||||||
UInt8 buffer;
|
if (context.currentBitPos == 8)
|
||||||
if (context.stream->Read(&buffer, 1) == 1)
|
|
||||||
{
|
{
|
||||||
*value = (buffer == 1);
|
if (!Unserialize(context, &context.currentByte))
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
context.currentBitPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
*value = (context.currentByte & (1 << context.currentBitPos)) != 0;
|
||||||
|
|
||||||
|
context.currentBitPos++;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
@ -113,6 +138,9 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NazaraAssert(value, "Invalid data pointer");
|
NazaraAssert(value, "Invalid data pointer");
|
||||||
|
|
||||||
|
// Reset bit position
|
||||||
|
context.currentBitPos = 8;
|
||||||
|
|
||||||
if (context.stream->Read(value, sizeof(T)) == sizeof(T))
|
if (context.stream->Read(value, sizeof(T)) == sizeof(T))
|
||||||
{
|
{
|
||||||
if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness())
|
if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness())
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,16 @@ namespace Nz
|
||||||
{
|
{
|
||||||
Stream* stream;
|
Stream* stream;
|
||||||
Endianness endianness;
|
Endianness endianness;
|
||||||
|
UInt8 currentBitPos;
|
||||||
|
UInt8 currentByte;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UnserializationContext
|
struct UnserializationContext
|
||||||
{
|
{
|
||||||
Stream* stream;
|
Stream* stream;
|
||||||
Endianness endianness;
|
Endianness endianness;
|
||||||
|
UInt8 currentBitPos;
|
||||||
|
UInt8 currentByte;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace Nz
|
||||||
inline Serializer(Stream& stream);
|
inline Serializer(Stream& stream);
|
||||||
Serializer(const Serializer&) = default;
|
Serializer(const Serializer&) = default;
|
||||||
Serializer(Serializer&&) = default;
|
Serializer(Serializer&&) = default;
|
||||||
~Serializer() = default;
|
~Serializer();
|
||||||
|
|
||||||
inline Endianness GetDataEndianness() const;
|
inline Endianness GetDataEndianness() const;
|
||||||
inline Stream& GetStream() const;
|
inline Stream& GetStream() const;
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,29 @@
|
||||||
// This file is part of the "Nazara Engine - Core module"
|
// This file is part of the "Nazara Engine - Core module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Core/Algorithm.hpp>
|
||||||
#include <Nazara/Core/Debug.hpp>
|
#include <Nazara/Core/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline Serializer::Serializer(Stream& stream)
|
inline Serializer::Serializer(Stream& stream)
|
||||||
{
|
{
|
||||||
|
m_serializationContext.currentBitPos = 8;
|
||||||
m_serializationContext.endianness = Endianness_BigEndian;
|
m_serializationContext.endianness = Endianness_BigEndian;
|
||||||
m_serializationContext.stream = &stream;
|
m_serializationContext.stream = &stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Serializer::~Serializer()
|
||||||
|
{
|
||||||
|
if (m_serializationContext.currentBitPos != 8)
|
||||||
|
{
|
||||||
|
m_serializationContext.currentBitPos = 8; //< To prevent Serialize to flush bits itself
|
||||||
|
|
||||||
|
if (!Serialize<UInt8>(m_serializationContext, m_serializationContext.currentByte))
|
||||||
|
NazaraWarning("Failed to flush bits at serializer destruction");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline Endianness Serializer::GetDataEndianness() const
|
inline Endianness Serializer::GetDataEndianness() const
|
||||||
{
|
{
|
||||||
return m_serializationContext.endianness;
|
return m_serializationContext.endianness;
|
||||||
|
|
@ -43,3 +56,4 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/Core/DebugOff.hpp>
|
#include <Nazara/Core/DebugOff.hpp>
|
||||||
|
#include "Serializer.hpp"
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
|
#include "Stream.hpp"
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
|
@ -70,5 +71,4 @@ namespace Nz
|
||||||
|
|
||||||
return WriteBlock(buffer, size);
|
return WriteBlock(buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
inline Unserializer::Unserializer(Stream& stream)
|
inline Unserializer::Unserializer(Stream& stream)
|
||||||
{
|
{
|
||||||
|
m_unserializationContext.currentBitPos = 8;
|
||||||
m_unserializationContext.endianness = Endianness_BigEndian;
|
m_unserializationContext.endianness = Endianness_BigEndian;
|
||||||
m_unserializationContext.stream = &stream;
|
m_unserializationContext.stream = &stream;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue