[+] Futureproofing: AuByteBuffer flag
This commit is contained in:
parent
4a584ce73a
commit
98c1235554
@ -79,6 +79,10 @@ namespace Aurora::Memory
|
||||
AuUInt8 flagReadError : 1 {};
|
||||
AuUInt8 flagWriteError : 1 {};
|
||||
AuUInt8 flagNoFree : 1 {};
|
||||
AuUInt8 flagAlwaysExpandable : 1 {}; // it's a long story from how we got from string views to std::vector<std::uint8_t>s to current day AuByteBuffer.
|
||||
// anyway long story short, if you want a buffered api to write into us linearly and grow, enable me.
|
||||
// if you just want ::Write and similar functions to work keem me false and enable flagExpandable.
|
||||
// flagExpandable is for when the default constructor is called. i'm for apis that use us as an interface to grow.
|
||||
// TODO: flag: allow circular overrun to allow for 100% access of the buffer from either read head
|
||||
// - implicit padding
|
||||
AuUInt8 scaleSize {};//
|
||||
@ -90,24 +94,25 @@ namespace Aurora::Memory
|
||||
*/
|
||||
inline ByteBuffer(ByteBuffer &&buffer)
|
||||
{
|
||||
this->base = buffer.base;
|
||||
this->length = buffer.length;
|
||||
this->allocSize = buffer.length;
|
||||
this->writePtr = this->base + (buffer.writePtr - buffer.base);
|
||||
this->readPtr = this->base + (buffer.readPtr - buffer.base);
|
||||
this->flagCircular = buffer.flagCircular;
|
||||
this->flagExpandable = buffer.flagExpandable;
|
||||
this->scaleSize = buffer.scaleSize;
|
||||
this->flagReadError = buffer.flagReadError;
|
||||
this->flagWriteError = buffer.flagWriteError;
|
||||
buffer.base = {};
|
||||
buffer.length = {};
|
||||
buffer.allocSize = {};
|
||||
buffer.writePtr = {};
|
||||
buffer.readPtr = {};
|
||||
buffer.flagCircular = {};
|
||||
buffer.flagExpandable = {};
|
||||
buffer.scaleSize = {};
|
||||
this->base = buffer.base;
|
||||
this->length = buffer.length;
|
||||
this->allocSize = buffer.length;
|
||||
this->writePtr = this->base + (buffer.writePtr - buffer.base);
|
||||
this->readPtr = this->base + (buffer.readPtr - buffer.base);
|
||||
this->flagCircular = buffer.flagCircular;
|
||||
this->flagExpandable = buffer.flagExpandable;
|
||||
this->scaleSize = buffer.scaleSize;
|
||||
this->flagReadError = buffer.flagReadError;
|
||||
this->flagWriteError = buffer.flagWriteError;
|
||||
buffer.base = {};
|
||||
buffer.length = {};
|
||||
buffer.allocSize = {};
|
||||
buffer.writePtr = {};
|
||||
buffer.readPtr = {};
|
||||
buffer.flagCircular = {};
|
||||
buffer.flagExpandable = {};
|
||||
buffer.flagAlwaysExpandable = {};
|
||||
buffer.scaleSize = {};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,6 +129,7 @@ namespace Aurora::Memory
|
||||
this->scaleSize = buffer.scaleSize;
|
||||
this->flagCircular = buffer.flagCircular;
|
||||
this->flagExpandable = buffer.flagExpandable;
|
||||
this->flagAlwaysExpandable = buffer.flagAlwaysExpandable;
|
||||
if (!this->base)
|
||||
{
|
||||
Reset();
|
||||
@ -291,27 +297,29 @@ namespace Aurora::Memory
|
||||
* @brief base of the bytebuffer
|
||||
* @return
|
||||
*/
|
||||
inline auline AuUInt8 * data() const;
|
||||
inline auline AuUInt8 * data() const;
|
||||
|
||||
/**
|
||||
* @brief size of the byte array as requested by the caller (actual allocation may differ, ::allocSize)
|
||||
* @return
|
||||
*/
|
||||
inline auline AuUInt size() const;
|
||||
inline auline AuUInt size() const;
|
||||
|
||||
/**
|
||||
* @brief linear read begin
|
||||
* @warning writers should use ::GetLinearWriteable(uDesiredLength) or ::GetOrAllocateLinearWriteable(...)
|
||||
* @return
|
||||
*/
|
||||
inline auline const AuUInt8 * begin() const;
|
||||
inline auline const AuUInt8 * begin();
|
||||
inline auline const AuUInt8 * cbegin() const;
|
||||
|
||||
/**
|
||||
* @brief linear read end
|
||||
* @warning writers should use ::GetLinearWriteable(uDesiredLength) or ::GetOrAllocateLinearWriteable(...)
|
||||
* @return
|
||||
*/
|
||||
inline auline const AuUInt8 * end() const;
|
||||
inline auline const AuUInt8 * end();
|
||||
inline auline const AuUInt8 * cend() const;
|
||||
|
||||
inline auline bool empty() const;
|
||||
|
||||
@ -372,14 +380,52 @@ namespace Aurora::Memory
|
||||
inline auline bool CanWrite(AuUInt length);
|
||||
inline auline bool CanRead(AuUInt length);
|
||||
|
||||
/**
|
||||
* @brief Returns a linear amount of memory for exactly length of linear bytes
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
inline auline MemoryViewRead GetLinearReadableForExactly(AuUInt length)
|
||||
{
|
||||
return GetLinearReadable(length);
|
||||
}
|
||||
|
||||
inline auline MemoryViewWrite GetLinearWriteableForExactly(AuUInt length)
|
||||
{
|
||||
return GetLinearWriteable(length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a linear amount of memory of at least length
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
inline auline MemoryViewRead GetLinearReadableForAtleast(AuUInt length);
|
||||
|
||||
inline auline MemoryViewWrite GetLinearWriteableForAtleast(AuUInt length);
|
||||
|
||||
/**
|
||||
* @brief Returns a linear amount of memory capped to length
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
inline auline MemoryViewRead GetLinearReadableForNoMore(AuUInt length);
|
||||
|
||||
inline auline MemoryViewWrite GetLinearWriteableForNoMore(AuUInt length);
|
||||
|
||||
/// legacy: ForExactly variant
|
||||
inline auline MemoryViewRead GetLinearReadable(AuUInt length);
|
||||
|
||||
/// legacy: ForExactly variant
|
||||
inline auline MemoryViewWrite GetLinearWriteable(AuUInt length);
|
||||
|
||||
/**
|
||||
* @brief Used to write into existing linear space (writing into a stream or preallocated packet)
|
||||
* or allocates the linear space if permitted (eg: a default constructor call would allow this).
|
||||
*
|
||||
* This is used to create APIs that accept an input bytebuffer write parameter over write view based apis.
|
||||
* @brief Long story short, AuList<AuUInt8> ~= std::vector<AuUInt8>:
|
||||
* AuByteBuffer should be (was) a drag and drop replacement for trash code that uses lists as bytebuffers. This is opposed to ye old std::string contains anything buffers.
|
||||
* Either way, to the point, AuByteBuffer's default constructor is to allow for expandability on Write. GetOrAllocateLinearWriteable is used by certain parse APIs to
|
||||
* expand ONCE into a buffer that is uninitialized. Should the caller setup the AuByteBuffer, preallocate a runway, etc, etc, GetOrAllocateLinearWriteable will run on
|
||||
* the memory - the read/write heads of the already setup buffer.
|
||||
* Otherwise, the default constructor shall allow this to ALLOCATE ONCE given a buffer in an uninitialized/!IsValid()/!refByteBuffer state.
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
|
@ -333,15 +333,56 @@ namespace Aurora::Memory
|
||||
return this->RemainingBytes(true) >= length;
|
||||
}
|
||||
|
||||
MemoryViewRead ByteBuffer::GetLinearReadableForAtleast(AuUInt length)
|
||||
{
|
||||
auto view = this->GetNextLinearRead();
|
||||
return view.length < length ? MemoryViewRead {} : MemoryViewRead(view.ptr, view.length);
|
||||
}
|
||||
|
||||
MemoryViewWrite ByteBuffer::GetLinearWriteableForAtleast(AuUInt length)
|
||||
{
|
||||
auto view = this->GetNextLinearWrite();
|
||||
if (this->flagAlwaysExpandable &&
|
||||
(view.length < length))
|
||||
{
|
||||
return this->GetOrAllocateLinearWriteable(length);
|
||||
}
|
||||
return view.length < length ? MemoryViewWrite {} : MemoryViewWrite(view.ptr, view.length);
|
||||
}
|
||||
|
||||
MemoryViewRead ByteBuffer::GetLinearReadableForNoMore(AuUInt length)
|
||||
{
|
||||
auto view = this->GetNextLinearRead();
|
||||
return MemoryViewRead(view.ptr, AuMin(view.length, length));
|
||||
}
|
||||
|
||||
MemoryViewWrite ByteBuffer::GetLinearWriteableForNoMore(AuUInt length)
|
||||
{
|
||||
auto view = this->GetNextLinearWrite();
|
||||
if (this->flagAlwaysExpandable &&
|
||||
(view.length < length))
|
||||
{
|
||||
return this->GetOrAllocateLinearWriteable(length);
|
||||
}
|
||||
return MemoryViewWrite(view.ptr, AuMin(view.length, length));
|
||||
}
|
||||
|
||||
/* exactly */
|
||||
MemoryViewRead ByteBuffer::GetLinearReadable(AuUInt length)
|
||||
{
|
||||
auto view = this->GetNextLinearRead();
|
||||
return view.length < length ? MemoryViewRead {} : MemoryViewRead(view.ptr, length);
|
||||
}
|
||||
|
||||
/* exactly */
|
||||
MemoryViewWrite ByteBuffer::GetLinearWriteable(AuUInt length)
|
||||
{
|
||||
auto view = this->GetNextLinearWrite();
|
||||
if (this->flagAlwaysExpandable &&
|
||||
(view.length < length))
|
||||
{
|
||||
return this->GetOrAllocateLinearWriteable(length);
|
||||
}
|
||||
return view.length < length ? MemoryViewWrite {} : MemoryViewWrite(view.ptr, length);
|
||||
}
|
||||
|
||||
@ -351,7 +392,7 @@ namespace Aurora::Memory
|
||||
{
|
||||
return this->GetLinearWriteable(length);
|
||||
}
|
||||
else if (!this->flagCircular && this->length == 0 && this->flagExpandable)
|
||||
else if (!this->flagCircular && ((this->length == 0 && this->flagExpandable) || this->flagAlwaysExpandable))
|
||||
{
|
||||
if (!this->Resize(length))
|
||||
{
|
||||
|
@ -92,7 +92,7 @@ namespace Aurora::Memory
|
||||
|
||||
if ((len != requestLength))
|
||||
{
|
||||
if ((flagExpandable))
|
||||
if ((this->flagExpandable || this->flagAlwaysExpandable))
|
||||
{
|
||||
if (!Resize(offset + requestLength))
|
||||
{
|
||||
|
@ -41,8 +41,8 @@ namespace Aurora::Memory
|
||||
|
||||
AuUInt8 &ByteBuffer::operator [](AuUInt idx) const
|
||||
{
|
||||
auto pBegin = (AuUInt8 *)this->begin(); // intentionally returning a volatile reference
|
||||
auto pEnd = this->end();
|
||||
auto pBegin = (AuUInt8 *)this->cbegin(); // intentionally returning a volatile reference
|
||||
auto pEnd = this->cend();
|
||||
SysAssert(idx < (AuUInt)(pEnd - pBegin));
|
||||
return *(pBegin + idx);
|
||||
}
|
||||
@ -62,7 +62,7 @@ namespace Aurora::Memory
|
||||
return IsEmpty();
|
||||
}
|
||||
|
||||
const AuUInt8 *ByteBuffer::begin() const
|
||||
const AuUInt8 *ByteBuffer::cbegin() const
|
||||
{
|
||||
if (this->flagCircular)
|
||||
{
|
||||
@ -75,7 +75,12 @@ namespace Aurora::Memory
|
||||
return this->readPtr;
|
||||
}
|
||||
|
||||
const AuUInt8 *ByteBuffer::end() const
|
||||
const AuUInt8 *ByteBuffer::begin()
|
||||
{
|
||||
return cbegin();
|
||||
}
|
||||
|
||||
const AuUInt8 *ByteBuffer::cend() const
|
||||
{
|
||||
AuUInt8 *pBase {};
|
||||
AuUInt uCount {};
|
||||
@ -132,6 +137,11 @@ namespace Aurora::Memory
|
||||
return uCount + pBase;
|
||||
}
|
||||
|
||||
const AuUInt8 *ByteBuffer::end()
|
||||
{
|
||||
return cend();
|
||||
}
|
||||
|
||||
AuUInt32 ByteBuffer::GetAllocationPower() const
|
||||
{
|
||||
return AuUInt32(1) << (AuUInt32(this->scaleSize));
|
||||
@ -139,7 +149,7 @@ namespace Aurora::Memory
|
||||
|
||||
ByteBuffer::operator MemoryViewRead() const
|
||||
{
|
||||
return MemoryViewRead(begin(), end());
|
||||
return MemoryViewRead(cbegin(), cend());
|
||||
}
|
||||
|
||||
ByteBuffer::operator MemoryViewWrite()
|
||||
@ -177,7 +187,7 @@ namespace Aurora::Memory
|
||||
|
||||
bool ByteBuffer::IsValid() const
|
||||
{
|
||||
return (!IsEmpty() || this->flagExpandable) && !HasStreamError();
|
||||
return (!IsEmpty() || (this->flagExpandable || this->flagAlwaysExpandable)) && !HasStreamError();
|
||||
}
|
||||
|
||||
bool ByteBuffer::IsEmpty() const
|
||||
@ -195,6 +205,7 @@ namespace Aurora::Memory
|
||||
this->readPtr = this->base + (other.readPtr - other.base);
|
||||
this->flagCircular = other.flagCircular;
|
||||
this->flagExpandable = other.flagExpandable;
|
||||
this->flagAlwaysExpandable = other.flagAlwaysExpandable;
|
||||
this->scaleSize = other.scaleSize;
|
||||
other.base = {};
|
||||
other.length = {};
|
||||
@ -203,6 +214,7 @@ namespace Aurora::Memory
|
||||
other.readPtr = {};
|
||||
other.flagCircular = {};
|
||||
other.flagExpandable = {};
|
||||
other.flagAlwaysExpandable = {};
|
||||
other.scaleSize = {};
|
||||
return *this;
|
||||
}
|
||||
@ -230,6 +242,7 @@ namespace Aurora::Memory
|
||||
AuMemcpy(this->base, buffer.base, this->length);
|
||||
this->flagCircular = buffer.flagCircular;
|
||||
this->flagExpandable = buffer.flagExpandable;
|
||||
this->flagAlwaysExpandable = buffer.flagAlwaysExpandable;
|
||||
this->scaleSize = buffer.scaleSize;
|
||||
return *this;
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ namespace Aurora::Memory
|
||||
{
|
||||
auto readView = buffer.GetNextLinearRead();
|
||||
|
||||
if (this->flagExpandable && !this->CanWrite(readView.length))
|
||||
if ((this->flagExpandable || this->flagAlwaysExpandable) &&
|
||||
!this->CanWrite(readView.length))
|
||||
{
|
||||
this->Resize((this->writePtr - this->base) + readView.length);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ namespace Aurora::Compression
|
||||
{
|
||||
if (auto pBuffer = pThat->GetWeakBuffer())
|
||||
{
|
||||
auto view = pBuffer->GetLinearReadable(dwAmount);
|
||||
auto view = pBuffer->GetLinearReadableForNoMore(dwAmount);
|
||||
in = (T *)view.ptr;
|
||||
inAlreadyAvailable = view.length;
|
||||
pBuffer->readPtr += view.length;
|
||||
|
Loading…
Reference in New Issue
Block a user