refactor: Move unhex lookup table out of function (#83)

This commit is contained in:
Sergey Kuznetsov
2026-04-21 15:51:53 +01:00
committed by Bart
parent 024c9c57f7
commit 406b5346f8

View File

@@ -27,9 +27,11 @@
#include <boost/utility/string_view.hpp>
#include <array>
#include <concepts>
#include <cstdint>
#include <optional>
#include <string>
#include <type_traits>
namespace ripple {
@@ -46,28 +48,40 @@ namespace ripple {
std::string
sqlBlobLiteral(Blob const& blob);
namespace impl {
template <typename T>
concept SomeChar = std::same_as<std::remove_cvref_t<T>, int8_t> ||
std::same_as<std::remove_cvref_t<T>, char> ||
std::same_as<std::remove_cvref_t<T>, uint8_t>;
inline constexpr std::array<std::optional<int>, 256> DIGIT_LOOKUP_TABLE = []() {
std::array<std::optional<int>, 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<int>
hexCharToInt(SomeChar auto hexChar)
{
return DIGIT_LOOKUP_TABLE[static_cast<uint8_t>(hexChar)];
}
} // namespace impl
template <class Iterator>
std::optional<Blob>
strUnHex(std::size_t strSize, Iterator begin, Iterator end)
{
static constexpr std::array<int, 256> const unxtab = []() {
std::array<int, 256> 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<unsigned char>(*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<unsigned char>((cHigh << 4) | cLow));
out.push_back(static_cast<unsigned char>((*cHigh << 4) | *cLow));
}
return {std::move(out)};