[+] AuParse::[Stringify/Parse][U/S]Int[16] class of parse APIs
[*] Optimize UNIX IPC ABI: Handle String encodes an array of U16s to optimize space. Could still be better.
This commit is contained in:
parent
e4e0af2f1d
commit
21902a5d5b
@ -218,6 +218,68 @@ namespace Aurora::Parse
|
||||
AUKN_SYM void SerializeToken(ParsableTag type, const ParseValue &value, AuString &str);
|
||||
AUKN_SYM void Serialize(const ParsedObject &structure, AuString &ret);
|
||||
|
||||
AUKN_SYM AuString StringifyUInt16(AuUInt64 in, bool bZeroX = true);
|
||||
AUKN_SYM AuString StringifySInt16(AuInt64 in, bool bZeroX = true);
|
||||
|
||||
/**
|
||||
* @brief Parse Base10 null string
|
||||
*/
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt(const char *begin, const char *&end);
|
||||
|
||||
/**
|
||||
* @brief Parse Base10 null string
|
||||
*/
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt(const char *begin, const char *&end);
|
||||
|
||||
/**
|
||||
* @brief Parse Base64 string with optional 0x suffix and 'h' ending
|
||||
*/
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt16(const char *begin, const char *&end);
|
||||
|
||||
/**
|
||||
* @brief Parse Base64 string with optional 0x suffix and 'h' ending
|
||||
*/
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt16(const char *begin, const char *&end);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Parse Base64 null terminated string with optional 0x suffix and 'h' ending
|
||||
*/
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt16(const char *begin);
|
||||
|
||||
/**
|
||||
* @brief Parse Base64 abi terminated string with optional 0x suffix and 'h' ending
|
||||
*/
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt16(const AuString &str);
|
||||
|
||||
/**
|
||||
* @brief Parse Base64 null terminated string with optional 0x suffix and 'h' ending
|
||||
*/
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt16(const char *begin);
|
||||
|
||||
/**
|
||||
* @brief Parse Base64 abi terminated string with optional 0x suffix and 'h' ending
|
||||
*/
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt16(const AuString &str);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Parse abi null terminated string
|
||||
*/
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt(const AuString &str);
|
||||
|
||||
/**
|
||||
* @brief Parse Base10 null terminated string
|
||||
*/
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt(const char *begin);
|
||||
|
||||
/**
|
||||
* @brief Parse Base10 abi terminated string
|
||||
*/
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt(const AuString &str);
|
||||
|
||||
/**
|
||||
* @brief Parse Base10 null terminated string
|
||||
*/
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt(const char *begin);
|
||||
}
|
@ -27,7 +27,7 @@ namespace Aurora::IO::FS
|
||||
bool directIO;
|
||||
};
|
||||
|
||||
struct LinuxAsyncFileStream : public IAsyncFileStream
|
||||
struct LinuxAsyncFileStream : IAsyncFileStream
|
||||
{
|
||||
AuSPtr<IAsyncTransaction> NewTransaction() override;
|
||||
bool BlockingTruncate(AuUInt64 length) override;
|
||||
|
@ -0,0 +1,2 @@
|
||||
// TODO: Kevent can be backed by POSIX AIO
|
||||
// :D
|
@ -147,7 +147,7 @@ namespace Aurora::IO::IPC
|
||||
const char *endPtr = &in[stringOffset]; \
|
||||
const char *startPtr = &in[startOffset]; \
|
||||
stringOffset++; \
|
||||
auto nextIntOpt = AuParse::ParseUInt(startPtr, endPtr); \
|
||||
auto nextIntOpt = AuParse::ParseUInt16(startPtr, endPtr); \
|
||||
if (!nextIntOpt.has_value()) \
|
||||
{ \
|
||||
return false; \
|
||||
@ -157,7 +157,6 @@ namespace Aurora::IO::IPC
|
||||
|
||||
int stringOffset {};
|
||||
int count {};
|
||||
IPCHeader headerZero;
|
||||
while (in.size() > (stringOffset + 2))
|
||||
{
|
||||
int index = count++;
|
||||
@ -173,11 +172,6 @@ namespace Aurora::IO::IPC
|
||||
this->pid = nextInt;
|
||||
}
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
headerZero = header;
|
||||
}
|
||||
|
||||
auto readIPC = [&](IPCHeader header, IPCValue &value)
|
||||
{
|
||||
value.subtype = (EIPCHandleType)header.bmType;
|
||||
@ -275,13 +269,13 @@ namespace Aurora::IO::IPC
|
||||
|
||||
if (header.bmHasPid)
|
||||
{
|
||||
ret += AuToString(this->pid);
|
||||
ret += AuParse::StringifyUInt16(this->pid, false);
|
||||
ret += ':';
|
||||
}
|
||||
|
||||
if (header.bmHasWord)
|
||||
{
|
||||
ret += AuToString(ipcValue.token.word);
|
||||
ret += AuParse::StringifyUInt16(ipcValue.token.word, false);
|
||||
ret += ':';
|
||||
}
|
||||
|
||||
@ -292,7 +286,7 @@ namespace Aurora::IO::IPC
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += AuToString(ipcValue.token.cookie);
|
||||
ret += AuParse::StringifyUInt16(ipcValue.token.cookie, false);
|
||||
ret += ':';
|
||||
}
|
||||
|
||||
|
@ -262,28 +262,102 @@ namespace Aurora::Parse
|
||||
return true;
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt(const char *begin, const char *&end)
|
||||
template <typename T, typename Iterator>
|
||||
bool ParseInt16(Iterator begin, Iterator &end, T &out)
|
||||
{
|
||||
AuUInt temp{};
|
||||
T res = 0;
|
||||
T sign = 1;
|
||||
out = 0;
|
||||
|
||||
if (!ParseInt<AuUInt>(begin, end, temp))
|
||||
auto itr = begin;
|
||||
|
||||
if constexpr (AuIsSame_v<T, AuSInt>)
|
||||
{
|
||||
return {};
|
||||
if (itr != end)
|
||||
{
|
||||
if (*itr == '-')
|
||||
{
|
||||
itr++;
|
||||
sign = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt(const char *begin, const char *&end)
|
||||
{
|
||||
AuSInt temp{};
|
||||
|
||||
if (!ParseInt<AuSInt>(begin, end, temp))
|
||||
if (itr != end)
|
||||
{
|
||||
return {};
|
||||
if ((*itr == '0') && (itr[1] == 'x')) // TODO (Reece): EVIL... but it's only a byte
|
||||
{
|
||||
itr++;
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
|
||||
return temp;
|
||||
if (begin != end)
|
||||
{
|
||||
auto endChar = *(end - 1);
|
||||
if (endChar == 'h' || endChar == 'H')
|
||||
{
|
||||
end--;
|
||||
}
|
||||
}
|
||||
|
||||
int perf {};
|
||||
for (;
|
||||
(itr != end) &&
|
||||
(*itr != '\0');
|
||||
itr++)
|
||||
{
|
||||
auto c = *itr;
|
||||
|
||||
int delta {};
|
||||
if ((c >= 'A') && (c <= 'F'))
|
||||
{
|
||||
delta = 10 + (c - 'A');
|
||||
}
|
||||
else if ((c >= 'a') && (c <= 'f'))
|
||||
{
|
||||
delta = 10 + (c - 'a');
|
||||
}
|
||||
else if ((c >= '0') && (c <= '9'))
|
||||
{
|
||||
delta = c - '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto old = res;
|
||||
|
||||
res *= T(16);
|
||||
res += T(delta);
|
||||
|
||||
if ((perf++) >= 5)
|
||||
{
|
||||
if constexpr (AuIsSame_v<T, AuUInt>)
|
||||
{
|
||||
if (old > res)
|
||||
{
|
||||
SysPushErrorSyntaxError("Unsigned integer overflow: {}", AuString(begin, end));
|
||||
end = itr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if constexpr (AuIsSame_v<T, AuSInt>)
|
||||
{
|
||||
if (SignBit(old) != SignBit(res))
|
||||
{
|
||||
SysPushErrorSyntaxError("Signed integer overflow: {}", AuString(begin, end));
|
||||
end = itr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end = itr;
|
||||
out = res * sign;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ConsumeTokenPrimitiveish(ParseState &state, ParsableTag type, ParseValue &out)
|
||||
@ -657,4 +731,248 @@ namespace Aurora::Parse
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt(const char *begin, const char *&end)
|
||||
{
|
||||
AuUInt temp{};
|
||||
|
||||
if (!ParseInt<AuUInt>(begin, end, temp))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt(const char *begin, const char *&end)
|
||||
{
|
||||
AuSInt temp{};
|
||||
|
||||
if (!ParseInt<AuSInt>(begin, end, temp))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt16(const char *begin, const char *&end)
|
||||
{
|
||||
AuUInt temp{};
|
||||
|
||||
if (!ParseInt16<AuUInt>(begin, end, temp))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt16(const char *begin, const char *&end)
|
||||
{
|
||||
AuSInt temp{};
|
||||
|
||||
if (!ParseInt16<AuSInt>(begin, end, temp))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
AUKN_SYM AuString StringifySInt16(AuInt64 in, bool bZeroX)
|
||||
{
|
||||
if (bZeroX)
|
||||
{
|
||||
auto str = fmt::format("{0:#X}", in);
|
||||
if (str.size() > 2)
|
||||
{
|
||||
if (str[1] == 'X')
|
||||
{
|
||||
str[1] = 'x';
|
||||
}
|
||||
else if (str.size() > 3 && str[2] == 'X')
|
||||
{
|
||||
str[2] = 'x';
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fmt::format("{:X}", in);
|
||||
}
|
||||
}
|
||||
|
||||
AUKN_SYM AuString StringifyUInt16(AuUInt64 in, bool bZeroX)
|
||||
{
|
||||
if (bZeroX)
|
||||
{
|
||||
auto str = fmt::format("{0:#X}", in);
|
||||
if (str.size() > 2)
|
||||
{
|
||||
if (str[1] == 'X')
|
||||
{
|
||||
str[1] = 'x';
|
||||
}
|
||||
else if (str.size() > 3 && str[2] == 'X')
|
||||
{
|
||||
str[2] = 'x';
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fmt::format("{:X}", in);
|
||||
}
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt16(const char *begin)
|
||||
{
|
||||
const auto end = begin + ::strlen(begin);
|
||||
const char *didntFuckingAskTYVM {end };
|
||||
|
||||
auto res = ParseSInt16(begin, didntFuckingAskTYVM);
|
||||
if (!res.has_value())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (didntFuckingAskTYVM != end)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt16(const AuString &str)
|
||||
{
|
||||
const char *didntFuckingAskTYVM { &str[str.size()] };
|
||||
|
||||
auto res = ParseSInt16(str.c_str(), didntFuckingAskTYVM);
|
||||
if (!res.has_value())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (didntFuckingAskTYVM != &str[str.size()])
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt16(const char *begin)
|
||||
{
|
||||
const auto end = begin + ::strlen(begin);
|
||||
const char *didntFuckingAskTYVM { end };
|
||||
|
||||
auto res = ParseUInt16(begin, didntFuckingAskTYVM);
|
||||
if (!res.has_value())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (didntFuckingAskTYVM != end)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt16(const AuString &str)
|
||||
{
|
||||
const char *didntFuckingAskTYVM { &str[str.size()] };
|
||||
|
||||
auto res = ParseUInt16(str.c_str(), didntFuckingAskTYVM);
|
||||
if (!res.has_value())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (didntFuckingAskTYVM != &str[str.size()])
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt(const AuString &str)
|
||||
{
|
||||
const char *didntFuckingAskTYVM { &str[str.size()] };
|
||||
|
||||
auto res = ParseSInt(str.c_str(), didntFuckingAskTYVM);
|
||||
if (!res.has_value())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (didntFuckingAskTYVM != &str[str.size()])
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuSInt> ParseSInt(const char *begin)
|
||||
{
|
||||
const auto end = begin + ::strlen(begin);
|
||||
const char *didntFuckingAskTYVM { end };
|
||||
|
||||
auto res = ParseSInt(begin, didntFuckingAskTYVM);
|
||||
if (!res.has_value())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (didntFuckingAskTYVM != end)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt(const AuString &str)
|
||||
{
|
||||
const char *didntFuckingAskTYVM { &str[str.size()] };
|
||||
|
||||
auto res = ParseUInt(str.c_str(), didntFuckingAskTYVM);
|
||||
if (!res.has_value())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (didntFuckingAskTYVM != &str[str.size()])
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
AUKN_SYM AuResult<AuUInt> ParseUInt(const char *begin)
|
||||
{
|
||||
const auto end = begin + ::strlen(begin);
|
||||
const char *didntFuckingAskTYVM { end };
|
||||
|
||||
auto res = ParseUInt(begin, didntFuckingAskTYVM);
|
||||
if (!res.has_value())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (didntFuckingAskTYVM != end)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user