[*] Fix bytebuffer crash on copy assignment when empty (also move the constructors implementation to a inl file)

This commit is contained in:
Reece Wilson 2024-05-22 11:43:46 +01:00
parent 60771f6e6b
commit 9b3aa12db6
2 changed files with 209 additions and 177 deletions

View File

@ -96,76 +96,23 @@ namespace Aurora::Memory
AuUInt8 scaleSize {}; // TODO:
///////////////////////////////////////////////////////////////////////
/**
* @brief Default constructor, allocates an auto-expanding linear bytebuffer
*/
inline ByteBuffer();
/**
* @brief Move constructor
* @param buffer
*/
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;
this->alignment = buffer.alignment;
buffer.base = {};
buffer.length = {};
buffer.allocSize = {};
buffer.writePtr = {};
buffer.readPtr = {};
buffer.flagCircular = {};
buffer.flagExpandable = {};
buffer.flagAlwaysExpandable = {};
buffer.scaleSize = {};
buffer.alignment = {};
}
inline ByteBuffer(ByteBuffer &&buffer);
/**
* @brief Copy with possible preserve pointers
* @param buffer
* @param preservePointers
*/
inline ByteBuffer(const ByteBuffer &buffer, bool preservePointers = true)
{
if (buffer.length)
{
if (buffer.alignment)
{
this->base = ZAlloc<AuUInt8 *>(buffer.length, buffer.alignment);
}
else
{
this->base = ZAlloc<AuUInt8 *>(buffer.length);
}
}
this->scaleSize = buffer.scaleSize;
this->flagCircular = buffer.flagCircular;
this->flagExpandable = buffer.flagExpandable;
this->flagAlwaysExpandable = buffer.flagAlwaysExpandable;
if (!this->base)
{
Reset();
return;
}
this->length = buffer.length;
this->allocSize = buffer.length;
if (preservePointers)
{
this->writePtr = this->base + (buffer.writePtr - buffer.base);
this->readPtr = this->base + (buffer.readPtr - buffer.base);
}
else
{
this->writePtr = this->base;
this->readPtr = this->base;
}
AuMemcpy(this->base, buffer.base, this->length);
}
inline ByteBuffer(const ByteBuffer &buffer, bool preservePointers = true);
/**
* @brief Copy pointer range into a new ring or byte buffer
@ -174,124 +121,16 @@ namespace Aurora::Memory
* @param circular
* @param expandable
*/
inline ByteBuffer(const void *in, AuUInt length, bool circular = false, bool expandable = false) : flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
{
this->scaleSize = kBufferInitialPower;
this->base = length ? ZAlloc<AuUInt8 *>(length) : nullptr;
if (!this->base)
{
Reset();
return;
}
if (!in)
{
Reset();
return;
}
this->length = length;
this->allocSize = length;
this->readPtr = this->base;
this->writePtr = this->readPtr + this->length;
AuMemcpy(this->base, in, this->length);
}
inline ByteBuffer(const void *in, AuUInt length, bool circular = false, bool expandable = false);
inline ByteBuffer(const AuList<AuUInt8> &vector, bool circular = false, bool expandable = false) : flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
{
this->scaleSize = kBufferInitialPower;
this->base = vector.size() ? ZAlloc<AuUInt8 *>(vector.size()) : nullptr;
if (!this->base)
{
Reset();
return;
}
this->length = vector.size();
this->allocSize = this->length;
this->readPtr = this->base;
this->writePtr = this->readPtr + this->length;
AuMemcpy(this->base, vector.data(), this->length);
}
inline ByteBuffer(const AuList<AuUInt8> &vector, bool circular = false, bool expandable = false);
inline ByteBuffer(AuUInt length, bool circular = false, bool expandable = false) : flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
{
this->scaleSize = kBufferInitialPower;
if (!length)
{
Reset();
return;
}
this->base = ZAlloc<AuUInt8 *>(length);
if (!this->base)
{
Reset();
return;
}
this->length = length;
this->allocSize = length;
this->readPtr = this->base;
this->writePtr = this->base;
}
inline ByteBuffer(AuUInt length, bool circular = false, bool expandable = false);
inline ByteBuffer(AuUInt length, AuUInt alignment, bool circular = false, bool expandable = false) : flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
{
if (!length)
{
Reset();
return;
}
this->scaleSize = kBufferInitialPower;
this->base = ZAlloc<AuUInt8 *>(length, alignment);
this->alignment = alignment;
if (!this->base)
{
Reset();
return;
}
this->length = length;
this->allocSize = length;
this->readPtr = this->base;
this->writePtr = this->base;
}
inline ByteBuffer(AuUInt length, AuUInt alignment, bool circular = false, bool expandable = false);
template<typename T>
ByteBuffer(T *base, T *end, bool circular = false, bool expandable = false) : flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
{
if (!base)
{
Reset();
return;
}
if (!end)
{
Reset();
return;
}
auto length = static_cast<AuUInt>(end - base) * sizeof(T);
this->base = length ? ZAlloc<AuUInt8 *>(length) : nullptr;
this->scaleSize = kBufferInitialPower;
if (!this->base)
{
Reset();
return;
}
this->length = length;
this->allocSize = length;
this->readPtr = this->base;
this->writePtr = this->base + length;
AuMemcpy(this->base, base, length);
}
/**
* @brief Default constructor, allocates an auto-expanding linear bytebuffer
*/
inline ByteBuffer() : flagCircular(0), flagExpandable(true), flagReadError(0), flagWriteError(0)
{
this->base = {};
this->length = {};
this->allocSize = {};
this->readPtr = {};
this->writePtr = {};
this->scaleSize = kBufferInitialPower;
}
ByteBuffer(T *base, T *end, bool circular = false, bool expandable = false);
inline ~ByteBuffer()
{

View File

@ -195,6 +195,190 @@ namespace Aurora::Memory
return !length || !base;
}
ByteBuffer::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;
this->alignment = buffer.alignment;
buffer.base = {};
buffer.length = {};
buffer.allocSize = {};
buffer.writePtr = {};
buffer.readPtr = {};
buffer.flagCircular = {};
buffer.flagExpandable = {};
buffer.flagAlwaysExpandable = {};
buffer.scaleSize = {};
buffer.alignment = {};
}
ByteBuffer::ByteBuffer(const ByteBuffer &buffer, bool preservePointers)
{
if (buffer.length)
{
if (buffer.alignment)
{
this->base = ZAlloc<AuUInt8 *>(buffer.length, buffer.alignment);
}
else
{
this->base = ZAlloc<AuUInt8 *>(buffer.length);
}
}
this->scaleSize = buffer.scaleSize;
this->flagCircular = buffer.flagCircular;
this->flagExpandable = buffer.flagExpandable;
this->flagAlwaysExpandable = buffer.flagAlwaysExpandable;
if (!this->base)
{
Reset();
return;
}
this->length = buffer.length;
this->allocSize = buffer.length;
if (preservePointers)
{
this->writePtr = this->base + (buffer.writePtr - buffer.base);
this->readPtr = this->base + (buffer.readPtr - buffer.base);
}
else
{
this->writePtr = this->base;
this->readPtr = this->base;
}
AuMemcpy(this->base, buffer.base, this->length);
}
ByteBuffer::ByteBuffer(const void *in, AuUInt length, bool circular, bool expandable) :
flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
{
this->scaleSize = kBufferInitialPower;
this->base = length ? ZAlloc<AuUInt8 *>(length) : nullptr;
if (!this->base)
{
Reset();
return;
}
if (!in)
{
Reset();
return;
}
this->length = length;
this->allocSize = length;
this->readPtr = this->base;
this->writePtr = this->readPtr + this->length;
AuMemcpy(this->base, in, this->length);
}
ByteBuffer::ByteBuffer(const AuList<AuUInt8> &vector, bool circular, bool expandable) :
flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
{
this->scaleSize = kBufferInitialPower;
this->base = vector.size() ? ZAlloc<AuUInt8 *>(vector.size()) : nullptr;
if (!this->base)
{
Reset();
return;
}
this->length = vector.size();
this->allocSize = this->length;
this->readPtr = this->base;
this->writePtr = this->readPtr + this->length;
AuMemcpy(this->base, vector.data(), this->length);
}
ByteBuffer::ByteBuffer(AuUInt length, bool circular, bool expandable) :
flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
{
this->scaleSize = kBufferInitialPower;
if (!length)
{
Reset();
return;
}
this->base = ZAlloc<AuUInt8 *>(length);
if (!this->base)
{
Reset();
return;
}
this->length = length;
this->allocSize = length;
this->readPtr = this->base;
this->writePtr = this->base;
}
ByteBuffer::ByteBuffer(AuUInt length, AuUInt alignment, bool circular, bool expandable) :
flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
{
if (!length)
{
Reset();
return;
}
this->scaleSize = kBufferInitialPower;
this->base = ZAlloc<AuUInt8 *>(length, alignment);
this->alignment = alignment;
if (!this->base)
{
Reset();
return;
}
this->length = length;
this->allocSize = length;
this->readPtr = this->base;
this->writePtr = this->base;
}
template<typename T>
ByteBuffer::ByteBuffer(T *base, T *end, bool circular, bool expandable) :
flagCircular(circular), flagExpandable(expandable), flagReadError(0), flagWriteError(0)
{
if (!base)
{
Reset();
return;
}
if (!end)
{
Reset();
return;
}
auto length = static_cast<AuUInt>(end - base) * sizeof(T);
this->base = length ? ZAlloc<AuUInt8 *>(length) : nullptr;
this->scaleSize = kBufferInitialPower;
if (!this->base)
{
Reset();
return;
}
this->length = length;
this->allocSize = length;
this->readPtr = this->base;
this->writePtr = this->base + length;
AuMemcpy(this->base, base, length);
}
ByteBuffer::ByteBuffer() :
flagCircular(0), flagExpandable(true), flagReadError(0), flagWriteError(0)
{
this->base = {};
this->length = {};
this->allocSize = {};
this->readPtr = {};
this->writePtr = {};
this->scaleSize = kBufferInitialPower;
}
ByteBuffer &ByteBuffer::operator =(ByteBuffer &&other)
{
Reset();
@ -225,6 +409,15 @@ namespace Aurora::Memory
ByteBuffer &ByteBuffer::operator =(const ByteBuffer &buffer)
{
if (!buffer.length)
{
AuResetMember(*this);
this->flagCircular = buffer.flagCircular;
this->flagExpandable = buffer.flagExpandable;
this->flagAlwaysExpandable = buffer.flagAlwaysExpandable;
return *this;
}
this->base = FAlloc<AuUInt8 *>(buffer.length);
if (!this->base)
{