From be01b6f3b4b18aba29f2677b1ef93798b1ab1fda Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 18 Nov 2015 18:29:20 +0100 Subject: [PATCH] Core: Add serialization interface Former-commit-id: cfa749dba1b6f23ef8f38519e0bc9ad9492e3db3 --- include/Nazara/Core/Algorithm.hpp | 10 +++++ include/Nazara/Core/Algorithm.inl | 55 ++++++++++++++++++++++++++++ include/Nazara/Core/InputStream.hpp | 3 ++ include/Nazara/Core/InputStream.inl | 11 ++++++ include/Nazara/Core/OutputStream.hpp | 6 +++ include/Nazara/Core/OutputStream.inl | 11 ++++++ include/Nazara/Core/Stream.hpp | 3 +- include/Nazara/Core/String.hpp | 5 ++- src/Nazara/Core/Stream.cpp | 1 + src/Nazara/Core/String.cpp | 21 +++++++++++ 10 files changed, 124 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index d70aff30b..a00d81280 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -9,8 +9,11 @@ #include #include +#include +#include #include #include +#include namespace Nz { @@ -26,8 +29,15 @@ namespace Nz template struct TypeTag {}; + inline bool Serialize(OutputStream* output, bool value); template + std::enable_if_t::value, bool> Serialize(OutputStream* output, T value); + + inline bool Unserialize(InputStream* input, bool* value); + + template + std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value); } #include diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 3912f615a..c6fbb4fb1 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -7,6 +7,7 @@ // Merci aussi à Freedom de siteduzero.com #include +#include #include namespace Nz @@ -75,6 +76,60 @@ namespace Nz seed = static_cast(b * kMul); } + + inline bool Serialize(OutputStream* output, bool value) + { + UInt8 buffer = (value) ? 1 : 0; + return output->Write(&buffer, 1) == 1; + } + + template + std::enable_if_t::value, bool> Serialize(OutputStream* output, T value) + { + if (output->Write(&value, sizeof(T)) == sizeof(T)) + { + // Write down everything as little endian + #if NAZARA_BIG_ENDIAN + SwapBytes(&value, sizeof(T)); + #endif + + return true; + } + else + return false; + } + + inline bool Unserialize(InputStream* input, bool* value) + { + NazaraAssert(value, "Invalid pointer"); + + UInt8 buffer; + if (input->Read(&buffer, 1) == 1) + { + *value = (buffer == 1); + return true; + } + else + return false; + } + + template + std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value) + { + NazaraAssert(value, "Invalid pointer"); + + if (input->Read(value, sizeof(T)) == sizeof(T)) + { + // Write down everything as little endian + #if NAZARA_BIG_ENDIAN + SwapBytes(&value, sizeof(T)); + #endif + + return true; + } + else + return false; + } } #include diff --git a/include/Nazara/Core/InputStream.hpp b/include/Nazara/Core/InputStream.hpp index 9bd66f91b..f431afe14 100644 --- a/include/Nazara/Core/InputStream.hpp +++ b/include/Nazara/Core/InputStream.hpp @@ -24,6 +24,9 @@ namespace Nz virtual std::size_t Read(void* buffer, std::size_t size) = 0; virtual String ReadLine(unsigned int lineSize = 0); + template + InputStream& operator>>(T& value); + protected: inline InputStream(); }; diff --git a/include/Nazara/Core/InputStream.inl b/include/Nazara/Core/InputStream.inl index 35912da00..a9a796032 100644 --- a/include/Nazara/Core/InputStream.inl +++ b/include/Nazara/Core/InputStream.inl @@ -2,10 +2,21 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include + namespace Nz { inline InputStream::InputStream() : Stream(OpenMode_Current) { } + + template + InputStream& InputStream::operator>>(T& value) + { + if (!Unserialize(this, &value)) + NazaraError("Failed to unserialize value"); + + return *this; + } } diff --git a/include/Nazara/Core/OutputStream.hpp b/include/Nazara/Core/OutputStream.hpp index 2f475d4b4..6ace7e403 100644 --- a/include/Nazara/Core/OutputStream.hpp +++ b/include/Nazara/Core/OutputStream.hpp @@ -12,6 +12,9 @@ namespace Nz { + class ByteArray; + class String; + class NAZARA_CORE_API OutputStream : virtual public Stream { public: @@ -23,6 +26,9 @@ namespace Nz bool Write(const String& string); virtual std::size_t Write(const void* buffer, std::size_t size) = 0; + template + OutputStream& operator<<(const T& value); + protected: inline OutputStream(); }; diff --git a/include/Nazara/Core/OutputStream.inl b/include/Nazara/Core/OutputStream.inl index 51766a889..098f012b7 100644 --- a/include/Nazara/Core/OutputStream.inl +++ b/include/Nazara/Core/OutputStream.inl @@ -2,10 +2,21 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include + namespace Nz { inline OutputStream::OutputStream() : Stream(OpenMode_Current) { } + + template + OutputStream& OutputStream::operator<<(const T& value) + { + if (!Serialize(this, value)) + NazaraError("Failed to serialize value"); + + return *this; + } } diff --git a/include/Nazara/Core/Stream.hpp b/include/Nazara/Core/Stream.hpp index a00c09661..85095e324 100644 --- a/include/Nazara/Core/Stream.hpp +++ b/include/Nazara/Core/Stream.hpp @@ -9,10 +9,11 @@ #include #include -#include namespace Nz { + class String; //< Do not include String.hpp in this file + class NAZARA_CORE_API Stream { public: diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 988ed96d3..c48e2552b 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -8,7 +8,6 @@ #define NAZARA_STRING_HPP #include -#include #include #include #include @@ -19,6 +18,8 @@ namespace Nz { class AbstractHash; class HashDigest; + class InputStream; + class OutputStream; class NAZARA_CORE_API String { @@ -325,6 +326,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); } namespace std diff --git a/src/Nazara/Core/Stream.cpp b/src/Nazara/Core/Stream.cpp index f3bdb8fe4..8a6951887 100644 --- a/src/Nazara/Core/Stream.cpp +++ b/src/Nazara/Core/Stream.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include namespace Nz diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index d5230577a..8aa2e5da7 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -5,6 +5,7 @@ ///TODO: Réécrire une bonne partie des algorithmes employés (Relu jusqu'à 3538) #include +#include #include #include #include @@ -4208,6 +4209,26 @@ namespace Nz return emptyString; } + bool Serialize(OutputStream* output, const String& string) + { + if (!Serialize(output, string.GetSize())) + return false; + + output->Write(string.GetConstBuffer(), string.GetSize()); + return true; + } + + bool Unserialize(InputStream* input, String* string) + { + UInt32 size; + if (!Unserialize(input, &size)) + return false; + + string->Resize(size); + input->Read(string->GetBuffer(), size); + return true; + } + const unsigned int String::npos(std::numeric_limits::max()); }