[+] AuMemory::SharedByteBuffer
[+] AuMemory::ByteBuffer.flagNoFree [*] SetBuffer(MemoryViewRead readView, bool bMoveWriteHeadForReaders = true); ...added bMoveWriteHeadForReaders [-] AuMemory::SetBuffer(const void *in, AuUInt length) [-] AuMemory::SetBuffer(const AuList<AuUInt8> &buffer) [*] Harden AuMemory::ByteBuffer::RemainingBytes bc it is a high level api that is not called excessively. Invalid head states should not mess with ::CanRead/::CanWrite [*] Harden AuMemory::ByteBuffer::RemainingWrite bc it is a high level api that is not called excessively. Invalid head states should not mess with ::CanRead/::CanWrite
This commit is contained in:
parent
e0d672ae9b
commit
37472e508e
@ -78,6 +78,7 @@ namespace Aurora::Memory
|
||||
|
||||
AuUInt8 flagReadError : 1 {};
|
||||
AuUInt8 flagWriteError : 1 {};
|
||||
AuUInt8 flagNoFree : 1 {};
|
||||
// TODO: flag: allow circular overrun to allow for 100% access of the buffer from either read head
|
||||
// - implicit padding
|
||||
AuUInt8 scaleSize {};//
|
||||
@ -388,9 +389,7 @@ namespace Aurora::Memory
|
||||
|
||||
inline auline bool Allocate(AuUInt length, bool fast = true);
|
||||
inline auline bool Allocate(AuUInt length, AuUInt alignment, bool fast = true);
|
||||
inline auline bool SetBuffer(MemoryViewRead readView);
|
||||
inline auline bool SetBuffer(const void *in, AuUInt length);
|
||||
inline auline bool SetBuffer(const AuList<AuUInt8> &buffer);
|
||||
inline auline bool SetBuffer(MemoryViewRead readView, bool bMoveWriteHeadForReaders = true);
|
||||
|
||||
/**
|
||||
* @brief Releases excess memory (like, shrink to fit in c++)
|
||||
@ -481,4 +480,31 @@ namespace Aurora::Memory
|
||||
{
|
||||
return ByteBuffer(length, true, false);
|
||||
}
|
||||
|
||||
struct SharedByteBuffer : ByteBuffer
|
||||
{
|
||||
AuSPtr<void> memory;
|
||||
|
||||
inline SharedByteBuffer(AuSPtr<MemoryViewWrite> pReadView) : ByteBuffer()
|
||||
{
|
||||
this->allocSize = 0;
|
||||
this->base = (AuUInt8 *)pReadView->ptr;
|
||||
this->length = pReadView->length;
|
||||
this->readPtr = this->base;
|
||||
this->writePtr = this->base + this->length;
|
||||
this->flagNoFree = true;
|
||||
this->memory = pReadView;
|
||||
}
|
||||
|
||||
inline SharedByteBuffer(AuSPtr<void> pRAIIParentOwner, MemoryViewWrite view) : ByteBuffer()
|
||||
{
|
||||
this->allocSize = 0;
|
||||
this->base = (AuUInt8 *)view.ptr;
|
||||
this->length = view.length;
|
||||
this->readPtr = this->base;
|
||||
this->writePtr = this->base + this->length;
|
||||
this->flagNoFree = true;
|
||||
this->memory = pRAIIParentOwner;
|
||||
}
|
||||
};
|
||||
}
|
@ -11,6 +11,11 @@ namespace Aurora::Memory
|
||||
{
|
||||
bool ByteBuffer::Allocate(AuUInt length, bool fast)
|
||||
{
|
||||
if (this->flagNoFree)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->base)
|
||||
{
|
||||
Free(this->base);
|
||||
@ -40,6 +45,11 @@ namespace Aurora::Memory
|
||||
|
||||
bool ByteBuffer::Allocate(AuUInt length, AuUInt alignment, bool fast)
|
||||
{
|
||||
if (this->flagNoFree)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->base)
|
||||
{
|
||||
Free(this->base);
|
||||
@ -68,8 +78,13 @@ namespace Aurora::Memory
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ByteBuffer::SetBuffer(MemoryViewRead readView)
|
||||
bool ByteBuffer::SetBuffer(MemoryViewRead readView, bool bMoveWriteHeadForReaders)
|
||||
{
|
||||
if (this->flagNoFree)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Allocate(readView.length))
|
||||
{
|
||||
return false;
|
||||
@ -81,28 +96,19 @@ namespace Aurora::Memory
|
||||
}
|
||||
|
||||
AuMemcpy(this->base, readView.ptr, this->length);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ByteBuffer::SetBuffer(const void *in, AuUInt length)
|
||||
{
|
||||
if (!Allocate(length))
|
||||
if (bMoveWriteHeadForReaders)
|
||||
{
|
||||
return false;
|
||||
this->readPtr = this->base;
|
||||
this->writePtr = this->base + this->length;
|
||||
}
|
||||
|
||||
AuMemcpy(this->base, in, this->length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ByteBuffer::SetBuffer(const AuList<AuUInt8> &buffer)
|
||||
{
|
||||
return SetBuffer(buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
void ByteBuffer::Reset()
|
||||
{
|
||||
if (this->base)
|
||||
if (this->base && !this->flagNoFree)
|
||||
{
|
||||
Free(this->base);
|
||||
this->base = {};
|
||||
@ -128,6 +134,11 @@ namespace Aurora::Memory
|
||||
|
||||
void ByteBuffer::GC()
|
||||
{
|
||||
if (this->flagNoFree)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this->base)
|
||||
{
|
||||
return;
|
||||
@ -151,6 +162,11 @@ namespace Aurora::Memory
|
||||
|
||||
bool ByteBuffer::Resize(AuUInt length)
|
||||
{
|
||||
if (this->flagNoFree)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AuUInt oldWriteIdx, oldReadIdx, oldLength, newLength;
|
||||
AuUInt8 *nextRead, *nextWrite, *nextPtr;
|
||||
|
||||
|
@ -97,20 +97,45 @@ namespace Aurora::Memory
|
||||
|
||||
AuUInt ByteBuffer::RemainingBytes(bool endAtWrite) const
|
||||
{
|
||||
if (flagCircular)
|
||||
// sanity:
|
||||
|
||||
if (this->writePtr > this->base + this->length)
|
||||
{
|
||||
if (readPtr == writePtr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this->writePtr < this->base)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this->readPtr > this->base + this->length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this->readPtr < this->base)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////
|
||||
|
||||
if (this->flagCircular)
|
||||
{
|
||||
if (this->readPtr == this->writePtr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if ((readPtr < writePtr) && (endAtWrite))
|
||||
else if ((this->readPtr < this->writePtr) && (endAtWrite))
|
||||
{
|
||||
return writePtr - readPtr;
|
||||
return this->writePtr - this->readPtr;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto linearOverhead = length - (readPtr - base);
|
||||
auto toWriteOverhead = writePtr - base;
|
||||
// you should be able to read the entirety of the buffer - writers cannot to prevent overflows
|
||||
auto linearOverhead = this->length - (this->readPtr - this->base);
|
||||
auto toWriteOverhead = this->writePtr - this->base;
|
||||
return linearOverhead + toWriteOverhead;
|
||||
}
|
||||
}
|
||||
@ -118,24 +143,48 @@ namespace Aurora::Memory
|
||||
{
|
||||
if (endAtWrite)
|
||||
{
|
||||
if (writePtr < readPtr)
|
||||
if (this->writePtr < this->readPtr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return writePtr - readPtr;
|
||||
return this->writePtr - this->readPtr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return (length - (readPtr - base));
|
||||
return (this->length - (this->readPtr - this->base));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AuUInt ByteBuffer::RemainingWrite(bool endAtRead) const
|
||||
{
|
||||
// sanity:
|
||||
|
||||
if (this->writePtr > this->base + this->length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this->writePtr < this->base)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this->readPtr > this->base + this->length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this->readPtr < this->base)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////
|
||||
|
||||
if (this->flagCircular)
|
||||
{
|
||||
if (this->readPtr == this->writePtr)
|
||||
@ -144,12 +193,14 @@ namespace Aurora::Memory
|
||||
}
|
||||
else if ((this->writePtr < this->readPtr) && (endAtRead))
|
||||
{
|
||||
// writers must not fall into a state of head parity, meaning that the entire buffer is readable
|
||||
return (this->readPtr - this->writePtr) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto linearOverhead = length - (writePtr - base);
|
||||
auto toWriteOverhead = readPtr - base;
|
||||
auto linearOverhead = this->length - (this->writePtr - this->base);
|
||||
auto toWriteOverhead = this->readPtr - this->base;
|
||||
// writers must not fall into a state of head parity, meaning that the entire buffer is readable
|
||||
return (linearOverhead + toWriteOverhead) - 1;
|
||||
}
|
||||
}
|
||||
@ -203,13 +254,17 @@ namespace Aurora::Memory
|
||||
pBase = this->readPtr;
|
||||
}
|
||||
|
||||
// sanity:
|
||||
|
||||
if (pBase + uCount > this->base + this->length)
|
||||
{
|
||||
this->flagReadError = true;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (pBase < this->base)
|
||||
{
|
||||
this->flagReadError = true;
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -251,13 +306,17 @@ namespace Aurora::Memory
|
||||
pBase = this->writePtr;
|
||||
}
|
||||
|
||||
// sanity:
|
||||
|
||||
if (pBase + uCount > this->base + this->length)
|
||||
{
|
||||
this->flagWriteError = true;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (pBase < this->base)
|
||||
{
|
||||
this->flagWriteError = true;
|
||||
return {};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user