You're breathtaking!
This commit is contained in:
163
Source/Engine/Serialization/MemoryWriteStream.cpp
Normal file
163
Source/Engine/Serialization/MemoryWriteStream.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Engine/Platform/Platform.h"
|
||||
#include "Engine/Platform/File.h"
|
||||
#include "MemoryWriteStream.h"
|
||||
|
||||
MemoryWriteStream::MemoryWriteStream()
|
||||
: _buffer(nullptr)
|
||||
, _position(nullptr)
|
||||
, _capacity(0)
|
||||
{
|
||||
}
|
||||
|
||||
MemoryWriteStream::MemoryWriteStream(uint32 capacity)
|
||||
: _capacity(capacity)
|
||||
{
|
||||
if (capacity > 0)
|
||||
{
|
||||
_buffer = (byte*)Allocator::Allocate(capacity);
|
||||
if (_buffer == nullptr)
|
||||
{
|
||||
OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffer = nullptr;
|
||||
}
|
||||
_position = _buffer;
|
||||
}
|
||||
|
||||
MemoryWriteStream::~MemoryWriteStream()
|
||||
{
|
||||
Allocator::Free(_buffer);
|
||||
}
|
||||
|
||||
void* MemoryWriteStream::Move(uint32 bytes)
|
||||
{
|
||||
const uint32 position = GetPosition();
|
||||
|
||||
// Check if there is need to update a buffer size
|
||||
if (_capacity - position < bytes)
|
||||
{
|
||||
// Perform reallocation
|
||||
uint32 newCapacity = _capacity != 0 ? _capacity * 2 : 256;
|
||||
while (newCapacity < position + bytes)
|
||||
newCapacity *= 2;
|
||||
byte* newBuf = (byte*)Allocator::Allocate(newCapacity);
|
||||
if (newBuf == nullptr)
|
||||
{
|
||||
OUT_OF_MEMORY;
|
||||
}
|
||||
Platform::MemoryCopy(newBuf, _buffer, _capacity);
|
||||
Allocator::Free(_buffer);
|
||||
|
||||
// Update state
|
||||
_buffer = newBuf;
|
||||
_capacity = newCapacity;
|
||||
_position = _buffer + position;
|
||||
}
|
||||
|
||||
// Skip bytes
|
||||
_position += bytes;
|
||||
|
||||
// Return pointer to begin
|
||||
return _buffer + position;
|
||||
}
|
||||
|
||||
void MemoryWriteStream::Reset(uint32 capacity)
|
||||
{
|
||||
// Check if resize
|
||||
if (capacity > _capacity)
|
||||
{
|
||||
Allocator::Free(_buffer);
|
||||
_buffer = (byte*)Allocator::Allocate(capacity);
|
||||
if (_buffer == nullptr)
|
||||
{
|
||||
OUT_OF_MEMORY;
|
||||
}
|
||||
_capacity = capacity;
|
||||
}
|
||||
|
||||
// Reset pointer
|
||||
_position = _buffer;
|
||||
}
|
||||
|
||||
bool MemoryWriteStream::SaveToFile(const StringView& path) const
|
||||
{
|
||||
// Open file for writing
|
||||
auto file = File::Open(path, FileMode::CreateAlways, FileAccess::Write, FileShare::Read);
|
||||
if (file == nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Write data
|
||||
uint32 bytesWritten;
|
||||
file->Write(GetHandle(), GetPosition(), &bytesWritten);
|
||||
|
||||
Delete(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
void MemoryWriteStream::Flush()
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
void MemoryWriteStream::Close()
|
||||
{
|
||||
Allocator::Free(_buffer);
|
||||
_buffer = nullptr;
|
||||
_position = nullptr;
|
||||
_capacity = 0;
|
||||
}
|
||||
|
||||
uint32 MemoryWriteStream::GetLength()
|
||||
{
|
||||
return _capacity;
|
||||
}
|
||||
|
||||
uint32 MemoryWriteStream::GetPosition()
|
||||
{
|
||||
return static_cast<uint32>(_position - _buffer);
|
||||
}
|
||||
|
||||
void MemoryWriteStream::SetPosition(uint32 seek)
|
||||
{
|
||||
_position = _buffer + seek;
|
||||
}
|
||||
|
||||
void MemoryWriteStream::WriteBytes(const void* data, uint32 bytes)
|
||||
{
|
||||
ASSERT(bytes >= 0);
|
||||
|
||||
// Calculate current position
|
||||
const uint32 position = GetPosition();
|
||||
|
||||
// Check if there is need to update a buffer size
|
||||
if (_capacity - position < bytes)
|
||||
{
|
||||
// Perform reallocation
|
||||
uint32 newCapacity = _capacity != 0 ? _capacity * 2 : 256;
|
||||
while (newCapacity < position + bytes)
|
||||
newCapacity *= 2;
|
||||
byte* newBuf = (byte*)Allocator::Allocate(newCapacity);
|
||||
if (newBuf == nullptr)
|
||||
{
|
||||
OUT_OF_MEMORY;
|
||||
}
|
||||
Platform::MemoryCopy(newBuf, _buffer, _capacity);
|
||||
Allocator::Free(_buffer);
|
||||
|
||||
// Update state
|
||||
_buffer = newBuf;
|
||||
_capacity = newCapacity;
|
||||
_position = _buffer + position;
|
||||
}
|
||||
|
||||
// Copy data
|
||||
Platform::MemoryCopy(_position, data, bytes);
|
||||
_position += bytes;
|
||||
}
|
||||
Reference in New Issue
Block a user