[+] Missing ByteBuffer::ReadString implementation after 2 years of procrastination

This commit is contained in:
Reece Wilson 2024-01-10 17:44:14 +00:00
parent 95adfe127d
commit 4112e33e48

View File

@ -161,8 +161,188 @@ namespace Aurora::Memory
bool ByteBuffer::ReadString(AuString &string, EStringType type, Locale::ECodePage codepage)
{
// TODO: ...
return {};
AuUInt64 uLength {};
AuUInt uZeroByteLength { 0 };
string.clear();
switch (type)
{
case EStringType::eStringByte:
{
AuUInt8 temp;
if (!Read<AuUInt8>(temp))
{
return {};
}
uLength = temp;
break;
}
case EStringType::eStringWord:
{
AuUInt16 temp;
if (!Read<AuUInt16>(temp))
{
return {};
}
uLength = temp;
break;
}
case EStringType::eStringDword:
{
AuUInt32 temp;
if (!Read<AuUInt32>(temp))
{
return {};
}
uLength = temp;
break;
}
case EStringType::eStringQword:
{
AuUInt64 temp;
if (!Read<AuUInt64>(temp))
{
return {};
}
uLength = temp;
break;
}
case EStringType::eStringTerminated:
{
MemoryViewRead read;
bool bFound {};
AuUInt uOffset {};
auto start = this->readPtr;
uLength = 0;
if (codepage == Locale::ECodePage::eUTF16 || codepage == Locale::ECodePage::eUTF16BE)
{
uZeroByteLength = 2;
}
else if (codepage == Locale::ECodePage::eUTF32 || codepage == Locale::ECodePage::eUTF32BE)
{
uZeroByteLength = 4;
}
else
{
uZeroByteLength = 1;
}
do
{
read = this->GetNextLinearRead();
auto uCodepoints = read.length / uZeroByteLength;
for (AU_ITERATE_N(i, uCodepoints))
{
bool bIsZero {};
auto uLocalOffset = i * uZeroByteLength;
auto pCodepoint = read.begin() + uLocalOffset;
switch (uZeroByteLength)
{
case 1:
{
bIsZero = !bool(*pCodepoint);
break;
}
case 2:
{
bIsZero = !bool(AuReadU16(pCodepoint, 0));
break;
}
case 4:
{
bIsZero = !bool(AuReadU32(pCodepoint, 0));
break;
}
};
if (bIsZero)
{
uLength = uOffset + uLocalOffset;
bFound = true;
read = MemoryViewRead {};
break;
}
}
uOffset += read.length;
this->readPtr += read.length;
}
while (read);
if (!bFound)
{
this->flagReadError = true;
return false;
}
this->readPtr = start;
break;
}
};
if (uLength > kMaxSaneElementsForAuMemory)
{
this->flagReadError = true;
return false;
}
if (uLength)
{
if (codepage == Locale::ECodePage::eUTF8)
{
auto view = this->GetLinearReadableForExactly((AuUInt)uLength);
if (!view)
{
string.resize((AuUInt)uLength);
if (this->Read(string.data(), uLength) != uLength)
{
this->flagReadError = true;
return false;
}
}
else
{
string = AuString(view.begin(), view.end());
this->readPtr += uLength;
}
}
else
{
AuString temp;
auto view = this->GetLinearReadableForExactly((AuUInt)uLength);
if (!view)
{
temp.resize((AuUInt)uLength);
if (this->Read(temp.data(), uLength) != uLength)
{
this->flagReadError = true;
return false;
}
view = temp;
}
else
{
this->readPtr += uLength;
}
auto [uRead, uWritten] = Locale::Encoding::DecodeUTF8(view, string, codepage);
if (uRead != uLength)
{
this->flagReadError = true;
return false;
}
}
}
this->readPtr += uZeroByteLength;
return true;
}
}