From 90b9ff7c5fa804ad513cab067456f7f8db030af7 Mon Sep 17 00:00:00 2001 From: Sergey Kuznetsov Date: Wed, 13 May 2026 18:48:43 +0100 Subject: [PATCH] refactor: Move unhex lookup table out of function (#7104) --- include/xrpl/basics/StringUtilities.h | 66 ++++++++++++++++----------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/include/xrpl/basics/StringUtilities.h b/include/xrpl/basics/StringUtilities.h index 13c4f04e0c..f4bdd61f6a 100644 --- a/include/xrpl/basics/StringUtilities.h +++ b/include/xrpl/basics/StringUtilities.h @@ -7,9 +7,11 @@ #include #include +#include #include #include #include +#include namespace xrpl { @@ -26,28 +28,39 @@ namespace xrpl { std::string sqlBlobLiteral(Blob const& blob); +namespace detail { + +template +concept SomeChar = std::same_as, int8_t> || + std::same_as, char> || std::same_as, uint8_t>; + +inline constexpr std::array, 256> const kDIGIT_LOOKUP_TABLE = []() { + std::array, 256> t{}; + + for (int i = 0; i < 10; ++i) + t['0' + i] = i; + + for (int i = 0; i < 6; ++i) + { + t['A' + i] = 10 + i; + t['a' + i] = 10 + i; + } + + return t; +}(); + +inline std::optional +hexCharToInt(SomeChar auto hexChar) +{ + return kDIGIT_LOOKUP_TABLE[static_cast(hexChar)]; +} + +} // namespace detail + template std::optional strUnHex(std::size_t strSize, Iterator begin, Iterator end) { - static constexpr std::array const kDIGIT_LOOKUP_TABLE = []() { - std::array t{}; - - for (auto& x : t) - x = -1; - - for (int i = 0; i < 10; ++i) - t['0' + i] = i; - - for (int i = 0; i < 6; ++i) - { - t['A' + i] = 10 + i; - t['a' + i] = 10 + i; - } - - return t; - }(); - Blob out; out.reserve((strSize + 1) / 2); @@ -56,27 +69,26 @@ strUnHex(std::size_t strSize, Iterator begin, Iterator end) if (strSize & 1) { - int c = kDIGIT_LOOKUP_TABLE[*iter++]; - - if (c < 0) + auto const c = detail::hexCharToInt(*iter++); + if (!c.has_value()) return {}; - out.push_back(c); + out.push_back(static_cast(*c)); } while (iter != end) { - int const cHigh = kDIGIT_LOOKUP_TABLE[*iter++]; + auto const cHigh = detail::hexCharToInt(*iter++); - if (cHigh < 0) + if (!cHigh.has_value()) return {}; - int const cLow = kDIGIT_LOOKUP_TABLE[*iter++]; + auto const cLow = detail::hexCharToInt(*iter++); - if (cLow < 0) + if (!cLow.has_value()) return {}; - out.push_back(static_cast((cHigh << 4) | cLow)); + out.push_back(static_cast((*cHigh << 4) | *cLow)); } return {std::move(out)};