[*] Fix auline macro under msvc

[*] Breakout ByteBuffer into inl files
This commit is contained in:
Reece Wilson 2022-01-18 18:59:19 +00:00
parent da2b59d083
commit 62aecf3308
13 changed files with 743 additions and 635 deletions

View File

@ -1,7 +0,0 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Array.hpp
Date: 2021-8-5
Author: Reece
***/

View File

@ -176,515 +176,58 @@ namespace Aurora::Memory
}
// Iterator
AUKN_SYM AuUInt8 *begin() const;
AUKN_SYM AuUInt8 *end() const;
inline auline AuUInt8 * begin() const;
inline auline AuUInt8 * end() const;
// To alternative types
AUKN_SYM AuList<AuUInt8> ToVector() const;
// Seek
AUKN_SYM bool ReaderTryGoForward(AuUInt32 offset);
AUKN_SYM bool ReaderTryGoBack(AuUInt32 offset);
AUKN_SYM bool WriterTryGoForward(AuUInt32 offset);
// Utils To alternative types
inline auline AuList<AuUInt8> ToVector() const;
inline AuUInt32 GetAllocationPower() const;
inline operator AuList<AuUInt8>() const;
inline operator MemoryViewRead() const;
inline AuList<AuUInt8> RemainingBytesToVector(bool endAtWrite = true) const;
AUKN_SYM AuOptional<AuUInt8 *> WriterTryGetWriteHeadFor(AuUInt32 nBytes);
// Seek / Position
inline auline bool ReaderTryGoForward(AuUInt32 offset);
inline auline bool ReaderTryGoBack(AuUInt32 offset);
inline auline bool WriterTryGoForward(AuUInt32 offset);
inline AuUInt32 GetAllocationPower() const
{
return AuUInt32(1) << (AuUInt32(this->scaleSize));
}
inline auline AuUInt RemainingWrite(bool endAtRead = true);
inline auline AuUInt RemainingBytes(bool endAtWrite = true);
inline operator AuList<AuUInt8>() const
{
return ToVector();
}
inline auline bool Skip(AuUInt count);
inline auline AuUInt GetReadOffset() const;
inline auline AuUInt GetWriteOffset() const;
inline operator MemoryViewRead() const
{
return MemoryViewRead(begin(), end());
}
inline AuOptional<AuUInt8 *> WriterTryGetWriteHeadFor(AuUInt32 nBytes);
inline bool Allocate(AuUInt length, bool fast = true)
{
if (this->base)
{
Free(this->base);
this->base = nullptr;
}
this->base = fast ? FAlloc<AuUInt8 *>(length) : ZAlloc<AuUInt8 *>(length);
if (!this->base)
{
return false;
}
this->length = length;
this->allocSize = length;
this->readPtr = this->base;
this->writePtr = this->readPtr + this->length;
return true;
}
// Memory operations
inline bool SetBuffer(const void *in, AuUInt length)
{
if (!Allocate(length))
{
return false;
}
inline auline bool Allocate(AuUInt length, bool fast = true);
inline auline bool SetBuffer(const void *in, AuUInt length);
inline auline bool SetBuffer(const AuList<AuUInt8> &buffer);
std::memcpy(this->base, in, this->length);
return true;
}
inline auline void GC();
inline bool SetBuffer(const AuList<AuUInt8> &buffer)
{
return SetBuffer(buffer.data(), buffer.size());
}
inline auline bool Resize(AuUInt length);
// Template implementation
// TODO: move to .inl
// Basic Read Write
inline auline AuUInt Write(const void *buffer, AuUInt requestLength);
inline auline AuUInt Read(void *out, AuUInt requestedLength, bool peek = false);
// Typed read/write
template<typename T>
T Read();
template<typename T>
inline bool Read(T &out)
{
if constexpr (std::is_class_v<T>)
{
if constexpr (AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, std::remove_reference_t<T>>::value)
{
if (Read<AuUInt32>() != sizeof(typename T::value_type))
{
this->flagReadError = true;
return false;
}
auto len = Read<AuUInt32>();
out.resize(len);
for (auto i = 0u; i < len; i++)
{
Read<T::value_type>(out[i]);
}
return !this->flagReadError;
}
else if constexpr (std::is_same_v<std::remove_reference_t<T>, AuString>)
{
out.resize(Read<AuUInt32>());
Read(out.data(), out.size());
return !this->flagReadError;
}
}
auto skipped = Read(&out, sizeof(T));
if (skipped != sizeof(T))
{
this->flagReadError = true;
return false;
}
return true;
}
bool Write(const T &in);
template<typename T>
inline T Read()
{
T a{};
Read(a);
return a;
}
template<typename T>
inline bool Write(const T &in)
{
if constexpr (std::is_class_v<T>)
{
if constexpr (AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, std::remove_reference_t<T>>::value)
{
Write<AuUInt32>(sizeof(typename T::value_type));
Write<AuUInt32>(AuUInt32(in.size()));
for (const auto &item : in)
{
Write<T::value_type>(item);
}
return !this->flagWriteError;
}
else if constexpr (std::is_same_v<std::remove_reference_t<T>, AuString>)
{
Write<AuUInt32>(AuUInt32(in.size()));
Write(in.data(), in.size());
return !this->flagWriteError;
}
}
auto skipped = Write(&in, sizeof(T));
if (skipped != sizeof(T))
{
this->flagWriteError = true;
return false;
}
return true;
}
inline void GC()
{
if (this->allocSize == this->length) return;
auto temp = Memory::FRealloc(this->base, this->length);
if (!temp) return;
this->base = temp;
this->length = this->length;
this->allocSize = this->length;
}
inline bool Resize(AuUInt length)
{
AuUInt oldWriteIdx, oldReadIdx, oldLength, newLength;
AuUInt8 *nextRead, *nextWrite, *nextPtr;
if (this->allocSize > length)
{
this->length = length;
oldLength = this->length;
newLength = length;
nextPtr = this->base;
oldWriteIdx = this->writePtr - this->base;
oldReadIdx = this->readPtr - this->base;
nextRead = nextPtr + oldReadIdx;
nextWrite = nextPtr + oldWriteIdx;
}
else
{
auto scale = GetAllocationPower();
oldLength = this->length;
newLength = std::max(AuUInt(length), AuUInt(((this->allocSize / scale) + 1) * scale));
nextPtr = ZRealloc(this->base, newLength);
if (!nextPtr)
{
return false;
}
oldWriteIdx = this->writePtr - this->base;
oldReadIdx = this->readPtr - this->base;
nextRead = nextPtr + oldReadIdx;
nextWrite = nextPtr + oldWriteIdx;
this->allocSize = newLength;
this->length = length;
}
this->base = nextPtr;
if (!flagCircular)
{
this->readPtr = nextRead;
this->writePtr = nextWrite;
}
else
{
if (this->writePtr > this->readPtr)
{
this->readPtr = nextRead;
this->writePtr = nextWrite;
}
else
{
auto expansion = newLength - oldLength;
auto movableTail = std::min(oldWriteIdx, expansion);
std::memcpy(nextPtr + oldLength, nextPtr, movableTail);
this->readPtr = nextRead;
this->writePtr = nextPtr + oldLength + movableTail;
}
}
return true;
}
inline AuUInt Write(const void *buffer, AuUInt requestLength)
{
AuUInt linearOverhead = 0, toReadOverhead = 0, linearWritable = 0, toReadWritable = 0, writable = 0;
auto cptr = reinterpret_cast<const AuUInt8 *>(buffer);
if (flagCircular)
{
// 0 1 2 3 4 5
// W R
// 6 - (1) = 5 -> read bound; we have zero overhead not 5
if (writePtr < readPtr)
{
// Handle read-bound writes
linearOverhead = readPtr - writePtr;
toReadOverhead = 0;
}
else
{
// Handle ordinary stream consume bound IO
linearOverhead = length - (writePtr - base);
toReadOverhead = readPtr - base;
}
writable = std::min(linearOverhead + toReadOverhead, requestLength);
linearWritable = std::min(linearOverhead, requestLength);
toReadWritable = writable - linearWritable;
if (cptr)
{
std::memcpy(writePtr, cptr, linearWritable);
}
writePtr += linearWritable;
if (toReadWritable)
{
writePtr = base;
if (cptr)
{
std::memcpy(writePtr, cptr + linearOverhead, toReadWritable);
}
writePtr += toReadWritable;
}
#if 0
if (writePtr == base + length)
{
writePtr = base;
}
#endif
return linearWritable + toReadWritable;
}
else
{
auto offset = writePtr - base;
auto overhead = length - offset;
AuUInt len = std::min(overhead, requestLength);
if ((len != requestLength) && (flagExpandable))
{
if (!Resize(offset + requestLength))
{
return 0;
}
overhead = length - offset;
len = std::min(overhead, requestLength);
}
if (buffer)
{
std::memcpy(writePtr, buffer, len);
}
writePtr += len;
return len;
}
}
inline AuUInt RemainingBytes(bool endAtWrite = true)
{
if (flagCircular)
{
if ((readPtr < writePtr) && (endAtWrite))
{
return length - (writePtr - readPtr);
}
else
{
auto linearOverhead = length - (readPtr - base);
auto toWriteOverhead = writePtr - base;
return linearOverhead + toWriteOverhead;
}
}
else
{
if (endAtWrite)
{
if (writePtr < readPtr)
{
return 0;
}
else
{
return writePtr - readPtr;
}
}
else
{
return (length - (readPtr - base));
}
}
}
inline AuUInt RemainingWrite(bool endAtRead = true)
{
if (flagCircular)
{
if ((writePtr < readPtr) && (endAtRead))
{
return length - (readPtr - writePtr);
}
else
{
auto linearOverhead = length - (writePtr - base);
auto toWriteOverhead = readPtr - base;
return linearOverhead + toWriteOverhead;
}
}
else
{
return length - (writePtr - base);
}
}
inline AuList<AuUInt8> RemainingBytesToVector(bool endAtWrite = true) const
{
AuList<AuUInt8> vec;
if (flagCircular)
{
if ((readPtr < writePtr) && (endAtWrite))
{
auto len = length - (writePtr - readPtr);
vec.resize(len);
std::memcpy(vec.data(), readPtr, len);
}
else
{
auto linearOverhead = length - (readPtr - base);
auto toWriteOverhead = endAtWrite ? (writePtr - base) : (readPtr - base);
vec.resize(linearOverhead + toWriteOverhead);
std::memcpy(vec.data(), readPtr, linearOverhead);
std::memcpy(vec.data() + linearOverhead, base, linearOverhead);
}
}
else
{
AuUInt len;
if (endAtWrite)
{
len = writePtr - readPtr;
}
else
{
len = length - (readPtr - base);
}
vec.resize(len);
std::memcpy(vec.data(), readPtr, len);
}
return vec;
}
inline bool Skip(AuUInt count)
{
auto oldptr = readPtr;
auto skipped = Read(nullptr, count);
if (skipped != count)
{
readPtr = oldptr;
return false;
}
return true;
}
inline AuUInt GetReadOffset() const
{
if (flagCircular)
{
return 0;
}
else
{
return readPtr - base;
}
}
inline AuUInt GetWriteOffset() const
{
if (flagCircular)
{
return 0;
}
else
{
return writePtr - base;
}
}
inline AuUInt Read(void *out, AuUInt requestedLength, bool peek = false)
{
AuUInt linearOverhead = 0, toWriteOverhead = 0, linearReadable = 0, toWriteReadable = 0;
if (flagCircular)
{
if (readPtr < writePtr)
{
linearOverhead = writePtr - readPtr;
toWriteOverhead = 0;
}
else
{
linearOverhead = length - (readPtr - base);
toWriteOverhead = writePtr - base;
}
auto readable = std::min(linearOverhead + toWriteOverhead, requestedLength);
linearReadable = std::min(linearOverhead, requestedLength);
toWriteReadable = readable - linearReadable;
if (out)
{
std::memcpy(out, readPtr, linearOverhead);
}
if (!peek)
{
readPtr += linearOverhead;
}
if (toWriteOverhead)
{
std::memcpy(reinterpret_cast<AuUInt8 *>(out) + linearOverhead, base, toWriteReadable);
if (!peek)
{
readPtr = base + toWriteReadable;
}
}
#if 0
if (readPtr == base + length)
{
readPtr = base;
}
#endif
return linearReadable + toWriteReadable;
}
else
{
AuUInt len = std::min(AuUInt(writePtr - readPtr), requestedLength);
if (out)
{
std::memcpy(out, readPtr, len);
}
if (!peek)
{
readPtr += len;
}
return len;
}
}
bool Read(T &out);
};
}

View File

@ -0,0 +1,123 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ByteBuffer_Memory.inl
Date: 2022-1-18
Author: Reece
***/
#pragma once
namespace Aurora::Memory
{
bool ByteBuffer::Allocate(AuUInt length, bool fast)
{
if (this->base)
{
Free(this->base);
this->base = nullptr;
}
this->base = fast ? FAlloc<AuUInt8 *>(length) : ZAlloc<AuUInt8 *>(length);
if (!this->base)
{
return false;
}
this->length = length;
this->allocSize = length;
this->readPtr = this->base;
this->writePtr = this->readPtr + this->length;
return true;
}
bool ByteBuffer::SetBuffer(const void *in, AuUInt length)
{
if (!Allocate(length))
{
return false;
}
std::memcpy(this->base, in, this->length);
return true;
}
bool ByteBuffer::SetBuffer(const AuList<AuUInt8> &buffer)
{
return SetBuffer(buffer.data(), buffer.size());
}
void ByteBuffer::GC()
{
if (this->allocSize == this->length) return;
auto temp = Memory::FRealloc(this->base, this->length);
if (!temp) return;
this->base = temp;
this->length = this->length;
this->allocSize = this->length;
}
bool ByteBuffer::Resize(AuUInt length)
{
AuUInt oldWriteIdx, oldReadIdx, oldLength, newLength;
AuUInt8 *nextRead, *nextWrite, *nextPtr;
if (this->allocSize > length)
{
this->length = length;
oldLength = this->length;
newLength = length;
nextPtr = this->base;
oldWriteIdx = this->writePtr - this->base;
oldReadIdx = this->readPtr - this->base;
nextRead = nextPtr + oldReadIdx;
nextWrite = nextPtr + oldWriteIdx;
}
else
{
auto scale = GetAllocationPower();
oldLength = this->length;
newLength = std::max(AuUInt(length), AuUInt(((this->allocSize / scale) + 1) * scale));
nextPtr = ZRealloc(this->base, newLength);
if (!nextPtr)
{
return false;
}
oldWriteIdx = this->writePtr - this->base;
oldReadIdx = this->readPtr - this->base;
nextRead = nextPtr + oldReadIdx;
nextWrite = nextPtr + oldWriteIdx;
this->allocSize = newLength;
this->length = length;
}
this->base = nextPtr;
if (!flagCircular)
{
this->readPtr = nextRead;
this->writePtr = nextWrite;
}
else
{
if (this->writePtr > this->readPtr)
{
this->readPtr = nextRead;
this->writePtr = nextWrite;
}
else
{
auto expansion = newLength - oldLength;
auto movableTail = std::min(oldWriteIdx, expansion);
std::memcpy(nextPtr + oldLength, nextPtr, movableTail);
this->readPtr = nextRead;
this->writePtr = nextPtr + oldLength + movableTail;
}
}
return true;
}
}

View File

@ -0,0 +1,206 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ByteBuffer_Position.inl
Date: 2022-1-18
Author: Reece
***/
#pragma once
namespace Aurora::Memory
{
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;
}
}
AuUInt ByteBuffer::RemainingBytes(bool endAtWrite)
{
if (flagCircular)
{
if ((readPtr < writePtr) && (endAtWrite))
{
return length - (writePtr - readPtr);
}
else
{
auto linearOverhead = length - (readPtr - base);
auto toWriteOverhead = writePtr - base;
return linearOverhead + toWriteOverhead;
}
}
else
{
if (endAtWrite)
{
if (writePtr < readPtr)
{
return 0;
}
else
{
return writePtr - readPtr;
}
}
else
{
return (length - (readPtr - base));
}
}
}
AuUInt ByteBuffer::RemainingWrite(bool endAtRead)
{
if (flagCircular)
{
if ((writePtr < readPtr) && (endAtRead))
{
return length - (readPtr - writePtr);
}
else
{
auto linearOverhead = length - (writePtr - base);
auto toWriteOverhead = readPtr - base;
return linearOverhead + toWriteOverhead;
}
}
else
{
return length - (writePtr - base);
}
}
bool ByteBuffer::Skip(AuUInt count)
{
auto oldptr = readPtr;
auto skipped = Read(nullptr, count);
if (skipped != count)
{
readPtr = oldptr;
return false;
}
return true;
}
AuUInt ByteBuffer::GetReadOffset() const
{
if (flagCircular)
{
return 0;
}
else
{
return readPtr - base;
}
}
AuUInt ByteBuffer::GetWriteOffset() const
{
if (flagCircular)
{
return 0;
}
else
{
return writePtr - base;
}
}
}

View File

@ -0,0 +1,163 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ByteBuffer_ReadWrite.inl
Date: 2022-1-18
Author: Reece
***/
#pragma once
namespace Aurora::Memory
{
AuUInt ByteBuffer::Write(const void *buffer, AuUInt requestLength)
{
AuUInt linearOverhead = 0, toReadOverhead = 0, linearWritable = 0, toReadWritable = 0, writable = 0;
auto cptr = reinterpret_cast<const AuUInt8 *>(buffer);
if (flagCircular)
{
// 0 1 2 3 4 5
// W R
// 6 - (1) = 5 -> read bound; we have zero overhead not 5
if (writePtr < readPtr)
{
// Handle read-bound writes
linearOverhead = readPtr - writePtr;
toReadOverhead = 0;
}
else
{
// Handle ordinary stream consume bound IO
linearOverhead = length - (writePtr - base);
toReadOverhead = readPtr - base;
}
writable = std::min(linearOverhead + toReadOverhead, requestLength);
linearWritable = std::min(linearOverhead, requestLength);
toReadWritable = writable - linearWritable;
if (cptr)
{
std::memcpy(writePtr, cptr, linearWritable);
}
writePtr += linearWritable;
if (toReadWritable)
{
writePtr = base;
if (cptr)
{
std::memcpy(writePtr, cptr + linearOverhead, toReadWritable);
}
writePtr += toReadWritable;
}
#if 0
if (writePtr == base + length)
{
writePtr = base;
}
#endif
return linearWritable + toReadWritable;
}
else
{
auto offset = writePtr - base;
auto overhead = length - offset;
AuUInt len = std::min(overhead, requestLength);
if ((len != requestLength) && (flagExpandable))
{
if (!Resize(offset + requestLength))
{
return 0;
}
overhead = length - offset;
len = std::min(overhead, requestLength);
}
if (buffer)
{
std::memcpy(writePtr, buffer, len);
}
writePtr += len;
return len;
}
}
AuUInt ByteBuffer::Read(void *out, AuUInt requestedLength, bool peek)
{
AuUInt linearOverhead = 0, toWriteOverhead = 0, linearReadable = 0, toWriteReadable = 0;
if (flagCircular)
{
if (readPtr < writePtr)
{
linearOverhead = writePtr - readPtr;
toWriteOverhead = 0;
}
else
{
linearOverhead = length - (readPtr - base);
toWriteOverhead = writePtr - base;
}
auto readable = std::min(linearOverhead + toWriteOverhead, requestedLength);
linearReadable = std::min(linearOverhead, requestedLength);
toWriteReadable = readable - linearReadable;
if (out)
{
std::memcpy(out, readPtr, linearOverhead);
}
if (!peek)
{
readPtr += linearOverhead;
}
if (toWriteOverhead)
{
std::memcpy(reinterpret_cast<AuUInt8 *>(out) + linearOverhead, base, toWriteReadable);
if (!peek)
{
readPtr = base + toWriteReadable;
}
}
#if 0
if (readPtr == base + length)
{
readPtr = base;
}
#endif
return linearReadable + toWriteReadable;
}
else
{
AuUInt len = std::min(AuUInt(writePtr - readPtr), requestedLength);
if (out)
{
std::memcpy(out, readPtr, len);
}
if (!peek)
{
readPtr += len;
}
return len;
}
}
}

View File

@ -0,0 +1,13 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ByteBuffer_TaggedReadWrite.inl
Date: 2022-1-18
Author: Reece
***/
#pragma once
namespace Aurora::Memory
{
}

View File

@ -0,0 +1,93 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ByteBuffer_TypedReadWrite.inl
Date: 2022-1-18
Author: Reece
***/
#pragma once
namespace Aurora::Memory
{
template<typename T>
bool ByteBuffer::Read(T &out)
{
if constexpr (std::is_class_v<T>)
{
if constexpr (AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, std::remove_reference_t<T>>::value)
{
if (Read<AuUInt32>() != sizeof(typename T::value_type))
{
this->flagReadError = true;
return false;
}
auto len = Read<AuUInt32>();
out.resize(len);
for (auto i = 0u; i < len; i++)
{
Read<T::value_type>(out[i]);
}
return !this->flagReadError;
}
else if constexpr (std::is_same_v<std::remove_reference_t<T>, AuString>)
{
out.resize(Read<AuUInt32>());
Read(out.data(), out.size());
return !this->flagReadError;
}
}
auto skipped = Read(&out, sizeof(T));
if (skipped != sizeof(T))
{
this->flagReadError = true;
return false;
}
return true;
}
template<typename T>
T ByteBuffer::Read()
{
T a {};
Read(a);
return a;
}
template<typename T>
bool ByteBuffer::Write(const T &in)
{
if constexpr (std::is_class_v<T>)
{
if constexpr (AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, std::remove_reference_t<T>>::value)
{
Write<AuUInt32>(sizeof(typename T::value_type));
Write<AuUInt32>(AuUInt32(in.size()));
for (const auto &item : in)
{
Write<T::value_type>(item);
}
return !this->flagWriteError;
}
else if constexpr (std::is_same_v<std::remove_reference_t<T>, AuString>)
{
Write<AuUInt32>(AuUInt32(in.size()));
Write(in.data(), in.size());
return !this->flagWriteError;
}
}
auto skipped = Write(&in, sizeof(T));
if (skipped != sizeof(T))
{
this->flagWriteError = true;
return false;
}
return true;
}
}

View File

@ -0,0 +1,95 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ByteBuffer_Utils.inl
Date: 2022-1-18
Author: Reece
***/
#pragma once
namespace Aurora::Memory
{
AuList<AuUInt8> ByteBuffer::ToVector() const
{
AuList<AuUInt8> vec;
vec.resize(length);
if (flagCircular)
{
return RemainingBytesToVector(false);
}
else
{
std::memcpy(vec.data(), base, length);
}
return vec;
}
AuUInt8 *ByteBuffer::begin() const
{
SysAssert(!flagCircular, "::begin is only available for linear buffers");
return base;
}
AuUInt8 *ByteBuffer::end() const
{
SysAssert(!flagCircular, "::end is only available for linear buffers");
return base + length;
}
AuUInt32 ByteBuffer::GetAllocationPower() const
{
return AuUInt32(1) << (AuUInt32(this->scaleSize));
}
ByteBuffer::operator AuList<AuUInt8>() const
{
return ToVector();
}
ByteBuffer::operator MemoryViewRead() const
{
return MemoryViewRead(begin(), end());
}
AuList<AuUInt8> ByteBuffer::RemainingBytesToVector(bool endAtWrite) const
{
AuList<AuUInt8> vec;
if (flagCircular)
{
if ((readPtr < writePtr) && (endAtWrite))
{
auto len = length - (writePtr - readPtr);
vec.resize(len);
std::memcpy(vec.data(), readPtr, len);
}
else
{
auto linearOverhead = length - (readPtr - base);
auto toWriteOverhead = endAtWrite ? (writePtr - base) : (readPtr - base);
vec.resize(linearOverhead + toWriteOverhead);
std::memcpy(vec.data(), readPtr, linearOverhead);
std::memcpy(vec.data() + linearOverhead, base, linearOverhead);
}
}
else
{
AuUInt len;
if (endAtWrite)
{
len = writePtr - readPtr;
}
else
{
len = length - (readPtr - base);
}
vec.resize(len);
std::memcpy(vec.data(), readPtr, len);
}
return vec;
}
}

View File

@ -145,5 +145,4 @@ namespace Aurora::Memory
#endif
}
#include "Array.hpp"
#include "ByteBuffer.hpp"
#include "ByteBuffer.hpp"

View File

@ -0,0 +1,7 @@
#include "ByteBuffer_Utils.inl"
#include "ByteBuffer_TaggedReadWrite.inl"
#include "ByteBuffer_TypedReadWrite.inl"
#include "ByteBuffer_ReadWrite.inl"
#include "ByteBuffer_Memory.inl"
#include "ByteBuffer_Utils.inl"
#include "ByteBuffer_Position.inl"

View File

@ -23,7 +23,7 @@
#include "../AuroraMacros.hpp"
#include <utilitY>
#include <utility>
#include <memory>
#include <optional>
#include <functional>
@ -73,6 +73,8 @@
#include "Time/Time.hpp"
#include "Loop/Loop.hpp"
#include "Memory/_ByteBuffer.hpp"
namespace AuAsync = Aurora::Async;
namespace AuBuild = Aurora::Build;
namespace AuCompression = Aurora::Compression;

View File

@ -85,7 +85,7 @@
#if !defined(AU_INLINE)
#if defined(AURORA_COMPILER_MSVC)
#define AU_INLINE __declspec(__forceinline)
#define AU_INLINE __forceinline
#else
#define AU_INLINE __attribute__((always_inline))
#endif

View File

@ -10,134 +10,5 @@
namespace Aurora::Memory
{
AuList<AuUInt8> ByteBuffer::ToVector() const
{
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() const
{
SysAssert(!flagCircular, "::begin is only available for linear buffers");
return base;
}
AuUInt8 *ByteBuffer::end() const
{
SysAssert(!flagCircular, "::end is only available for linear buffers");
return base + length;
}
}