From 3fb9e5736039e5be91bf873212c78be951f2ac49 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 18 Nov 2015 18:49:38 +0100 Subject: [PATCH] Core/Serialization: Add correct endianness handling Core/File: Remove endianness handling Former-commit-id: 6f7bba52057f36c507a024f7a7ea873658a3cfd3 --- include/Nazara/Core/Algorithm.hpp | 8 ++--- include/Nazara/Core/Algorithm.inl | 33 ++++++++++-------- include/Nazara/Core/Endianness.hpp | 2 +- include/Nazara/Core/Endianness.inl | 2 +- include/Nazara/Core/File.hpp | 3 -- include/Nazara/Core/InputStream.inl | 2 +- include/Nazara/Core/OutputStream.inl | 2 +- include/Nazara/Core/Stream.hpp | 8 +++-- include/Nazara/Core/Stream.inl | 11 ++++++ include/Nazara/Core/String.hpp | 5 +-- src/Nazara/Core/File.cpp | 50 ---------------------------- src/Nazara/Core/String.cpp | 8 ++--- 12 files changed, 51 insertions(+), 83 deletions(-) diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index a00d81280..2f4d770d0 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -29,15 +29,15 @@ namespace Nz template struct TypeTag {}; - inline bool Serialize(OutputStream* output, bool value); + inline bool Serialize(OutputStream* output, bool value, Endianness dataEndianness); template - std::enable_if_t::value, bool> Serialize(OutputStream* output, T value); + std::enable_if_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 - std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value); + std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value, Endianness dataEndianness); } #include diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index c6fbb4fb1..6fed14897 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -77,21 +77,25 @@ namespace Nz seed = static_cast(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; return output->Write(&buffer, 1) == 1; } template - std::enable_if_t::value, bool> Serialize(OutputStream* output, T value) + std::enable_if_t::value, bool> Serialize(OutputStream* output, T value, Endianness dataEndianness) { + NazaraAssert(output, "Invalid stream"); + if (output->Write(&value, sizeof(T)) == sizeof(T)) { - // Write down everything as little endian - #if NAZARA_BIG_ENDIAN - SwapBytes(&value, sizeof(T)); - #endif + if (dataEndianness != Endianness_Unknown && dataEndianness != GetPlatformEndianness()) + SwapBytes(&value, sizeof(T)); return true; } @@ -99,9 +103,11 @@ namespace Nz 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; if (input->Read(&buffer, 1) == 1) @@ -114,16 +120,15 @@ namespace Nz } template - std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value) + std::enable_if_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)) { - // Write down everything as little endian - #if NAZARA_BIG_ENDIAN - SwapBytes(&value, sizeof(T)); - #endif + if (dataEndianness != Endianness_Unknown && dataEndianness != GetPlatformEndianness()) + SwapBytes(&value, sizeof(T)); return true; } diff --git a/include/Nazara/Core/Endianness.hpp b/include/Nazara/Core/Endianness.hpp index a97687dac..62cac093d 100644 --- a/include/Nazara/Core/Endianness.hpp +++ b/include/Nazara/Core/Endianness.hpp @@ -27,7 +27,7 @@ namespace Nz { - inline Endianness GetPlatformEndianness(); + inline constexpr Endianness GetPlatformEndianness(); inline void SwapBytes(void* buffer, unsigned int size); } diff --git a/include/Nazara/Core/Endianness.inl b/include/Nazara/Core/Endianness.inl index 3d489c567..96e4fdf8a 100644 --- a/include/Nazara/Core/Endianness.inl +++ b/include/Nazara/Core/Endianness.inl @@ -7,7 +7,7 @@ namespace Nz { - inline Endianness GetPlatformEndianness() + inline constexpr Endianness GetPlatformEndianness() { #if defined(NAZARA_BIG_ENDIAN) return Endianness_BigEndian; diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index 18ed54b98..c3dde211c 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -64,7 +64,6 @@ namespace Nz 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 typeSize, unsigned int count); bool Rename(const String& newFilePath); bool SetCursorPos(CursorPosition pos, Int64 offset = 0); @@ -74,7 +73,6 @@ namespace Nz 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 typeSize, unsigned int count); File& operator=(const String& filePath); File& operator=(const File&) = delete; @@ -99,7 +97,6 @@ namespace Nz private: NazaraMutexAttrib(m_mutex, mutable) - Endianness m_endianness; String m_filePath; FileImpl* m_impl; }; diff --git a/include/Nazara/Core/InputStream.inl b/include/Nazara/Core/InputStream.inl index a9a796032..4e8abe925 100644 --- a/include/Nazara/Core/InputStream.inl +++ b/include/Nazara/Core/InputStream.inl @@ -14,7 +14,7 @@ namespace Nz template InputStream& InputStream::operator>>(T& value) { - if (!Unserialize(this, &value)) + if (!Unserialize(this, &value, m_dataEndianness)) NazaraError("Failed to unserialize value"); return *this; diff --git a/include/Nazara/Core/OutputStream.inl b/include/Nazara/Core/OutputStream.inl index 098f012b7..95f0f03e0 100644 --- a/include/Nazara/Core/OutputStream.inl +++ b/include/Nazara/Core/OutputStream.inl @@ -14,7 +14,7 @@ namespace Nz template OutputStream& OutputStream::operator<<(const T& value) { - if (!Serialize(this, value)) + if (!Serialize(this, value, m_dataEndianness)) NazaraError("Failed to serialize value"); return *this; diff --git a/include/Nazara/Core/Stream.hpp b/include/Nazara/Core/Stream.hpp index 85095e324..0abaaab63 100644 --- a/include/Nazara/Core/Stream.hpp +++ b/include/Nazara/Core/Stream.hpp @@ -8,6 +8,7 @@ #define NAZARA_STREAM_HPP #include +#include #include namespace Nz @@ -24,6 +25,7 @@ namespace Nz virtual UInt64 GetCursorPos() const = 0; virtual String GetDirectory() const; virtual String GetPath() const; + inline Endianness GetDataEndianness() const; inline UInt32 GetOpenMode() const; inline UInt32 GetStreamOptions() const; @@ -31,14 +33,16 @@ namespace Nz inline bool IsWritable() const; 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=(Stream&&) = default; protected: inline Stream(UInt32 openMode); - + + Endianness m_dataEndianness; UInt32 m_openMode; UInt32 m_streamOptions; }; diff --git a/include/Nazara/Core/Stream.inl b/include/Nazara/Core/Stream.inl index 905c9276e..4c9bb138f 100644 --- a/include/Nazara/Core/Stream.inl +++ b/include/Nazara/Core/Stream.inl @@ -5,11 +5,17 @@ namespace Nz { inline Stream::Stream(UInt32 openMode) : + m_dataEndianness(Endianness_Unknown), m_openMode(openMode), m_streamOptions(0) { } + inline Endianness Stream::GetDataEndianness() const + { + return m_dataEndianness; + } + inline UInt32 Stream::GetOpenMode() const { return m_openMode; @@ -30,6 +36,11 @@ namespace Nz return m_openMode & OpenMode_ReadWrite || m_openMode & OpenMode_WriteOnly; } + inline void Stream::SetDataEndianness(Endianness endiannes) + { + m_dataEndianness = endiannes; + } + inline void Stream::SetStreamOptions(UInt32 options) { m_streamOptions = options; diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index c48e2552b..17ef58aab 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -8,6 +8,7 @@ #define NAZARA_STRING_HPP #include +#include #include #include #include @@ -326,8 +327,8 @@ namespace Nz }; inline bool HashAppend(AbstractHash* hash, const String& string); - NAZARA_CORE_API bool Serialize(OutputStream* output, const String& string); - NAZARA_CORE_API bool Unserialize(InputStream* input, String* string); + NAZARA_CORE_API bool Serialize(OutputStream* output, const String& string, Endianness dataEndianness); + NAZARA_CORE_API bool Unserialize(InputStream* input, String* string, Endianness dataEndianness); } namespace std diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index eedfc99a6..cc5674d2f 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -32,7 +32,6 @@ namespace Nz { File::File() : Stream(OpenMode_Current), - m_endianness(Endianness_Unknown), m_impl(nullptr) { } @@ -53,7 +52,6 @@ namespace Nz Stream(std::move(file)), InputStream(std::move(file)), OutputStream(std::move(file)), - m_endianness(file.m_endianness), m_filePath(std::move(file.m_filePath)), 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(buffer) + i*typeSize, typeSize); - } - - return byteRead; - } - bool File::Rename(const String& newFilePath) { NazaraLock(m_mutex) @@ -311,13 +293,6 @@ namespace Nz return m_impl->SetCursorPos(CursorPosition_AtBegin, offset); } - void File::SetEndianness(Endianness endianness) - { - NazaraLock(m_mutex) - - m_endianness = endianness; - } - bool File::SetFile(const String& filePath) { NazaraLock(m_mutex) @@ -359,29 +334,6 @@ namespace Nz 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 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) { SetFile(filePath); @@ -393,10 +345,8 @@ namespace Nz { NazaraLock(m_mutex) - std::swap(m_endianness, file.m_endianness); std::swap(m_filePath, file.m_filePath); std::swap(m_impl, file.m_impl); - std::swap(m_openMode, file.m_openMode); return *this; } diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 8aa2e5da7..6ad60a3cb 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -4209,19 +4209,19 @@ namespace Nz return emptyString; } - bool Serialize(OutputStream* output, const String& string) + bool Serialize(OutputStream* output, const String& string, Endianness dataEndianness) { - if (!Serialize(output, string.GetSize())) + if (!Serialize(output, string.GetSize(), dataEndianness)) return false; output->Write(string.GetConstBuffer(), string.GetSize()); return true; } - bool Unserialize(InputStream* input, String* string) + bool Unserialize(InputStream* input, String* string, Endianness dataEndianness) { UInt32 size; - if (!Unserialize(input, &size)) + if (!Unserialize(input, &size, dataEndianness)) return false; string->Resize(size);