[*] Minor AuByteBuffer TypeReadWrite "improvements"
(more like, i cant be bothered to finish this in a clean way and we need a minimum viable product)
This commit is contained in:
parent
fc08e8351d
commit
1cd56ab161
@ -506,10 +506,16 @@ namespace Aurora::Memory
|
||||
inline bool Pad(AuUInt16 aPowOf2, AuUInt8 magicCharacter = '\x00');
|
||||
inline bool Fill(AuUInt length, AuUInt8 magicCharacter = '\x00');
|
||||
|
||||
// Typed read/write
|
||||
// Templated read/write for **PODs**
|
||||
// (yes, there's some support for non-primitive classes this early into the abstraction.)
|
||||
// (AuString and some other containers may work, but really, we need a typed bytebuffer.)
|
||||
template<typename T>
|
||||
T Read();
|
||||
|
||||
// Panics if flagReadError is true by the end of deserialization
|
||||
template<typename T>
|
||||
T ReadChecked();
|
||||
|
||||
template<typename T>
|
||||
bool Write(const T &in);
|
||||
|
||||
|
@ -9,14 +9,49 @@
|
||||
|
||||
namespace Aurora::Memory
|
||||
{
|
||||
static const auto kMaxSaneElementsForAuMemory = 0xFFFFF;
|
||||
#if !defined(AURORA_RUNTIME_BUFFER_MAX_ELEMS)
|
||||
#define AURORA_RUNTIME_BUFFER_MAX_ELEMS 0xFFFFFu
|
||||
#endif
|
||||
|
||||
static const auto kMaxSaneElementsForAuMemory = AURORA_RUNTIME_BUFFER_MAX_ELEMS;
|
||||
|
||||
template<typename T>
|
||||
bool ByteBuffer::Read(T &out)
|
||||
{
|
||||
if constexpr (AuIsClass_v<T>)
|
||||
{
|
||||
if constexpr (AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, AuRemoveReference_t<T>>::value)
|
||||
if constexpr (AuIsTuple_v<AuRemoveReference_t<T>>)
|
||||
{
|
||||
AuTupleForEach(out, [=](auto &tupleElement)
|
||||
{
|
||||
Read(tupleElement);
|
||||
});
|
||||
return !this->flagReadError;
|
||||
}
|
||||
else if constexpr (AuIsOptional_v<AuRemoveReference_t<T>>)
|
||||
{
|
||||
if (Read<bool>())
|
||||
{
|
||||
AuRemoveReference_t<decltype(out.value())> value;
|
||||
|
||||
Read(value);
|
||||
|
||||
if (this->flagReadError)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
out = T { AuMove(value) };
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return !this->flagReadError;
|
||||
}
|
||||
}
|
||||
else if constexpr (AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, AuRemoveReference_t<T>>::value)
|
||||
{
|
||||
if (Read<AuUInt32>() != sizeof(typename T::value_type))
|
||||
{
|
||||
@ -31,11 +66,67 @@ namespace Aurora::Memory
|
||||
return false;
|
||||
}
|
||||
|
||||
out.resize(uLength);
|
||||
if (!AuTryResize(out, uLength))
|
||||
{
|
||||
this->flagReadError = true;
|
||||
SysPushErrorMemory();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto i = 0u; i < uLength; i++)
|
||||
{
|
||||
Read<T::value_type>(out[i]);
|
||||
Read(out[i]);
|
||||
}
|
||||
|
||||
return !this->flagReadError;
|
||||
}
|
||||
else if constexpr (AuIsBST_v<AuRemoveReference_t<T>> ||
|
||||
AuIsHashMap_v<AuRemoveReference_t<T>>)
|
||||
{
|
||||
if (Read<AuUInt32>() != sizeof(typename T::key_type))
|
||||
{
|
||||
this->flagReadError = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Read<AuUInt32>() != sizeof(typename T::mapped_type))
|
||||
{
|
||||
this->flagReadError = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto uLength = Read<AuUInt32>();
|
||||
if (uLength > kMaxSaneElementsForAuMemory)
|
||||
{
|
||||
this->flagReadError = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AuTryReserve(out, uLength))
|
||||
{
|
||||
this->flagReadError = true;
|
||||
SysPushErrorMemory();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto i = 0u; i < uLength; i++)
|
||||
{
|
||||
typename T::key_type key;
|
||||
typename T::mapped_type value;
|
||||
|
||||
Read(key);
|
||||
if (this->flagReadError)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Read(value);
|
||||
if (this->flagReadError)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
out[key] = value;
|
||||
}
|
||||
|
||||
return !this->flagReadError;
|
||||
@ -71,19 +162,58 @@ namespace Aurora::Memory
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T ByteBuffer::ReadChecked()
|
||||
{
|
||||
T a {};
|
||||
Read(a);
|
||||
SysAssert(!this->flagReadError);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool ByteBuffer::Write(const T &in)
|
||||
{
|
||||
if constexpr (AuIsClass_v<T>)
|
||||
{
|
||||
if constexpr (AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, AuRemoveReference_t<T>>::value)
|
||||
if constexpr (AuIsTuple_v<AuRemoveReference_t<T>>)
|
||||
{
|
||||
AuTupleForEach(in, [=](auto &tupleElement)
|
||||
{
|
||||
Write(tupleElement);
|
||||
});
|
||||
return !this->flagWriteError;
|
||||
}
|
||||
else if constexpr (AuIsOptional_v<AuRemoveReference_t<T>>)
|
||||
{
|
||||
Write<bool>(AuStaticCast<bool>(in));
|
||||
Write(in.value());
|
||||
return !this->flagWriteError;
|
||||
}
|
||||
else if constexpr (AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, AuRemoveReference_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);
|
||||
Write(item);
|
||||
}
|
||||
|
||||
return !this->flagWriteError;
|
||||
}
|
||||
else if constexpr (AuIsBST_v<AuRemoveReference_t<T>> ||
|
||||
AuIsHashMap_v<AuRemoveReference_t<T>>)
|
||||
|
||||
{
|
||||
Write<AuUInt32>(sizeof(typename T::key_type));
|
||||
Write<AuUInt32>(sizeof(typename T::mapped_type));
|
||||
Write<AuUInt32>(AuUInt32(in.size()));
|
||||
|
||||
for (const auto &[key, value]: in)
|
||||
{
|
||||
Write(key);
|
||||
Write(value);
|
||||
}
|
||||
|
||||
return !this->flagWriteError;
|
||||
|
Loading…
Reference in New Issue
Block a user