diff options
| author | Dan Engelbrecht <[email protected]> | 2022-03-23 23:45:06 +0100 |
|---|---|---|
| committer | Dan Engelbrecht <[email protected]> | 2022-03-31 11:29:27 +0200 |
| commit | 7255a5652f5e4788f13a1d6bbcbd53c7f93f90d8 (patch) | |
| tree | aeabdf91c72dbd61f8b55096cc1e42e1337c2cc6 | |
| parent | Rename FormatHex to ToHex (diff) | |
| download | zen-7255a5652f5e4788f13a1d6bbcbd53c7f93f90d8.tar.xz zen-7255a5652f5e4788f13a1d6bbcbd53c7f93f90d8.zip | |
clean up number -> hex -> number code
| -rw-r--r-- | zencore/include/zencore/string.h | 98 | ||||
| -rw-r--r-- | zencore/string.cpp | 27 | ||||
| -rw-r--r-- | zenstore/compactcas.cpp | 44 |
3 files changed, 97 insertions, 72 deletions
diff --git a/zencore/include/zencore/string.h b/zencore/include/zencore/string.h index 013f2f568..da5a50064 100644 --- a/zencore/include/zencore/string.h +++ b/zencore/include/zencore/string.h @@ -488,6 +488,29 @@ std::string WideToUtf8(const wchar_t* wstr); void WideToUtf8(const std::wstring_view& wstr, StringBuilderBase& out); std::string WideToUtf8(const std::wstring_view Wstr); +inline uint8_t +Char2Nibble(char c) +{ + uint8_t c8 = uint8_t(c - '0'); + + if (c8 < 10) + return c8; + + c8 -= 'A' - '0' - 10; + + if (c8 < 16) + return c8; + + c8 -= 'a' - 'A'; + + if (c8 < 16) + return c8; + + return uint8_t(0xff); +}; + +static constexpr const char HexChars[] = "0123456789abcdef"; + /// <summary> /// Parse hex string into a byte buffer /// </summary> @@ -501,38 +524,56 @@ ParseHexBytes(const char* InputString, size_t CharacterCount, uint8_t* OutPtr) { ZEN_ASSERT((CharacterCount & 1) == 0); - auto char2nibble = [](char c) { - uint8_t c8 = uint8_t(c - '0'); + uint8_t allBits = 0; - if (c8 < 10) - return c8; + while (CharacterCount) + { + uint8_t n0 = Char2Nibble(InputString[0]); + uint8_t n1 = Char2Nibble(InputString[1]); - c8 -= 'A' - '0' - 10; + allBits |= n0 | n1; - if (c8 < 16) - return c8; + *OutPtr = (n0 << 4) | n1; - c8 -= 'a' - 'A'; + OutPtr += 1; + InputString += 2; + CharacterCount -= 2; + } - if (c8 < 16) - return c8; + return (allBits & 0x80) == 0; +} - return uint8_t(0xff); - }; +inline void +ToHexBytes(const uint8_t* InputData, size_t ByteCount, char* OutString) +{ + while (ByteCount--) + { + uint8_t byte = *InputData++; + + *OutString++ = HexChars[byte >> 4]; + *OutString++ = HexChars[byte & 15]; + } +} + +inline bool +ParseHexNumber(const char* InputString, size_t CharacterCount, uint8_t* OutPtr) +{ + ZEN_ASSERT((CharacterCount & 1) == 0); uint8_t allBits = 0; + InputString += CharacterCount; while (CharacterCount) { - uint8_t n0 = char2nibble(InputString[0]); - uint8_t n1 = char2nibble(InputString[1]); + InputString -= 2; + uint8_t n0 = Char2Nibble(InputString[0]); + uint8_t n1 = Char2Nibble(InputString[1]); allBits |= n0 | n1; *OutPtr = (n0 << 4) | n1; OutPtr += 1; - InputString += 2; CharacterCount -= 2; } @@ -540,21 +581,32 @@ ParseHexBytes(const char* InputString, size_t CharacterCount, uint8_t* OutPtr) } inline void -ToHexBytes(const uint8_t* InputData, size_t ByteCount, char* OutString) +ToHexNumber(const uint8_t* InputData, size_t ByteCount, char* OutString) { - const char hexchars[] = "0123456789abcdef"; - + InputData += ByteCount; while (ByteCount--) { - uint8_t byte = *InputData++; + uint8_t byte = *(--InputData); - *OutString++ = hexchars[byte >> 4]; - *OutString++ = hexchars[byte & 15]; + *OutString++ = HexChars[byte >> 4]; + *OutString++ = HexChars[byte & 15]; } } -ZENCORE_API void ToHex(uint32_t Value, char OutBlockHexString[9]); -ZENCORE_API bool ParseHex(const std::string HexString, uint32_t& OutValue); +template<typename T> +void +ToHexNumber(T Value, char* OutString) +{ + ToHexNumber((const uint8_t*)&Value, sizeof(T), OutString); + OutString[sizeof(T) * 2] = 0; +} + +template<typename T> +bool +ParseHexNumber(const std::string HexString, T& OutValue) +{ + return ParseHexNumber(HexString.c_str(), sizeof(T) * 2, (uint8_t*)&OutValue); +} ////////////////////////////////////////////////////////////////////////// // Format numbers for humans diff --git a/zencore/string.cpp b/zencore/string.cpp index 933d210e7..ad6ee78fc 100644 --- a/zencore/string.cpp +++ b/zencore/string.cpp @@ -335,33 +335,6 @@ NiceNumGeneral(uint64_t Num, std::span<char> Buffer, NicenumFormat Format) } } -bool -ParseHex(const std::string HexString, uint32_t& OutValue) -{ - if (HexString.length() != 8) - { - return false; - } - OutValue = strtoul(HexString.data(), 0, 16); - return true; -} - -static const char HexLUT[] = "0123456789abcdef"; - -void -ToHex(uint32_t Value, char OutBlockHexString[9]) -{ - OutBlockHexString[0] = HexLUT[(Value >> 28) & 0xf]; - OutBlockHexString[1] = HexLUT[(Value >> 24) & 0xf]; - OutBlockHexString[2] = HexLUT[(Value >> 20) & 0xf]; - OutBlockHexString[3] = HexLUT[(Value >> 16) & 0xf]; - OutBlockHexString[4] = HexLUT[(Value >> 12) & 0xf]; - OutBlockHexString[5] = HexLUT[(Value >> 8) & 0xf]; - OutBlockHexString[6] = HexLUT[(Value >> 4) & 0xf]; - OutBlockHexString[7] = HexLUT[(Value >> 0) & 0xf]; - OutBlockHexString[8] = 0; -} - size_t NiceNumToBuffer(uint64_t Num, std::span<char> Buffer) { diff --git a/zenstore/compactcas.cpp b/zenstore/compactcas.cpp index 65b9bc969..51c515e8d 100644 --- a/zenstore/compactcas.cpp +++ b/zenstore/compactcas.cpp @@ -27,15 +27,15 @@ namespace zen { struct CasDiskIndexHeader { - static constexpr uint32_t ExpectedMagic = 0x75696478; // 'uidx'; - static constexpr uint32_t CurrentVersion = 1; - uint32_t Magic = ExpectedMagic; - uint32_t Version = CurrentVersion; - uint32_t PayloadAlignement; - uint32_t Reserved0 = 0; - uint64_t EntryCount; - uint32_t Reserved1 = 0; - uint32_t Reserved2 = 0; + static constexpr uint32_t ExpectedMagic = 0x75696478; // 'uidx'; + static constexpr uint32_t CurrentVersion = 1; + uint32_t Magic = ExpectedMagic; + uint32_t Version = CurrentVersion; + uint32_t PayloadAlignement = 0; + uint32_t Reserved0 = 0; + uint64_t EntryCount = 0; + uint32_t Reserved1 = 0; + uint32_t Reserved2 = 0; }; static_assert(sizeof(CasDiskIndexHeader) == 32); @@ -46,7 +46,7 @@ namespace { ExtendablePathBuilder<256> Path; char BlockHexString[9]; - ToHex(BlockIndex, BlockHexString); + ToHexNumber(BlockIndex, BlockHexString); Path.Append(BlocksBasePath); Path.AppendSeparator(); @@ -1119,7 +1119,7 @@ CasContainerStrategy::OpenContainer(bool IsNewStore) } std::string FileName = Path.stem().string(); uint32_t BlockIndex; - bool OK = ParseHex(FileName, BlockIndex); + bool OK = ParseHexNumber(FileName, BlockIndex); if (!OK) { continue; @@ -1219,36 +1219,36 @@ TEST_CASE("compactcas.hex") { uint32_t Value; std::string HexString; - CHECK(!ParseHex("", Value)); + CHECK(!ParseHexNumber("", Value)); char Hex[9]; - ToHex(0, Hex); + ToHexNumber(0, Hex); HexString = std::string(Hex); - CHECK(ParseHex(HexString, Value)); + CHECK(ParseHexNumber(HexString, Value)); CHECK(Value == 0); - ToHex(std::numeric_limits<std::uint32_t>::max(), Hex); + ToHexNumber(std::numeric_limits<std::uint32_t>::max(), Hex); HexString = std::string(Hex); CHECK(HexString == "ffffffff"); - CHECK(ParseHex(HexString, Value)); + CHECK(ParseHexNumber(HexString, Value)); CHECK(Value == std::numeric_limits<std::uint32_t>::max()); - ToHex(0xadf14711, Hex); + ToHexNumber(0xadf14711, Hex); HexString = std::string(Hex); CHECK(HexString == "adf14711"); - CHECK(ParseHex(HexString, Value)); + CHECK(ParseHexNumber(HexString, Value)); CHECK(Value == 0xadf14711); - ToHex(0x80000000, Hex); + ToHexNumber(0x80000000, Hex); HexString = std::string(Hex); CHECK(HexString == "80000000"); - CHECK(ParseHex(HexString, Value)); + CHECK(ParseHexNumber(HexString, Value)); CHECK(Value == 0x80000000); - ToHex(0x718293a4, Hex); + ToHexNumber(0x718293a4, Hex); HexString = std::string(Hex); CHECK(HexString == "718293a4"); - CHECK(ParseHex(HexString, Value)); + CHECK(ParseHexNumber(HexString, Value)); CHECK(Value == 0x718293a4); } |