Core/Serialization: Add correct endianness handling
Core/File: Remove endianness handling Former-commit-id: 6f7bba52057f36c507a024f7a7ea873658a3cfd3
This commit is contained in:
parent
be01b6f3b4
commit
3fb9e57360
|
|
@ -29,15 +29,15 @@ namespace Nz
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct TypeTag {};
|
struct TypeTag {};
|
||||||
|
|
||||||
inline bool Serialize(OutputStream* output, bool value);
|
inline bool Serialize(OutputStream* output, bool value, Endianness dataEndianness);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(OutputStream* output, T value);
|
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(OutputStream* output, T value, Endianness dataEndianness);
|
||||||
|
|
||||||
inline bool Unserialize(InputStream* input, bool* value);
|
inline bool Unserialize(InputStream* input, bool* value, Endianness dataEndianness);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(InputStream* input, T* value);
|
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(InputStream* input, T* value, Endianness dataEndianness);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/Core/Algorithm.inl>
|
#include <Nazara/Core/Algorithm.inl>
|
||||||
|
|
|
||||||
|
|
@ -77,21 +77,25 @@ namespace Nz
|
||||||
seed = static_cast<std::size_t>(b * kMul);
|
seed = static_cast<std::size_t>(b * kMul);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Serialize(OutputStream* output, bool value)
|
inline bool Serialize(OutputStream* output, bool value, Endianness dataEndianness)
|
||||||
{
|
{
|
||||||
|
NazaraAssert(output, "Invalid stream");
|
||||||
|
NazaraUnused(dataEndianness);
|
||||||
|
|
||||||
|
///TODO: Handle bits writing (Serializing 8 bits should only use one byte)
|
||||||
UInt8 buffer = (value) ? 1 : 0;
|
UInt8 buffer = (value) ? 1 : 0;
|
||||||
return output->Write(&buffer, 1) == 1;
|
return output->Write(&buffer, 1) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(OutputStream* output, T value)
|
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(OutputStream* output, T value, Endianness dataEndianness)
|
||||||
{
|
{
|
||||||
|
NazaraAssert(output, "Invalid stream");
|
||||||
|
|
||||||
if (output->Write(&value, sizeof(T)) == sizeof(T))
|
if (output->Write(&value, sizeof(T)) == sizeof(T))
|
||||||
{
|
{
|
||||||
// Write down everything as little endian
|
if (dataEndianness != Endianness_Unknown && dataEndianness != GetPlatformEndianness())
|
||||||
#if NAZARA_BIG_ENDIAN
|
SwapBytes(&value, sizeof(T));
|
||||||
SwapBytes(&value, sizeof(T));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -99,9 +103,11 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Unserialize(InputStream* input, bool* value)
|
inline bool Unserialize(InputStream* input, bool* value, Endianness dataEndianness)
|
||||||
{
|
{
|
||||||
NazaraAssert(value, "Invalid pointer");
|
NazaraAssert(input, "Invalid stream");
|
||||||
|
NazaraAssert(value, "Invalid data pointer");
|
||||||
|
NazaraUnused(dataEndianness);
|
||||||
|
|
||||||
UInt8 buffer;
|
UInt8 buffer;
|
||||||
if (input->Read(&buffer, 1) == 1)
|
if (input->Read(&buffer, 1) == 1)
|
||||||
|
|
@ -114,16 +120,15 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(InputStream* input, T* value)
|
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(InputStream* input, T* value, Endianness dataEndianness)
|
||||||
{
|
{
|
||||||
NazaraAssert(value, "Invalid pointer");
|
NazaraAssert(input, "Invalid stream");
|
||||||
|
NazaraAssert(value, "Invalid data pointer");
|
||||||
|
|
||||||
if (input->Read(value, sizeof(T)) == sizeof(T))
|
if (input->Read(value, sizeof(T)) == sizeof(T))
|
||||||
{
|
{
|
||||||
// Write down everything as little endian
|
if (dataEndianness != Endianness_Unknown && dataEndianness != GetPlatformEndianness())
|
||||||
#if NAZARA_BIG_ENDIAN
|
SwapBytes(&value, sizeof(T));
|
||||||
SwapBytes(&value, sizeof(T));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline Endianness GetPlatformEndianness();
|
inline constexpr Endianness GetPlatformEndianness();
|
||||||
inline void SwapBytes(void* buffer, unsigned int size);
|
inline void SwapBytes(void* buffer, unsigned int size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline Endianness GetPlatformEndianness()
|
inline constexpr Endianness GetPlatformEndianness()
|
||||||
{
|
{
|
||||||
#if defined(NAZARA_BIG_ENDIAN)
|
#if defined(NAZARA_BIG_ENDIAN)
|
||||||
return Endianness_BigEndian;
|
return Endianness_BigEndian;
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,6 @@ namespace Nz
|
||||||
bool Open(const String& filePath, unsigned int openMode = OpenMode_Current);
|
bool Open(const String& filePath, unsigned int openMode = OpenMode_Current);
|
||||||
|
|
||||||
std::size_t Read(void* buffer, std::size_t size) override;
|
std::size_t Read(void* buffer, std::size_t size) override;
|
||||||
std::size_t Read(void* buffer, std::size_t typeSize, unsigned int count);
|
|
||||||
bool Rename(const String& newFilePath);
|
bool Rename(const String& newFilePath);
|
||||||
|
|
||||||
bool SetCursorPos(CursorPosition pos, Int64 offset = 0);
|
bool SetCursorPos(CursorPosition pos, Int64 offset = 0);
|
||||||
|
|
@ -74,7 +73,6 @@ namespace Nz
|
||||||
|
|
||||||
using OutputStream::Write;
|
using OutputStream::Write;
|
||||||
std::size_t Write(const void* buffer, std::size_t size) override;
|
std::size_t Write(const void* buffer, std::size_t size) override;
|
||||||
std::size_t Write(const void* buffer, std::size_t typeSize, unsigned int count);
|
|
||||||
|
|
||||||
File& operator=(const String& filePath);
|
File& operator=(const String& filePath);
|
||||||
File& operator=(const File&) = delete;
|
File& operator=(const File&) = delete;
|
||||||
|
|
@ -99,7 +97,6 @@ namespace Nz
|
||||||
private:
|
private:
|
||||||
NazaraMutexAttrib(m_mutex, mutable)
|
NazaraMutexAttrib(m_mutex, mutable)
|
||||||
|
|
||||||
Endianness m_endianness;
|
|
||||||
String m_filePath;
|
String m_filePath;
|
||||||
FileImpl* m_impl;
|
FileImpl* m_impl;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ namespace Nz
|
||||||
template<typename T>
|
template<typename T>
|
||||||
InputStream& InputStream::operator>>(T& value)
|
InputStream& InputStream::operator>>(T& value)
|
||||||
{
|
{
|
||||||
if (!Unserialize(this, &value))
|
if (!Unserialize(this, &value, m_dataEndianness))
|
||||||
NazaraError("Failed to unserialize value");
|
NazaraError("Failed to unserialize value");
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ namespace Nz
|
||||||
template<typename T>
|
template<typename T>
|
||||||
OutputStream& OutputStream::operator<<(const T& value)
|
OutputStream& OutputStream::operator<<(const T& value)
|
||||||
{
|
{
|
||||||
if (!Serialize(this, value))
|
if (!Serialize(this, value, m_dataEndianness))
|
||||||
NazaraError("Failed to serialize value");
|
NazaraError("Failed to serialize value");
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#define NAZARA_STREAM_HPP
|
#define NAZARA_STREAM_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
#include <Nazara/Core/Endianness.hpp>
|
||||||
#include <Nazara/Core/Enums.hpp>
|
#include <Nazara/Core/Enums.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
|
|
@ -24,6 +25,7 @@ namespace Nz
|
||||||
virtual UInt64 GetCursorPos() const = 0;
|
virtual UInt64 GetCursorPos() const = 0;
|
||||||
virtual String GetDirectory() const;
|
virtual String GetDirectory() const;
|
||||||
virtual String GetPath() const;
|
virtual String GetPath() const;
|
||||||
|
inline Endianness GetDataEndianness() const;
|
||||||
inline UInt32 GetOpenMode() const;
|
inline UInt32 GetOpenMode() const;
|
||||||
inline UInt32 GetStreamOptions() const;
|
inline UInt32 GetStreamOptions() const;
|
||||||
|
|
||||||
|
|
@ -31,14 +33,16 @@ namespace Nz
|
||||||
inline bool IsWritable() const;
|
inline bool IsWritable() const;
|
||||||
|
|
||||||
virtual bool SetCursorPos(UInt64 offset) = 0;
|
virtual bool SetCursorPos(UInt64 offset) = 0;
|
||||||
void SetStreamOptions(UInt32 options);
|
inline void SetDataEndianness(Endianness endiannes);
|
||||||
|
inline void SetStreamOptions(UInt32 options);
|
||||||
|
|
||||||
Stream& operator=(const Stream&) = default;
|
Stream& operator=(const Stream&) = default;
|
||||||
Stream& operator=(Stream&&) = default;
|
Stream& operator=(Stream&&) = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
inline Stream(UInt32 openMode);
|
inline Stream(UInt32 openMode);
|
||||||
|
|
||||||
|
Endianness m_dataEndianness;
|
||||||
UInt32 m_openMode;
|
UInt32 m_openMode;
|
||||||
UInt32 m_streamOptions;
|
UInt32 m_streamOptions;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,17 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline Stream::Stream(UInt32 openMode) :
|
inline Stream::Stream(UInt32 openMode) :
|
||||||
|
m_dataEndianness(Endianness_Unknown),
|
||||||
m_openMode(openMode),
|
m_openMode(openMode),
|
||||||
m_streamOptions(0)
|
m_streamOptions(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Endianness Stream::GetDataEndianness() const
|
||||||
|
{
|
||||||
|
return m_dataEndianness;
|
||||||
|
}
|
||||||
|
|
||||||
inline UInt32 Stream::GetOpenMode() const
|
inline UInt32 Stream::GetOpenMode() const
|
||||||
{
|
{
|
||||||
return m_openMode;
|
return m_openMode;
|
||||||
|
|
@ -30,6 +36,11 @@ namespace Nz
|
||||||
return m_openMode & OpenMode_ReadWrite || m_openMode & OpenMode_WriteOnly;
|
return m_openMode & OpenMode_ReadWrite || m_openMode & OpenMode_WriteOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Stream::SetDataEndianness(Endianness endiannes)
|
||||||
|
{
|
||||||
|
m_dataEndianness = endiannes;
|
||||||
|
}
|
||||||
|
|
||||||
inline void Stream::SetStreamOptions(UInt32 options)
|
inline void Stream::SetStreamOptions(UInt32 options)
|
||||||
{
|
{
|
||||||
m_streamOptions = options;
|
m_streamOptions = options;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#define NAZARA_STRING_HPP
|
#define NAZARA_STRING_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
#include <Nazara/Core/Endianness.hpp>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
@ -326,8 +327,8 @@ namespace Nz
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool HashAppend(AbstractHash* hash, const String& string);
|
inline bool HashAppend(AbstractHash* hash, const String& string);
|
||||||
NAZARA_CORE_API bool Serialize(OutputStream* output, const String& string);
|
NAZARA_CORE_API bool Serialize(OutputStream* output, const String& string, Endianness dataEndianness);
|
||||||
NAZARA_CORE_API bool Unserialize(InputStream* input, String* string);
|
NAZARA_CORE_API bool Unserialize(InputStream* input, String* string, Endianness dataEndianness);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ namespace Nz
|
||||||
{
|
{
|
||||||
File::File() :
|
File::File() :
|
||||||
Stream(OpenMode_Current),
|
Stream(OpenMode_Current),
|
||||||
m_endianness(Endianness_Unknown),
|
|
||||||
m_impl(nullptr)
|
m_impl(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +52,6 @@ namespace Nz
|
||||||
Stream(std::move(file)),
|
Stream(std::move(file)),
|
||||||
InputStream(std::move(file)),
|
InputStream(std::move(file)),
|
||||||
OutputStream(std::move(file)),
|
OutputStream(std::move(file)),
|
||||||
m_endianness(file.m_endianness),
|
|
||||||
m_filePath(std::move(file.m_filePath)),
|
m_filePath(std::move(file.m_filePath)),
|
||||||
m_impl(file.m_impl)
|
m_impl(file.m_impl)
|
||||||
{
|
{
|
||||||
|
|
@ -219,22 +217,6 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t File::Read(void* buffer, std::size_t typeSize, unsigned int count)
|
|
||||||
{
|
|
||||||
std::size_t byteRead = Read(buffer, typeSize*count);
|
|
||||||
if (byteRead == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (buffer && typeSize != 1 && m_endianness != Endianness_Unknown && m_endianness != GetPlatformEndianness())
|
|
||||||
{
|
|
||||||
unsigned int typeCount = byteRead/typeSize;
|
|
||||||
for (unsigned int i = 0; i < typeCount; ++i)
|
|
||||||
SwapBytes(reinterpret_cast<UInt8*>(buffer) + i*typeSize, typeSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
return byteRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File::Rename(const String& newFilePath)
|
bool File::Rename(const String& newFilePath)
|
||||||
{
|
{
|
||||||
NazaraLock(m_mutex)
|
NazaraLock(m_mutex)
|
||||||
|
|
@ -311,13 +293,6 @@ namespace Nz
|
||||||
return m_impl->SetCursorPos(CursorPosition_AtBegin, offset);
|
return m_impl->SetCursorPos(CursorPosition_AtBegin, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void File::SetEndianness(Endianness endianness)
|
|
||||||
{
|
|
||||||
NazaraLock(m_mutex)
|
|
||||||
|
|
||||||
m_endianness = endianness;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File::SetFile(const String& filePath)
|
bool File::SetFile(const String& filePath)
|
||||||
{
|
{
|
||||||
NazaraLock(m_mutex)
|
NazaraLock(m_mutex)
|
||||||
|
|
@ -359,29 +334,6 @@ namespace Nz
|
||||||
return m_impl->Write(buffer, size);
|
return m_impl->Write(buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t File::Write(const void* buffer, std::size_t typeSize, unsigned int count)
|
|
||||||
{
|
|
||||||
if (count == 0 || typeSize == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
NazaraAssert(buffer, "Invalid buffer");
|
|
||||||
|
|
||||||
NazaraLock(m_mutex)
|
|
||||||
|
|
||||||
if (m_endianness != Endianness_Unknown && m_endianness != GetPlatformEndianness() && typeSize != 1)
|
|
||||||
{
|
|
||||||
std::unique_ptr<char[]> buf(new char[count*typeSize]);
|
|
||||||
std::memcpy(buf.get(), buffer, count*typeSize);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
|
||||||
SwapBytes(&buf[i*typeSize], typeSize);
|
|
||||||
|
|
||||||
return Write(buf.get(), count*typeSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return Write(buffer, count*typeSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
File& File::operator=(const String& filePath)
|
File& File::operator=(const String& filePath)
|
||||||
{
|
{
|
||||||
SetFile(filePath);
|
SetFile(filePath);
|
||||||
|
|
@ -393,10 +345,8 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NazaraLock(m_mutex)
|
NazaraLock(m_mutex)
|
||||||
|
|
||||||
std::swap(m_endianness, file.m_endianness);
|
|
||||||
std::swap(m_filePath, file.m_filePath);
|
std::swap(m_filePath, file.m_filePath);
|
||||||
std::swap(m_impl, file.m_impl);
|
std::swap(m_impl, file.m_impl);
|
||||||
std::swap(m_openMode, file.m_openMode);
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4209,19 +4209,19 @@ namespace Nz
|
||||||
return emptyString;
|
return emptyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serialize(OutputStream* output, const String& string)
|
bool Serialize(OutputStream* output, const String& string, Endianness dataEndianness)
|
||||||
{
|
{
|
||||||
if (!Serialize<UInt32>(output, string.GetSize()))
|
if (!Serialize<UInt32>(output, string.GetSize(), dataEndianness))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
output->Write(string.GetConstBuffer(), string.GetSize());
|
output->Write(string.GetConstBuffer(), string.GetSize());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unserialize(InputStream* input, String* string)
|
bool Unserialize(InputStream* input, String* string, Endianness dataEndianness)
|
||||||
{
|
{
|
||||||
UInt32 size;
|
UInt32 size;
|
||||||
if (!Unserialize(input, &size))
|
if (!Unserialize(input, &size, dataEndianness))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
string->Resize(size);
|
string->Resize(size);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue