Core: Rework Serialization

Former-commit-id: d97eedbd3efc92235e3880ad061a5216fa77ebd7
This commit is contained in:
Lynix 2016-02-03 18:42:19 +01:00
parent f0863d9055
commit e367ec456d
17 changed files with 337 additions and 273 deletions

View File

@ -41,10 +41,10 @@ namespace Nz
template<typename T> template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value); std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value);
inline bool Unserialize(UnserializationContext& context, bool* value); inline bool Unserialize(SerializationContext& context, bool* value);
template<typename T> template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(UnserializationContext& context, T* value); std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(SerializationContext& context, T* value);
} }
#include <Nazara/Core/Algorithm.inl> #include <Nazara/Core/Algorithm.inl>

View File

@ -131,10 +131,8 @@ namespace Nz
return context.stream->Write(&value, sizeof(T)) == sizeof(T); return context.stream->Write(&value, sizeof(T)) == sizeof(T);
} }
inline bool Unserialize(UnserializationContext& context, bool* value) inline bool Unserialize(SerializationContext& context, bool* value)
{ {
NazaraAssert(value, "Invalid data pointer");
if (context.currentBitPos == 8) if (context.currentBitPos == 8)
{ {
if (!Unserialize(context, &context.currentByte)) if (!Unserialize(context, &context.currentByte))
@ -152,7 +150,7 @@ namespace Nz
} }
template<typename T> template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(UnserializationContext& context, T* value) std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(SerializationContext& context, T* value)
{ {
NazaraAssert(value, "Invalid data pointer"); NazaraAssert(value, "Invalid data pointer");

View File

@ -0,0 +1,65 @@
// 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_BYTESTREAM_HPP
#define NAZARA_BYTESTREAM_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/Serialization.hpp>
#include <Nazara/Core/Stream.hpp>
#include <memory>
namespace Nz
{
class NAZARA_CORE_API ByteStream
{
public:
inline ByteStream(Stream* stream = nullptr);
ByteStream(ByteArray* byteArray, UInt32 openMode = OpenMode_ReadWrite);
ByteStream(void* ptr, Nz::UInt64 size);
ByteStream(const void* ptr, Nz::UInt64 size);
ByteStream(const ByteStream&) = delete;
inline ByteStream(ByteStream&& stream);
~ByteStream();
inline Endianness GetDataEndianness() const;
inline Nz::UInt64 GetSize() const;
inline Stream* GetStream() const;
inline bool FlushBits();
inline std::size_t Read(void* ptr, std::size_t size);
inline void SetDataEndianness(Endianness endiannes);
inline void SetStream(Stream* stream);
void SetStream(ByteArray* byteArray, UInt32 openMode = OpenMode_ReadWrite);
void SetStream(void* ptr, Nz::UInt64 size);
void SetStream(const void* ptr, Nz::UInt64 size);
inline void Write(const void* data, std::size_t size);
template<typename T>
ByteStream& operator>>(T& value);
template<typename T>
ByteStream& operator<<(const T& value);
ByteStream& operator=(const ByteStream&) = delete;
inline ByteStream& operator=(ByteStream&&);
private:
virtual void OnEmptyStream();
std::unique_ptr<Stream> m_ownedStream;
SerializationContext m_context;
};
}
#include <Nazara/Core/ByteStream.inl>
#endif // NAZARA_BYTESTREAM_HPP

View File

@ -0,0 +1,129 @@
// 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
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
inline ByteStream::ByteStream(Stream* stream)
{
m_context.stream = stream;
}
inline ByteStream::ByteStream(ByteStream&& stream) :
m_ownedStream(std::move(stream.m_ownedStream)),
m_context(stream.m_context)
{
stream.m_context.stream = nullptr;
}
inline ByteStream::~ByteStream()
{
if (!FlushBits())
NazaraWarning("Failed to flush bits at serializer destruction");
}
inline Endianness ByteStream::GetDataEndianness() const
{
return m_context.endianness;
}
inline Nz::UInt64 ByteStream::GetSize() const
{
if (m_context.stream)
return m_context.stream->GetSize();
else
return 0;
}
inline Stream* ByteStream::GetStream() const
{
return m_context.stream;
}
inline bool ByteStream::FlushBits()
{
if (!m_context.stream)
return true;
if (m_context.currentBitPos != 8)
{
m_context.currentBitPos = 8; //< To prevent Serialize to flush bits itself
if (!Serialize<UInt8>(m_context, m_context.currentByte))
return false;
}
return true;
}
inline std::size_t ByteStream::Read(void* ptr, std::size_t size)
{
if (!m_context.stream)
OnEmptyStream();
FlushBits();
return m_context.stream->Read(ptr, size);
}
inline void ByteStream::SetDataEndianness(Endianness endiannes)
{
m_context.endianness = endiannes;
}
inline void ByteStream::SetStream(Stream* stream)
{
// We don't want to lose some bits..
FlushBits();
m_context.stream = stream;
m_ownedStream.reset();
}
inline void ByteStream::Write(const void* data, std::size_t size)
{
if (!m_context.stream)
OnEmptyStream();
FlushBits();
m_context.stream->Write(data, size);
}
template<typename T>
ByteStream& ByteStream::operator>>(T& value)
{
if (!m_context.stream)
OnEmptyStream();
if (!Unserialize(m_context, &value))
NazaraError("Failed to serialize value");
return *this;
}
template<typename T>
ByteStream& ByteStream::operator<<(const T& value)
{
if (!m_context.stream)
OnEmptyStream();
if (!Serialize(m_context, value))
NazaraError("Failed to serialize value");
return *this;
}
inline ByteStream& ByteStream::operator=(ByteStream&& stream)
{
m_context = stream.m_context;
m_ownedStream = std::move(stream.m_ownedStream);
stream.m_context.stream = nullptr;
return *this;
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -8,16 +8,17 @@
#define NAZARA_MEMORYSTREAM_HPP #define NAZARA_MEMORYSTREAM_HPP
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/Stream.hpp> #include <Nazara/Core/Stream.hpp>
namespace Nz namespace Nz
{ {
class ByteArray;
class NAZARA_CORE_API MemoryStream : public Stream class NAZARA_CORE_API MemoryStream : public Stream
{ {
public: public:
MemoryStream(); inline MemoryStream();
MemoryStream(const void* ptr, unsigned int size); inline MemoryStream(ByteArray* byteArray, UInt32 openMode = OpenMode_ReadWrite);
MemoryStream(const MemoryStream&) = default; MemoryStream(const MemoryStream&) = default;
MemoryStream(MemoryStream&&) = default; MemoryStream(MemoryStream&&) = default;
~MemoryStream() = default; ~MemoryStream() = default;
@ -26,11 +27,12 @@ namespace Nz
bool EndOfStream() const override; bool EndOfStream() const override;
const ByteArray& GetBuffer() const; inline ByteArray& GetBuffer();
const UInt8* GetData() const; inline const ByteArray& GetBuffer() const;
UInt64 GetCursorPos() const override; UInt64 GetCursorPos() const override;
UInt64 GetSize() const override; UInt64 GetSize() const override;
void SetBuffer(ByteArray* byteArray, UInt32 openMode = OpenMode_ReadWrite);
bool SetCursorPos(UInt64 offset) override; bool SetCursorPos(UInt64 offset) override;
MemoryStream& operator=(const MemoryStream&) = default; MemoryStream& operator=(const MemoryStream&) = default;
@ -41,15 +43,9 @@ namespace Nz
std::size_t ReadBlock(void* buffer, std::size_t size) override; std::size_t ReadBlock(void* buffer, std::size_t size) override;
std::size_t WriteBlock(const void* buffer, std::size_t size) override; std::size_t WriteBlock(const void* buffer, std::size_t size) override;
ByteArray m_buffer; ByteArray* m_buffer;
UInt64 m_pos; UInt64 m_pos;
}; };
class AbstractHash;
inline bool HashAppend(AbstractHash* hash, const String& string);
NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string);
NAZARA_CORE_API bool Unserialize(UnserializationContext& context, String* string);
} }
#include <Nazara/Core/MemoryStream.inl> #include <Nazara/Core/MemoryStream.inl>

View File

@ -2,13 +2,35 @@
// This file is part of the "Nazara Engine - Core module" // This file is part of the "Nazara Engine - Core module"
// 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/Debug.hpp> #include <Nazara/Core/Debug.hpp>
namespace Nz namespace Nz
{ {
inline bool HashAppend(AbstractHash* hash, const MemoryStream& stream) inline MemoryStream::MemoryStream() :
Stream(StreamOption_None, OpenMode_ReadWrite),
m_pos(0)
{ {
return HashAppend(hash, stream.GetBuffer()); }
inline MemoryStream::MemoryStream(ByteArray* byteArray, UInt32 openMode) :
MemoryStream()
{
SetBuffer(byteArray, openMode);
}
inline ByteArray& MemoryStream::GetBuffer()
{
NazaraAssert(m_buffer, "Invalid buffer");
return *m_buffer;
}
inline const ByteArray& MemoryStream::GetBuffer() const
{
NazaraAssert(m_buffer, "Invalid buffer");
return *m_buffer;
} }
} }

View File

@ -15,6 +15,7 @@ namespace Nz
class NAZARA_CORE_API MemoryView : public Stream class NAZARA_CORE_API MemoryView : public Stream
{ {
public: public:
MemoryView(void* ptr, UInt64 size);
MemoryView(const void* ptr, UInt64 size); MemoryView(const void* ptr, UInt64 size);
MemoryView(const MemoryView&) = delete; MemoryView(const MemoryView&) = delete;
MemoryView(MemoryView&&) = delete; ///TODO MemoryView(MemoryView&&) = delete; ///TODO
@ -35,7 +36,7 @@ namespace Nz
std::size_t ReadBlock(void* buffer, std::size_t size) override; std::size_t ReadBlock(void* buffer, std::size_t size) override;
std::size_t WriteBlock(const void* buffer, std::size_t size) override; std::size_t WriteBlock(const void* buffer, std::size_t size) override;
const UInt8* m_ptr; UInt8* m_ptr;
UInt64 m_pos; UInt64 m_pos;
UInt64 m_size; UInt64 m_size;
}; };

View File

@ -20,17 +20,9 @@ namespace Nz
struct SerializationContext struct SerializationContext
{ {
Stream* stream; Stream* stream;
Endianness endianness; Endianness endianness = Endianness_BigEndian; //< Default to Big Endian encoding
UInt8 currentBitPos; UInt8 currentBitPos = 8; //< 8 means no bit is currently wrote
UInt8 currentByte; UInt8 currentByte; //< Undefined value, will be initialized at the first bit write
};
struct UnserializationContext
{
Stream* stream;
Endianness endianness;
UInt8 currentBitPos;
UInt8 currentByte;
}; };
} }

View File

@ -1,46 +0,0 @@
// 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_SERIALIZER_HPP
#define NAZARA_SERIALIZER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Serialization.hpp>
namespace Nz
{
class Stream;
class Serializer
{
public:
inline Serializer(Stream& stream);
Serializer(const Serializer&) = default;
Serializer(Serializer&&) = default;
~Serializer();
inline Endianness GetDataEndianness() const;
inline Stream& GetStream() const;
inline bool FlushBits();
inline void SetDataEndianness(Endianness endiannes);
inline void SetStream(Stream& stream);
template<typename T>
Serializer& operator<<(const T& value);
Serializer& operator=(const Serializer&) = default;
Serializer& operator=(Serializer&&) = default;
private:
SerializationContext m_serializationContext;
};
}
#include <Nazara/Core/Serializer.inl>
#endif // NAZARA_SERIALIZER_HPP

View File

@ -1,67 +0,0 @@
// 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
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
inline Serializer::Serializer(Stream& stream)
{
m_serializationContext.currentBitPos = 8;
m_serializationContext.endianness = Endianness_BigEndian;
m_serializationContext.stream = &stream;
}
inline Serializer::~Serializer()
{
if (!FlushBits())
NazaraWarning("Failed to flush bits at serializer destruction");
}
inline Endianness Serializer::GetDataEndianness() const
{
return m_serializationContext.endianness;
}
inline Stream& Serializer::GetStream() const
{
return *m_serializationContext.stream;
}
inline bool Serializer::FlushBits()
{
if (m_serializationContext.currentBitPos != 8)
{
m_serializationContext.currentBitPos = 8; //< To prevent Serialize to flush bits itself
if (!Serialize<UInt8>(m_serializationContext, m_serializationContext.currentByte))
return false;
}
return true;
}
inline void Serializer::SetDataEndianness(Endianness endiannes)
{
m_serializationContext.endianness = endiannes;
}
inline void Serializer::SetStream(Stream& stream)
{
m_serializationContext.stream = &stream;
}
template<typename T>
Serializer& Serializer::operator<<(const T& value)
{
if (!Serialize(m_serializationContext, value))
NazaraError("Failed to serialize value");
return *this;
}
}
#include <Nazara/Core/DebugOff.hpp>
#include "Serializer.hpp"

View File

@ -326,7 +326,7 @@ namespace Nz
inline bool HashAppend(AbstractHash* hash, const String& string); inline bool HashAppend(AbstractHash* hash, const String& string);
NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string); NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string);
NAZARA_CORE_API bool Unserialize(UnserializationContext& context, String* string); NAZARA_CORE_API bool Unserialize(SerializationContext& context, String* string);
} }
namespace std namespace std

View File

@ -1,44 +0,0 @@
// 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_UNSERIALIZER_HPP
#define NAZARA_UNSERIALIZER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Serialization.hpp>
namespace Nz
{
class Stream;
class Unserializer
{
public:
inline Unserializer(Stream& stream);
Unserializer(const Unserializer&) = default;
Unserializer(Unserializer&&) = default;
~Unserializer() = default;
inline Endianness GetDataEndianness() const;
inline Stream& GetStream() const;
inline void SetDataEndianness(Endianness endiannes);
inline void SetStream(Stream& stream);
template<typename T>
Unserializer& operator>>(T& value);
Unserializer& operator=(const Unserializer&) = default;
Unserializer& operator=(Unserializer&&) = default;
private:
UnserializationContext m_unserializationContext;
};
}
#include <Nazara/Core/Unserializer.inl>
#endif // NAZARA_UNSERIALIZER_HPP

View File

@ -1,46 +0,0 @@
// 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
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
inline Unserializer::Unserializer(Stream& stream)
{
m_unserializationContext.currentBitPos = 8;
m_unserializationContext.endianness = Endianness_BigEndian;
m_unserializationContext.stream = &stream;
}
inline Endianness Unserializer::GetDataEndianness() const
{
return m_unserializationContext.endianness;
}
inline Stream& Unserializer::GetStream() const
{
return *m_unserializationContext.stream;
}
inline void Unserializer::SetDataEndianness(Endianness endiannes)
{
m_unserializationContext.endianness = endiannes;
}
inline void Unserializer::SetStream(Stream& stream)
{
m_unserializationContext.stream = &stream;
}
template<typename T>
Unserializer& Unserializer::operator>>(T& value)
{
if (!Unserialize(m_unserializationContext, &value))
NazaraError("Failed to serialize value");
return *this;
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -0,0 +1,63 @@
// 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
#include <Nazara/Core/ByteStream.hpp>
#include <Nazara/Core/MemoryStream.hpp>
#include <Nazara/Core/MemoryView.hpp>
#include <algorithm>
#include <cstring>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
ByteStream::ByteStream(ByteArray* byteArray, UInt32 openMode) :
ByteStream()
{
SetStream(byteArray, openMode);
}
ByteStream::ByteStream(void* ptr, Nz::UInt64 size) :
ByteStream()
{
SetStream(ptr, size);
}
ByteStream::ByteStream(const void* ptr, Nz::UInt64 size) :
ByteStream()
{
SetStream(ptr, size);
}
void ByteStream::SetStream(ByteArray* byteArray, UInt32 openMode)
{
std::unique_ptr<Stream> stream(new MemoryStream(byteArray, openMode));
SetStream(m_ownedStream.get());
// SetStream reset our smart pointer, set it after calling it
m_ownedStream = std::move(stream);
}
void ByteStream::SetStream(void* ptr, Nz::UInt64 size)
{
std::unique_ptr<Stream> stream(new MemoryView(ptr, size));
SetStream(m_ownedStream.get());
// SetStream reset our smart pointer, set it after calling it
m_ownedStream = std::move(stream);
}
void ByteStream::SetStream(const void* ptr, Nz::UInt64 size)
{
std::unique_ptr<Stream> stream(new MemoryView(ptr, size));
SetStream(m_ownedStream.get());
// SetStream reset our smart pointer, set it after calling it
m_ownedStream = std::move(stream);
}
void ByteStream::OnEmptyStream()
{
NazaraError("No stream");
}
}

View File

@ -3,39 +3,22 @@
// 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/MemoryStream.hpp> #include <Nazara/Core/MemoryStream.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include <Nazara/Core/Debug.hpp> #include <Nazara/Core/Debug.hpp>
namespace Nz namespace Nz
{ {
MemoryStream::MemoryStream() :
Stream(StreamOption_None, OpenMode_ReadWrite),
m_pos(0)
{
}
MemoryStream::MemoryStream(const void* ptr, unsigned int size) :
MemoryStream()
{
m_buffer.Resize(size);
std::memcpy(m_buffer.GetBuffer(), ptr, size);
}
void MemoryStream::Clear() void MemoryStream::Clear()
{ {
m_buffer.Clear(); m_buffer->Clear();
m_pos = 0; m_pos = 0;
} }
bool MemoryStream::EndOfStream() const bool MemoryStream::EndOfStream() const
{ {
return m_pos >= m_buffer.size(); return m_pos >= m_buffer->size();
}
const ByteArray& MemoryStream::GetBuffer() const
{
return m_buffer;
} }
UInt64 MemoryStream::GetCursorPos() const UInt64 MemoryStream::GetCursorPos() const
@ -43,19 +26,20 @@ namespace Nz
return m_pos; return m_pos;
} }
const UInt8* MemoryStream::GetData() const
{
return m_buffer.GetConstBuffer();
}
UInt64 MemoryStream::GetSize() const UInt64 MemoryStream::GetSize() const
{ {
return m_buffer.size(); return m_buffer->GetSize();
}
void MemoryStream::SetBuffer(ByteArray* byteArray, UInt32 openMode)
{
m_buffer = byteArray;
m_openMode = openMode;
} }
bool MemoryStream::SetCursorPos(UInt64 offset) bool MemoryStream::SetCursorPos(UInt64 offset)
{ {
m_pos = std::min<UInt64>(offset, m_buffer.size()); m_pos = offset;
return true; return true;
} }
@ -67,10 +51,13 @@ namespace Nz
std::size_t MemoryStream::ReadBlock(void* buffer, std::size_t size) std::size_t MemoryStream::ReadBlock(void* buffer, std::size_t size)
{ {
std::size_t readSize = std::min<std::size_t>(size, static_cast<std::size_t>(m_buffer.size() - m_pos)); if (EndOfStream())
return 0;
std::size_t readSize = std::min<std::size_t>(size, static_cast<std::size_t>(m_buffer->GetSize() - m_pos));
if (buffer) if (buffer)
std::memcpy(buffer, &m_buffer[m_pos], readSize); std::memcpy(buffer, m_buffer->GetConstBuffer() + m_pos, readSize);
m_pos += readSize; m_pos += readSize;
return readSize; return readSize;
@ -79,10 +66,10 @@ namespace Nz
std::size_t MemoryStream::WriteBlock(const void* buffer, std::size_t size) std::size_t MemoryStream::WriteBlock(const void* buffer, std::size_t size)
{ {
std::size_t endPos = static_cast<std::size_t>(m_pos + size); std::size_t endPos = static_cast<std::size_t>(m_pos + size);
if (endPos > m_buffer.size()) if (endPos > m_buffer->GetSize())
m_buffer.Resize(endPos); m_buffer->Resize(endPos);
std::memcpy(&m_buffer[m_pos], buffer, size); std::memcpy(m_buffer->GetBuffer() + m_pos, buffer, size);
m_pos = endPos; m_pos = endPos;
return size; return size;

View File

@ -9,9 +9,17 @@
namespace Nz namespace Nz
{ {
MemoryView::MemoryView(void* ptr, UInt64 size) :
Stream(StreamOption_None, OpenMode_ReadWrite),
m_ptr(reinterpret_cast<UInt8*>(ptr)),
m_pos(0),
m_size(size)
{
}
MemoryView::MemoryView(const void* ptr, UInt64 size) : MemoryView::MemoryView(const void* ptr, UInt64 size) :
Stream(StreamOption_None, OpenMode_ReadOnly), Stream(StreamOption_None, OpenMode_ReadOnly),
m_ptr(reinterpret_cast<const UInt8*>(ptr)), m_ptr(reinterpret_cast<UInt8*>(const_cast<void*>(ptr))), //< Okay, right, const_cast is bad, but this pointer is still read-only
m_pos(0), m_pos(0),
m_size(size) m_size(size)
{ {
@ -41,7 +49,7 @@ namespace Nz
void MemoryView::FlushStream() void MemoryView::FlushStream()
{ {
NazaraInternalError("FlushStream has been called on a MemoryView"); // Nothing to do
} }
std::size_t MemoryView::ReadBlock(void* buffer, std::size_t size) std::size_t MemoryView::ReadBlock(void* buffer, std::size_t size)
@ -57,7 +65,13 @@ namespace Nz
std::size_t MemoryView::WriteBlock(const void* buffer, std::size_t size) std::size_t MemoryView::WriteBlock(const void* buffer, std::size_t size)
{ {
NazaraInternalError("WriteBlock has been called on a MemoryView"); std::size_t endPos = static_cast<std::size_t>(m_pos + size);
return 0; if (endPos > m_size)
size = m_size - m_pos;
std::memcpy(&m_ptr[m_pos], buffer, size);
m_pos += size;
return size;
} }
} }

View File

@ -4226,7 +4226,7 @@ namespace Nz
return context.stream->Write(string.GetConstBuffer(), string.GetSize()) == string.GetSize(); return context.stream->Write(string.GetConstBuffer(), string.GetSize()) == string.GetSize();
} }
bool Unserialize(UnserializationContext& context, String* string) bool Unserialize(SerializationContext& context, String* string)
{ {
UInt32 size; UInt32 size;
if (!Unserialize(context, &size)) if (!Unserialize(context, &size))