From 1c8a09f90c09bfa64ea6f50bf743a99204ec4e80 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 Nov 2015 13:25:07 +0100 Subject: [PATCH] Core: Replace serialization arguments by context structures Also fixed some endianness errors Former-commit-id: 450849e681a9b002c3d501a856a8481470d08dea --- include/Nazara/Core/Algorithm.hpp | 11 ++++--- include/Nazara/Core/Algorithm.inl | 39 +++++++++--------------- include/Nazara/Core/InputStream.hpp | 8 +++++ include/Nazara/Core/InputStream.inl | 43 ++++++++++++++++++++++++++- include/Nazara/Core/OutputStream.hpp | 8 +++++ include/Nazara/Core/OutputStream.inl | 43 ++++++++++++++++++++++++++- include/Nazara/Core/Serialization.hpp | 34 +++++++++++++++++++++ include/Nazara/Core/String.hpp | 12 ++++---- src/Nazara/Core/String.cpp | 12 ++++---- 9 files changed, 164 insertions(+), 46 deletions(-) create mode 100644 include/Nazara/Core/Serialization.hpp diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index 2f4d770d0..cbbd8af04 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -9,8 +9,7 @@ #include #include -#include -#include +#include #include #include #include @@ -29,15 +28,15 @@ namespace Nz template struct TypeTag {}; - inline bool Serialize(OutputStream* output, bool value, Endianness dataEndianness); + inline bool Serialize(SerializationContext& context, bool value); template - std::enable_if_t::value, bool> Serialize(OutputStream* output, T value, Endianness dataEndianness); + std::enable_if_t::value, bool> Serialize(SerializationContext& context, T value); - inline bool Unserialize(InputStream* input, bool* value, Endianness dataEndianness); + inline bool Unserialize(UnserializationContext& context, bool* value); template - std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value, Endianness dataEndianness); + std::enable_if_t::value, bool> Unserialize(UnserializationContext& context, T* value); } #include diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 6fed14897..4c2f81f7e 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -8,6 +8,8 @@ #include #include +#include +#include #include namespace Nz @@ -77,40 +79,28 @@ namespace Nz seed = static_cast(b * kMul); } - inline bool Serialize(OutputStream* output, bool value, Endianness dataEndianness) + inline bool Serialize(SerializationContext& context, bool value) { - 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; + return context.stream->Write(&buffer, 1) == 1; } template - std::enable_if_t::value, bool> Serialize(OutputStream* output, T value, Endianness dataEndianness) + std::enable_if_t::value, bool> Serialize(SerializationContext& context, T value) { - NazaraAssert(output, "Invalid stream"); + if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness()) + SwapBytes(&value, sizeof(T)); - if (output->Write(&value, sizeof(T)) == sizeof(T)) - { - if (dataEndianness != Endianness_Unknown && dataEndianness != GetPlatformEndianness()) - SwapBytes(&value, sizeof(T)); - - return true; - } - else - return false; + return context.stream->Write(&value, sizeof(T)) == sizeof(T); } - inline bool Unserialize(InputStream* input, bool* value, Endianness dataEndianness) + inline bool Unserialize(UnserializationContext& context, bool* value) { - NazaraAssert(input, "Invalid stream"); NazaraAssert(value, "Invalid data pointer"); - NazaraUnused(dataEndianness); UInt8 buffer; - if (input->Read(&buffer, 1) == 1) + if (context.stream->Read(&buffer, 1) == 1) { *value = (buffer == 1); return true; @@ -120,15 +110,14 @@ namespace Nz } template - std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value, Endianness dataEndianness) + std::enable_if_t::value, bool> Unserialize(UnserializationContext& context, T* value) { - NazaraAssert(input, "Invalid stream"); NazaraAssert(value, "Invalid data pointer"); - if (input->Read(value, sizeof(T)) == sizeof(T)) + if (context.stream->Read(value, sizeof(T)) == sizeof(T)) { - if (dataEndianness != Endianness_Unknown && dataEndianness != GetPlatformEndianness()) - SwapBytes(&value, sizeof(T)); + if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness()) + SwapBytes(value, sizeof(T)); return true; } diff --git a/include/Nazara/Core/InputStream.hpp b/include/Nazara/Core/InputStream.hpp index f431afe14..19555cac4 100644 --- a/include/Nazara/Core/InputStream.hpp +++ b/include/Nazara/Core/InputStream.hpp @@ -8,6 +8,7 @@ #define NAZARA_INPUTSTREAM_HPP #include +#include #include namespace Nz @@ -15,6 +16,8 @@ namespace Nz class NAZARA_CORE_API InputStream : virtual public Stream { public: + inline InputStream(const InputStream& stream); + inline InputStream(InputStream&& stream) noexcept; virtual ~InputStream(); virtual bool EndOfStream() const = 0; @@ -27,8 +30,13 @@ namespace Nz template InputStream& operator>>(T& value); + inline InputStream& operator=(const InputStream& stream); + inline InputStream& operator=(InputStream&& stream) noexcept; + protected: inline InputStream(); + + UnserializationContext m_unserializationContext; }; } diff --git a/include/Nazara/Core/InputStream.inl b/include/Nazara/Core/InputStream.inl index 4e8abe925..00d1e2131 100644 --- a/include/Nazara/Core/InputStream.inl +++ b/include/Nazara/Core/InputStream.inl @@ -3,20 +3,61 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include +#include namespace Nz { inline InputStream::InputStream() : Stream(OpenMode_Current) { + m_unserializationContext.stream = this; + } + + inline InputStream::InputStream(const InputStream& stream) : + Stream(stream), + m_unserializationContext(stream.m_unserializationContext) + { + m_unserializationContext.stream = this; + } + + inline InputStream::InputStream(InputStream&& stream) noexcept : + Stream(std::move(stream)), + m_unserializationContext(std::move(stream.m_unserializationContext)) + { + m_unserializationContext.stream = this; } template InputStream& InputStream::operator>>(T& value) { - if (!Unserialize(this, &value, m_dataEndianness)) + m_unserializationContext.endianness = m_dataEndianness; //< In case m_dataEndianness changed + + if (!Unserialize(m_unserializationContext, &value)) NazaraError("Failed to unserialize value"); return *this; } + + inline InputStream& InputStream::operator=(const InputStream& stream) + { + Stream::operator=(stream); + + m_unserializationContext = stream.m_unserializationContext; + m_unserializationContext.stream = this; + + return *this; + } + + inline InputStream& InputStream::operator=(InputStream&& stream) noexcept + { + Stream::operator=(std::move(stream)); + + m_unserializationContext = std::move(stream.m_unserializationContext); + m_unserializationContext.stream = this; + + return *this; + } } + +#include diff --git a/include/Nazara/Core/OutputStream.hpp b/include/Nazara/Core/OutputStream.hpp index 6ace7e403..47e7c4bde 100644 --- a/include/Nazara/Core/OutputStream.hpp +++ b/include/Nazara/Core/OutputStream.hpp @@ -8,6 +8,7 @@ #define NAZARA_OUTPUTSTREAM_HPP #include +#include #include namespace Nz @@ -18,6 +19,8 @@ namespace Nz class NAZARA_CORE_API OutputStream : virtual public Stream { public: + inline OutputStream(const OutputStream& stream); + inline OutputStream(OutputStream&& stream) noexcept; virtual ~OutputStream(); virtual void Flush() = 0; @@ -29,8 +32,13 @@ namespace Nz template OutputStream& operator<<(const T& value); + inline OutputStream& operator=(const OutputStream& stream); + inline OutputStream& operator=(OutputStream&& stream) noexcept; + protected: inline OutputStream(); + + SerializationContext m_serializationContext; }; } diff --git a/include/Nazara/Core/OutputStream.inl b/include/Nazara/Core/OutputStream.inl index 95f0f03e0..3d8cbb65a 100644 --- a/include/Nazara/Core/OutputStream.inl +++ b/include/Nazara/Core/OutputStream.inl @@ -3,20 +3,61 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include +#include namespace Nz { inline OutputStream::OutputStream() : Stream(OpenMode_Current) { + m_serializationContext.stream = this; + } + + inline OutputStream::OutputStream(const OutputStream& stream) : + Stream(stream), + m_serializationContext(stream.m_serializationContext) + { + m_serializationContext.stream = this; + } + + inline OutputStream::OutputStream(OutputStream&& stream) noexcept : + Stream(std::move(stream)), + m_serializationContext(std::move(stream.m_serializationContext)) + { + m_serializationContext.stream = this; } template OutputStream& OutputStream::operator<<(const T& value) { - if (!Serialize(this, value, m_dataEndianness)) + m_serializationContext.endianness = m_dataEndianness; //< In case m_dataEndianness changed + + if (!Serialize(m_serializationContext, value)) NazaraError("Failed to serialize value"); return *this; } + + inline OutputStream& OutputStream::operator=(const OutputStream& stream) + { + Stream::operator=(stream); + + m_serializationContext = stream.m_serializationContext; + m_serializationContext.stream = this; + + return *this; + } + + inline OutputStream& OutputStream::operator=(OutputStream&& stream) noexcept + { + Stream::operator=(std::move(stream)); + + m_serializationContext = std::move(stream.m_serializationContext); + m_serializationContext.stream = this; + + return *this; + } } + +#include diff --git a/include/Nazara/Core/Serialization.hpp b/include/Nazara/Core/Serialization.hpp new file mode 100644 index 000000000..fc82cc0c7 --- /dev/null +++ b/include/Nazara/Core/Serialization.hpp @@ -0,0 +1,34 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_SERIALIZATION_HPP +#define NAZARA_SERIALIZATION_HPP + +#include +#include +#include +#include +#include + +namespace Nz +{ + class InputStream; + class OutputStream; + + struct SerializationContext + { + OutputStream* stream; + Endianness endianness; + }; + + struct UnserializationContext + { + InputStream* stream; + Endianness endianness; + }; +} + +#endif // NAZARA_SERIALIZATION_HPP diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 17ef58aab..7bfb21e5b 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -17,11 +18,6 @@ namespace Nz { - class AbstractHash; - class HashDigest; - class InputStream; - class OutputStream; - class NAZARA_CORE_API String { public: @@ -326,9 +322,11 @@ namespace Nz }; }; + class AbstractHash; + inline bool HashAppend(AbstractHash* hash, const 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); + NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string); + NAZARA_CORE_API bool Unserialize(UnserializationContext& context, String* string); } namespace std diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 6ad60a3cb..b81facd2e 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -4209,23 +4209,23 @@ namespace Nz return emptyString; } - bool Serialize(OutputStream* output, const String& string, Endianness dataEndianness) + bool Serialize(SerializationContext& context, const String& string) { - if (!Serialize(output, string.GetSize(), dataEndianness)) + if (!Serialize(context, string.GetSize())) return false; - output->Write(string.GetConstBuffer(), string.GetSize()); + context.stream->Write(string.GetConstBuffer(), string.GetSize()); return true; } - bool Unserialize(InputStream* input, String* string, Endianness dataEndianness) + bool Unserialize(UnserializationContext& context, String* string) { UInt32 size; - if (!Unserialize(input, &size, dataEndianness)) + if (!Unserialize(context, &size)) return false; string->Resize(size); - input->Read(string->GetBuffer(), size); + context.stream->Read(string->GetBuffer(), size); return true; }