AuroraRuntime/Source/Memory/ByteBuffer.cpp

143 lines
3.2 KiB
C++

/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ByteBuffer.cpp
Date: 2021-8-28
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "ByteBuffer.hpp"
namespace Aurora::Memory
{
AuList<AuUInt8> ByteBuffer::ToVector()
{
AuList<AuUInt8> vec;
vec.resize(length);
if (flagCircular)
{
return RemainingBytesToVector(false);
}
else
{
std::memcpy(vec.data(), base, length);
}
return vec;
}
AUKN_SYM bool ByteBuffer::WriterTryGoForward(AuUInt32 offset)
{
auto n = Write(nullptr, offset);
SysAssert(n == offset); // TODO: writer go back
return true;
}
bool ByteBuffer::ReaderTryGoForward(AuUInt32 offset)
{
auto n = Read(nullptr, offset, false);
if (n != offset)
{
SysAssert(ReaderTryGoBack(n));
return false;
}
return true;
}
AuOptional<AuUInt8 *> ByteBuffer::WriterTryGetWriteHeadFor(AuUInt32 nBytes)
{
if (writePtr == base + length)
{
writePtr = base;
}
if (flagCircular)
{
AuUInt32 linearOverhead;
if (writePtr < readPtr)
{
linearOverhead = readPtr - writePtr;
}
else
{
linearOverhead = length - (writePtr - base);
}
if (linearOverhead < nBytes)
{
return {};
}
}
else
{
if (length - (writePtr - base) < nBytes)
{
return {};
}
}
return writePtr;
}
bool ByteBuffer::ReaderTryGoBack(AuUInt32 offset)
{
if (flagCircular)
{
auto readOffset = readPtr - base;
if (readOffset < offset)
{
auto absPosition = offset - readOffset;
auto goAround = absPosition;
auto backIdx = length - goAround;
auto writeOffset = writePtr - base;
if (writeOffset > backIdx)
{
return false;
}
readPtr = base + backIdx;
}
else
{
auto writeOffset = writePtr - base;
auto backIdx = readOffset - offset;
if (writeOffset > backIdx)
{
return false;
}
readPtr = base + backIdx;
}
return true;
}
else
{
auto readOffset = readPtr - base;
if (readOffset < offset)
{
return false;
}
readPtr -= offset;
return true;
}
}
AuUInt8 *ByteBuffer::begin()
{
SysAssert(!flagCircular, "::begin is only available for linear buffers");
return base;
}
AuUInt8 *ByteBuffer::end()
{
SysAssert(!flagCircular, "::end is only available for linear buffers");
return base + length;
}
}