From 406b5346f85e3d2732ad28b622b6b5d549afffce Mon Sep 17 00:00:00 2001 From: Sergey Kuznetsov Date: Tue, 21 Apr 2026 15:51:53 +0100 Subject: [PATCH] refactor: Move unhex lookup table out of function (#83) --- include/xrpl/basics/StringUtilities.h | 66 ++++++++++++++++----------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/include/xrpl/basics/StringUtilities.h b/include/xrpl/basics/StringUtilities.h index 5f905638cb..12bf7b2f5f 100644 --- a/include/xrpl/basics/StringUtilities.h +++ b/include/xrpl/basics/StringUtilities.h @@ -27,9 +27,11 @@ #include #include +#include #include #include #include +#include namespace ripple { @@ -46,28 +48,40 @@ namespace ripple { std::string sqlBlobLiteral(Blob const& blob); +namespace impl { + +template +concept SomeChar = std::same_as, int8_t> || + std::same_as, char> || + std::same_as, uint8_t>; + +inline constexpr std::array, 256> DIGIT_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 DIGIT_LOOKUP_TABLE[static_cast(hexChar)]; +} + +} // namespace impl + template std::optional strUnHex(std::size_t strSize, Iterator begin, Iterator end) { - static constexpr std::array const unxtab = []() { - 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); @@ -76,27 +90,27 @@ strUnHex(std::size_t strSize, Iterator begin, Iterator end) if (strSize & 1) { - int c = unxtab[*iter++]; + auto const c = impl::hexCharToInt(*iter++); - if (c < 0) + if (!c.has_value()) return {}; - out.push_back(c); + out.push_back(static_cast(*c)); } while (iter != end) { - int cHigh = unxtab[*iter++]; + auto const cHigh = impl::hexCharToInt(*iter++); - if (cHigh < 0) + if (!cHigh.has_value()) return {}; - int cLow = unxtab[*iter++]; + auto const cLow = impl::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)};