First
This commit is contained in:
@@ -0,0 +1,259 @@
|
||||
#include "StdAfx.h"
|
||||
#include "fs/MemorySink.h"
|
||||
#include "fs/MemorySource.h"
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "tl/narrow_cast.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace fs
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MemorySink::MemorySink(size_t reserve)
|
||||
{
|
||||
m_data.reserve(reserve);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MemorySink::MemorySink(tl::memory_buffer&& buffer)
|
||||
: m_offset(buffer.size())
|
||||
, m_data(std::move(buffer))
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MemorySink::reserve(size_t capacity)
|
||||
{
|
||||
m_data.reserve(capacity);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MemorySink::shrinkToFit()
|
||||
{
|
||||
m_data.shrink_to_fit();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t MemorySink::write(tl::span<const uint8_t> data)
|
||||
{
|
||||
if (m_optLastError.has_value())
|
||||
{
|
||||
TL_FAIL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (data.empty())
|
||||
return 0;
|
||||
|
||||
const size_t totalSize = m_offset + data.size();
|
||||
if (m_data.size() < totalSize)
|
||||
m_data.resize_uninitialized(totalSize);
|
||||
|
||||
memcpy(m_data.data() + m_offset, data.data(), data.size());
|
||||
m_offset += data.size();
|
||||
return data.size();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MemorySink::seekBeg(uint64_t offset)
|
||||
{
|
||||
if (m_optLastError.has_value())
|
||||
{
|
||||
TL_FAIL();
|
||||
return;
|
||||
}
|
||||
|
||||
size_t realOffset;
|
||||
if constexpr (sizeof(uint64_t) > sizeof(size_t))
|
||||
realOffset = tl::narrow<size_t>(offset);
|
||||
else
|
||||
realOffset = offset;
|
||||
|
||||
if (m_offset != realOffset)
|
||||
{
|
||||
m_offset = realOffset;
|
||||
if (m_data.size() < m_offset)
|
||||
m_data.resize_uninitialized(m_offset);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MemorySink::seekRel(int64_t offset)
|
||||
{
|
||||
if (m_optLastError.has_value())
|
||||
{
|
||||
TL_FAIL();
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset != 0)
|
||||
{
|
||||
int64_t newOffset = static_cast<int64_t>(tell());
|
||||
newOffset += offset;
|
||||
newOffset = tl::max<int64_t>(newOffset, 0);
|
||||
seekBeg(static_cast<uint64_t>(newOffset));
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint64_t MemorySink::tell() const
|
||||
{
|
||||
if (m_optLastError.has_value())
|
||||
{
|
||||
TL_FAIL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint64_t MemorySink::getSize() const
|
||||
{
|
||||
if (m_optLastError.has_value())
|
||||
{
|
||||
TL_FAIL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tl::span<const uint8_t> MemorySink::getDataView() const
|
||||
{
|
||||
if (m_optLastError.has_value())
|
||||
{
|
||||
TL_FAIL();
|
||||
return {};
|
||||
}
|
||||
return tl::span<const uint8_t>{m_data.data(), m_data.size()};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tl::memory_buffer MemorySink::getDataCopy() const
|
||||
{
|
||||
if (m_optLastError.has_value())
|
||||
{
|
||||
TL_FAIL();
|
||||
return {};
|
||||
}
|
||||
return m_data;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tl::memory_buffer MemorySink::getDataMove()
|
||||
{
|
||||
if (m_optLastError.has_value())
|
||||
{
|
||||
TL_FAIL();
|
||||
return {};
|
||||
}
|
||||
return std::move(m_data);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MemorySink::clear()
|
||||
{
|
||||
if (m_optLastError.has_value())
|
||||
{
|
||||
TL_FAIL();
|
||||
return;
|
||||
}
|
||||
|
||||
m_offset = 0;
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MemorySink::swap(MemorySource& source)
|
||||
{
|
||||
if (m_optLastError.has_value())
|
||||
{
|
||||
TL_FAIL();
|
||||
return;
|
||||
}
|
||||
|
||||
tl::swap(source.m_data, m_data);
|
||||
source.m_offset = 0;
|
||||
m_offset = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tl::span<uint8_t> MemorySink::map(size_t size)
|
||||
{
|
||||
if (m_optLastError.has_value())
|
||||
{
|
||||
TL_FAIL();
|
||||
return {};
|
||||
}
|
||||
|
||||
const size_t remainingBytes = m_data.size() - m_offset;
|
||||
const size_t bytesToMap = tl::min(size, remainingBytes);
|
||||
if (bytesToMap == 0)
|
||||
return {};
|
||||
|
||||
const tl::span<uint8_t> mView(&m_data[m_offset], bytesToMap);
|
||||
m_offset += bytesToMap;
|
||||
|
||||
TL_ASSERT(m_offset <= getSize());
|
||||
|
||||
return mView;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tl::optional<Error> MemorySink::getLastError() const
|
||||
{
|
||||
auto error = m_optLastError;
|
||||
m_optLastError = tl::nullopt;
|
||||
return error;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t MemorySink::getPreferredBufferSize() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MemorySink::preReserve(size_t size)
|
||||
{
|
||||
if (m_optLastError.has_value())
|
||||
{
|
||||
TL_FAIL();
|
||||
return;
|
||||
}
|
||||
m_data.reserve(m_data.size() + size);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tl::memory_buffer MemorySink::extractData(MemorySink sink)
|
||||
{
|
||||
return sink.getDataMove();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user