[+] Missing ByteBuffer::ReadString implementation after 2 years of procrastination
This commit is contained in:
parent
95adfe127d
commit
4112e33e48
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user