Core: Replace serialization arguments by context structures

Also fixed some endianness errors


Former-commit-id: 450849e681a9b002c3d501a856a8481470d08dea
This commit is contained in:
Lynix 2015-11-19 13:25:07 +01:00
parent bc4eb96af2
commit 1c8a09f90c
9 changed files with 164 additions and 46 deletions

View File

@ -9,8 +9,7 @@
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Enums.hpp> #include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/InputStream.hpp> #include <Nazara/Core/Serialization.hpp>
#include <Nazara/Core/OutputStream.hpp>
#include <functional> #include <functional>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
@ -29,15 +28,15 @@ namespace Nz
template<typename T> template<typename T>
struct TypeTag {}; struct TypeTag {};
inline bool Serialize(OutputStream* output, bool value, Endianness dataEndianness); inline bool Serialize(SerializationContext& context, bool value);
template<typename T> template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(OutputStream* output, T value, Endianness dataEndianness); std::enable_if_t<std::is_arithmetic<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<typename T> template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(InputStream* input, T* value, Endianness dataEndianness); std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(UnserializationContext& context, T* value);
} }
#include <Nazara/Core/Algorithm.inl> #include <Nazara/Core/Algorithm.inl>

View File

@ -8,6 +8,8 @@
#include <Nazara/Core/AbstractHash.hpp> #include <Nazara/Core/AbstractHash.hpp>
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <Nazara/Core/InputStream.hpp>
#include <Nazara/Core/OutputStream.hpp>
#include <Nazara/Core/Debug.hpp> #include <Nazara/Core/Debug.hpp>
namespace Nz namespace Nz
@ -77,40 +79,28 @@ 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, 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) ///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 context.stream->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, Endianness dataEndianness) std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value)
{ {
NazaraAssert(output, "Invalid stream"); if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness())
if (output->Write(&value, sizeof(T)) == sizeof(T))
{
if (dataEndianness != Endianness_Unknown && dataEndianness != GetPlatformEndianness())
SwapBytes(&value, sizeof(T)); SwapBytes(&value, sizeof(T));
return true; return context.stream->Write(&value, sizeof(T)) == sizeof(T);
}
else
return false;
} }
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"); NazaraAssert(value, "Invalid data pointer");
NazaraUnused(dataEndianness);
UInt8 buffer; UInt8 buffer;
if (input->Read(&buffer, 1) == 1) if (context.stream->Read(&buffer, 1) == 1)
{ {
*value = (buffer == 1); *value = (buffer == 1);
return true; return true;
@ -120,15 +110,14 @@ namespace Nz
} }
template<typename T> template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(InputStream* input, T* value, Endianness dataEndianness) std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(UnserializationContext& context, T* value)
{ {
NazaraAssert(input, "Invalid stream");
NazaraAssert(value, "Invalid data pointer"); 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()) if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness())
SwapBytes(&value, sizeof(T)); SwapBytes(value, sizeof(T));
return true; return true;
} }

View File

@ -8,6 +8,7 @@
#define NAZARA_INPUTSTREAM_HPP #define NAZARA_INPUTSTREAM_HPP
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Serialization.hpp>
#include <Nazara/Core/Stream.hpp> #include <Nazara/Core/Stream.hpp>
namespace Nz namespace Nz
@ -15,6 +16,8 @@ namespace Nz
class NAZARA_CORE_API InputStream : virtual public Stream class NAZARA_CORE_API InputStream : virtual public Stream
{ {
public: public:
inline InputStream(const InputStream& stream);
inline InputStream(InputStream&& stream) noexcept;
virtual ~InputStream(); virtual ~InputStream();
virtual bool EndOfStream() const = 0; virtual bool EndOfStream() const = 0;
@ -27,8 +30,13 @@ namespace Nz
template<typename T> template<typename T>
InputStream& operator>>(T& value); InputStream& operator>>(T& value);
inline InputStream& operator=(const InputStream& stream);
inline InputStream& operator=(InputStream&& stream) noexcept;
protected: protected:
inline InputStream(); inline InputStream();
UnserializationContext m_unserializationContext;
}; };
} }

View File

@ -3,20 +3,61 @@
// 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 <utility>
#include <Nazara/Core/Debug.hpp>
namespace Nz namespace Nz
{ {
inline InputStream::InputStream() : inline InputStream::InputStream() :
Stream(OpenMode_Current) 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<typename T> template<typename T>
InputStream& InputStream::operator>>(T& value) 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"); NazaraError("Failed to unserialize value");
return *this; 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 <Nazara/Core/DebugOff.hpp>

View File

@ -8,6 +8,7 @@
#define NAZARA_OUTPUTSTREAM_HPP #define NAZARA_OUTPUTSTREAM_HPP
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Serialization.hpp>
#include <Nazara/Core/Stream.hpp> #include <Nazara/Core/Stream.hpp>
namespace Nz namespace Nz
@ -18,6 +19,8 @@ namespace Nz
class NAZARA_CORE_API OutputStream : virtual public Stream class NAZARA_CORE_API OutputStream : virtual public Stream
{ {
public: public:
inline OutputStream(const OutputStream& stream);
inline OutputStream(OutputStream&& stream) noexcept;
virtual ~OutputStream(); virtual ~OutputStream();
virtual void Flush() = 0; virtual void Flush() = 0;
@ -29,8 +32,13 @@ namespace Nz
template<typename T> template<typename T>
OutputStream& operator<<(const T& value); OutputStream& operator<<(const T& value);
inline OutputStream& operator=(const OutputStream& stream);
inline OutputStream& operator=(OutputStream&& stream) noexcept;
protected: protected:
inline OutputStream(); inline OutputStream();
SerializationContext m_serializationContext;
}; };
} }

View File

@ -3,20 +3,61 @@
// 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 <utility>
#include <Nazara/Core/Debug.hpp>
namespace Nz namespace Nz
{ {
inline OutputStream::OutputStream() : inline OutputStream::OutputStream() :
Stream(OpenMode_Current) 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<typename T> template<typename T>
OutputStream& OutputStream::operator<<(const T& value) 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"); NazaraError("Failed to serialize value");
return *this; 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 <Nazara/Core/DebugOff.hpp>

View File

@ -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 <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <functional>
#include <tuple>
#include <type_traits>
namespace Nz
{
class InputStream;
class OutputStream;
struct SerializationContext
{
OutputStream* stream;
Endianness endianness;
};
struct UnserializationContext
{
InputStream* stream;
Endianness endianness;
};
}
#endif // NAZARA_SERIALIZATION_HPP

View File

@ -9,6 +9,7 @@
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Endianness.hpp> #include <Nazara/Core/Endianness.hpp>
#include <Nazara/Core/Serialization.hpp>
#include <atomic> #include <atomic>
#include <iosfwd> #include <iosfwd>
#include <memory> #include <memory>
@ -17,11 +18,6 @@
namespace Nz namespace Nz
{ {
class AbstractHash;
class HashDigest;
class InputStream;
class OutputStream;
class NAZARA_CORE_API String class NAZARA_CORE_API String
{ {
public: public:
@ -326,9 +322,11 @@ namespace Nz
}; };
}; };
class AbstractHash;
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, Endianness dataEndianness); NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string);
NAZARA_CORE_API bool Unserialize(InputStream* input, String* string, Endianness dataEndianness); NAZARA_CORE_API bool Unserialize(UnserializationContext& context, String* string);
} }
namespace std namespace std

View File

@ -4209,23 +4209,23 @@ namespace Nz
return emptyString; return emptyString;
} }
bool Serialize(OutputStream* output, const String& string, Endianness dataEndianness) bool Serialize(SerializationContext& context, const String& string)
{ {
if (!Serialize<UInt32>(output, string.GetSize(), dataEndianness)) if (!Serialize<UInt32>(context, string.GetSize()))
return false; return false;
output->Write(string.GetConstBuffer(), string.GetSize()); context.stream->Write(string.GetConstBuffer(), string.GetSize());
return true; return true;
} }
bool Unserialize(InputStream* input, String* string, Endianness dataEndianness) bool Unserialize(UnserializationContext& context, String* string)
{ {
UInt32 size; UInt32 size;
if (!Unserialize(input, &size, dataEndianness)) if (!Unserialize(context, &size))
return false; return false;
string->Resize(size); string->Resize(size);
input->Read(string->GetBuffer(), size); context.stream->Read(string->GetBuffer(), size);
return true; return true;
} }