[+] Futureproofing: AuByteBuffer flag
This commit is contained in:
parent
4a584ce73a
commit
98c1235554
@ -79,6 +79,10 @@ namespace Aurora::Memory
|
|||||||
AuUInt8 flagReadError : 1 {};
|
AuUInt8 flagReadError : 1 {};
|
||||||
AuUInt8 flagWriteError : 1 {};
|
AuUInt8 flagWriteError : 1 {};
|
||||||
AuUInt8 flagNoFree : 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
|
// TODO: flag: allow circular overrun to allow for 100% access of the buffer from either read head
|
||||||
// - implicit padding
|
// - implicit padding
|
||||||
AuUInt8 scaleSize {};//
|
AuUInt8 scaleSize {};//
|
||||||
@ -90,24 +94,25 @@ namespace Aurora::Memory
|
|||||||
*/
|
*/
|
||||||
inline ByteBuffer(ByteBuffer &&buffer)
|
inline ByteBuffer(ByteBuffer &&buffer)
|
||||||
{
|
{
|
||||||
this->base = buffer.base;
|
this->base = buffer.base;
|
||||||
this->length = buffer.length;
|
this->length = buffer.length;
|
||||||
this->allocSize = buffer.length;
|
this->allocSize = buffer.length;
|
||||||
this->writePtr = this->base + (buffer.writePtr - buffer.base);
|
this->writePtr = this->base + (buffer.writePtr - buffer.base);
|
||||||
this->readPtr = this->base + (buffer.readPtr - buffer.base);
|
this->readPtr = this->base + (buffer.readPtr - buffer.base);
|
||||||
this->flagCircular = buffer.flagCircular;
|
this->flagCircular = buffer.flagCircular;
|
||||||
this->flagExpandable = buffer.flagExpandable;
|
this->flagExpandable = buffer.flagExpandable;
|
||||||
this->scaleSize = buffer.scaleSize;
|
this->scaleSize = buffer.scaleSize;
|
||||||
this->flagReadError = buffer.flagReadError;
|
this->flagReadError = buffer.flagReadError;
|
||||||
this->flagWriteError = buffer.flagWriteError;
|
this->flagWriteError = buffer.flagWriteError;
|
||||||
buffer.base = {};
|
buffer.base = {};
|
||||||
buffer.length = {};
|
buffer.length = {};
|
||||||
buffer.allocSize = {};
|
buffer.allocSize = {};
|
||||||
buffer.writePtr = {};
|
buffer.writePtr = {};
|
||||||
buffer.readPtr = {};
|
buffer.readPtr = {};
|
||||||
buffer.flagCircular = {};
|
buffer.flagCircular = {};
|
||||||
buffer.flagExpandable = {};
|
buffer.flagExpandable = {};
|
||||||
buffer.scaleSize = {};
|
buffer.flagAlwaysExpandable = {};
|
||||||
|
buffer.scaleSize = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,6 +129,7 @@ namespace Aurora::Memory
|
|||||||
this->scaleSize = buffer.scaleSize;
|
this->scaleSize = buffer.scaleSize;
|
||||||
this->flagCircular = buffer.flagCircular;
|
this->flagCircular = buffer.flagCircular;
|
||||||
this->flagExpandable = buffer.flagExpandable;
|
this->flagExpandable = buffer.flagExpandable;
|
||||||
|
this->flagAlwaysExpandable = buffer.flagAlwaysExpandable;
|
||||||
if (!this->base)
|
if (!this->base)
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
@ -291,27 +297,29 @@ namespace Aurora::Memory
|
|||||||
* @brief base of the bytebuffer
|
* @brief base of the bytebuffer
|
||||||
* @return
|
* @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)
|
* @brief size of the byte array as requested by the caller (actual allocation may differ, ::allocSize)
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
inline auline AuUInt size() const;
|
inline auline AuUInt size() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief linear read begin
|
* @brief linear read begin
|
||||||
* @warning writers should use ::GetLinearWriteable(uDesiredLength) or ::GetOrAllocateLinearWriteable(...)
|
* @warning writers should use ::GetLinearWriteable(uDesiredLength) or ::GetOrAllocateLinearWriteable(...)
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
inline auline const AuUInt8 * begin() const;
|
inline auline const AuUInt8 * begin();
|
||||||
|
inline auline const AuUInt8 * cbegin() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief linear read end
|
* @brief linear read end
|
||||||
* @warning writers should use ::GetLinearWriteable(uDesiredLength) or ::GetOrAllocateLinearWriteable(...)
|
* @warning writers should use ::GetLinearWriteable(uDesiredLength) or ::GetOrAllocateLinearWriteable(...)
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
inline auline const AuUInt8 * end() const;
|
inline auline const AuUInt8 * end();
|
||||||
|
inline auline const AuUInt8 * cend() const;
|
||||||
|
|
||||||
inline auline bool empty() const;
|
inline auline bool empty() const;
|
||||||
|
|
||||||
@ -372,14 +380,52 @@ namespace Aurora::Memory
|
|||||||
inline auline bool CanWrite(AuUInt length);
|
inline auline bool CanWrite(AuUInt length);
|
||||||
inline auline bool CanRead(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);
|
inline auline MemoryViewRead GetLinearReadable(AuUInt length);
|
||||||
|
|
||||||
|
/// legacy: ForExactly variant
|
||||||
inline auline MemoryViewWrite GetLinearWriteable(AuUInt length);
|
inline auline MemoryViewWrite GetLinearWriteable(AuUInt length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Used to write into existing linear space (writing into a stream or preallocated packet)
|
* @brief Long story short, AuList<AuUInt8> ~= std::vector<AuUInt8>:
|
||||||
* or allocates the linear space if permitted (eg: a default constructor call would allow this).
|
* 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
|
||||||
* This is used to create APIs that accept an input bytebuffer write parameter over write view based apis.
|
* 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
|
* @param length
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -333,15 +333,56 @@ namespace Aurora::Memory
|
|||||||
return this->RemainingBytes(true) >= length;
|
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)
|
MemoryViewRead ByteBuffer::GetLinearReadable(AuUInt length)
|
||||||
{
|
{
|
||||||
auto view = this->GetNextLinearRead();
|
auto view = this->GetNextLinearRead();
|
||||||
return view.length < length ? MemoryViewRead {} : MemoryViewRead(view.ptr, length);
|
return view.length < length ? MemoryViewRead {} : MemoryViewRead(view.ptr, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* exactly */
|
||||||
MemoryViewWrite ByteBuffer::GetLinearWriteable(AuUInt length)
|
MemoryViewWrite ByteBuffer::GetLinearWriteable(AuUInt length)
|
||||||
{
|
{
|
||||||
auto view = this->GetNextLinearWrite();
|
auto view = this->GetNextLinearWrite();
|
||||||
|
if (this->flagAlwaysExpandable &&
|
||||||
|
(view.length < length))
|
||||||
|
{
|
||||||
|
return this->GetOrAllocateLinearWriteable(length);
|
||||||
|
}
|
||||||
return view.length < length ? MemoryViewWrite {} : MemoryViewWrite(view.ptr, length);
|
return view.length < length ? MemoryViewWrite {} : MemoryViewWrite(view.ptr, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,7 +392,7 @@ namespace Aurora::Memory
|
|||||||
{
|
{
|
||||||
return this->GetLinearWriteable(length);
|
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))
|
if (!this->Resize(length))
|
||||||
{
|
{
|
||||||
|
@ -92,7 +92,7 @@ namespace Aurora::Memory
|
|||||||
|
|
||||||
if ((len != requestLength))
|
if ((len != requestLength))
|
||||||
{
|
{
|
||||||
if ((flagExpandable))
|
if ((this->flagExpandable || this->flagAlwaysExpandable))
|
||||||
{
|
{
|
||||||
if (!Resize(offset + requestLength))
|
if (!Resize(offset + requestLength))
|
||||||
{
|
{
|
||||||
|
@ -41,8 +41,8 @@ namespace Aurora::Memory
|
|||||||
|
|
||||||
AuUInt8 &ByteBuffer::operator [](AuUInt idx) const
|
AuUInt8 &ByteBuffer::operator [](AuUInt idx) const
|
||||||
{
|
{
|
||||||
auto pBegin = (AuUInt8 *)this->begin(); // intentionally returning a volatile reference
|
auto pBegin = (AuUInt8 *)this->cbegin(); // intentionally returning a volatile reference
|
||||||
auto pEnd = this->end();
|
auto pEnd = this->cend();
|
||||||
SysAssert(idx < (AuUInt)(pEnd - pBegin));
|
SysAssert(idx < (AuUInt)(pEnd - pBegin));
|
||||||
return *(pBegin + idx);
|
return *(pBegin + idx);
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ namespace Aurora::Memory
|
|||||||
return IsEmpty();
|
return IsEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
const AuUInt8 *ByteBuffer::begin() const
|
const AuUInt8 *ByteBuffer::cbegin() const
|
||||||
{
|
{
|
||||||
if (this->flagCircular)
|
if (this->flagCircular)
|
||||||
{
|
{
|
||||||
@ -75,7 +75,12 @@ namespace Aurora::Memory
|
|||||||
return this->readPtr;
|
return this->readPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AuUInt8 *ByteBuffer::end() const
|
const AuUInt8 *ByteBuffer::begin()
|
||||||
|
{
|
||||||
|
return cbegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const AuUInt8 *ByteBuffer::cend() const
|
||||||
{
|
{
|
||||||
AuUInt8 *pBase {};
|
AuUInt8 *pBase {};
|
||||||
AuUInt uCount {};
|
AuUInt uCount {};
|
||||||
@ -132,6 +137,11 @@ namespace Aurora::Memory
|
|||||||
return uCount + pBase;
|
return uCount + pBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AuUInt8 *ByteBuffer::end()
|
||||||
|
{
|
||||||
|
return cend();
|
||||||
|
}
|
||||||
|
|
||||||
AuUInt32 ByteBuffer::GetAllocationPower() const
|
AuUInt32 ByteBuffer::GetAllocationPower() const
|
||||||
{
|
{
|
||||||
return AuUInt32(1) << (AuUInt32(this->scaleSize));
|
return AuUInt32(1) << (AuUInt32(this->scaleSize));
|
||||||
@ -139,7 +149,7 @@ namespace Aurora::Memory
|
|||||||
|
|
||||||
ByteBuffer::operator MemoryViewRead() const
|
ByteBuffer::operator MemoryViewRead() const
|
||||||
{
|
{
|
||||||
return MemoryViewRead(begin(), end());
|
return MemoryViewRead(cbegin(), cend());
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer::operator MemoryViewWrite()
|
ByteBuffer::operator MemoryViewWrite()
|
||||||
@ -177,7 +187,7 @@ namespace Aurora::Memory
|
|||||||
|
|
||||||
bool ByteBuffer::IsValid() const
|
bool ByteBuffer::IsValid() const
|
||||||
{
|
{
|
||||||
return (!IsEmpty() || this->flagExpandable) && !HasStreamError();
|
return (!IsEmpty() || (this->flagExpandable || this->flagAlwaysExpandable)) && !HasStreamError();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ByteBuffer::IsEmpty() const
|
bool ByteBuffer::IsEmpty() const
|
||||||
@ -195,6 +205,7 @@ namespace Aurora::Memory
|
|||||||
this->readPtr = this->base + (other.readPtr - other.base);
|
this->readPtr = this->base + (other.readPtr - other.base);
|
||||||
this->flagCircular = other.flagCircular;
|
this->flagCircular = other.flagCircular;
|
||||||
this->flagExpandable = other.flagExpandable;
|
this->flagExpandable = other.flagExpandable;
|
||||||
|
this->flagAlwaysExpandable = other.flagAlwaysExpandable;
|
||||||
this->scaleSize = other.scaleSize;
|
this->scaleSize = other.scaleSize;
|
||||||
other.base = {};
|
other.base = {};
|
||||||
other.length = {};
|
other.length = {};
|
||||||
@ -203,6 +214,7 @@ namespace Aurora::Memory
|
|||||||
other.readPtr = {};
|
other.readPtr = {};
|
||||||
other.flagCircular = {};
|
other.flagCircular = {};
|
||||||
other.flagExpandable = {};
|
other.flagExpandable = {};
|
||||||
|
other.flagAlwaysExpandable = {};
|
||||||
other.scaleSize = {};
|
other.scaleSize = {};
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -230,6 +242,7 @@ namespace Aurora::Memory
|
|||||||
AuMemcpy(this->base, buffer.base, this->length);
|
AuMemcpy(this->base, buffer.base, this->length);
|
||||||
this->flagCircular = buffer.flagCircular;
|
this->flagCircular = buffer.flagCircular;
|
||||||
this->flagExpandable = buffer.flagExpandable;
|
this->flagExpandable = buffer.flagExpandable;
|
||||||
|
this->flagAlwaysExpandable = buffer.flagAlwaysExpandable;
|
||||||
this->scaleSize = buffer.scaleSize;
|
this->scaleSize = buffer.scaleSize;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,8 @@ namespace Aurora::Memory
|
|||||||
{
|
{
|
||||||
auto readView = buffer.GetNextLinearRead();
|
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);
|
this->Resize((this->writePtr - this->base) + readView.length);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ namespace Aurora::Compression
|
|||||||
{
|
{
|
||||||
if (auto pBuffer = pThat->GetWeakBuffer())
|
if (auto pBuffer = pThat->GetWeakBuffer())
|
||||||
{
|
{
|
||||||
auto view = pBuffer->GetLinearReadable(dwAmount);
|
auto view = pBuffer->GetLinearReadableForNoMore(dwAmount);
|
||||||
in = (T *)view.ptr;
|
in = (T *)view.ptr;
|
||||||
inAlreadyAvailable = view.length;
|
inAlreadyAvailable = view.length;
|
||||||
pBuffer->readPtr += view.length;
|
pBuffer->readPtr += view.length;
|
||||||
|
Loading…
Reference in New Issue
Block a user