Merge pull request #2373 from nghttp2/rewrite-format_hex

Rewrite format_hex
This commit is contained in:
Tatsuhiro Tsujikawa
2025-05-13 21:09:47 +09:00
committed by GitHub
6 changed files with 49 additions and 63 deletions

View File

@@ -605,7 +605,7 @@ void exec_binary() {
s += util::utos(wp->quic_ipc_fd);
for (auto &wid : wp->worker_ids) {
s += ',';
s += util::format_hex(std::span{&wid, 1});
s += util::format_hex(as_uint8_span(std::span{&wid, 1}));
}
quic_lwps.emplace_back(s);

View File

@@ -190,7 +190,7 @@ StringRef create_affinity_cookie(BlockAllocator &balloc, const StringRef &name,
auto p = std::ranges::copy(name, std::ranges::begin(iov)).out;
*p++ = '=';
affinity_cookie = htonl(affinity_cookie);
p = util::format_hex(p, std::span{&affinity_cookie, 1});
p = util::format_hex(as_uint8_span(std::span{&affinity_cookie, 1}), p);
if (!path.empty()) {
p = std::ranges::copy(PATH_PREFIX, p).out;
p = std::ranges::copy(path, p).out;

View File

@@ -51,7 +51,7 @@ LogConfig::LogConfig()
auto tid = std::this_thread::get_id();
auto tid_hash =
util::hash32(StringRef{reinterpret_cast<char *>(&tid), sizeof(tid)});
thread_id = util::format_hex(std::span{&tid_hash, 1});
thread_id = util::format_hex(as_uint8_span(std::span{&tid_hash, 1}));
}
#ifndef NOTHREADS

View File

@@ -502,24 +502,6 @@ char upcase(char c) {
}
}
std::string format_hex(std::span<const uint8_t> s) {
std::string res;
res.resize(s.size() * 2);
format_hex(std::begin(res), s);
return res;
}
StringRef format_hex(BlockAllocator &balloc, std::span<const uint8_t> s) {
auto iov = make_byte_ref(balloc, s.size() * 2 + 1);
auto p = format_hex(std::begin(iov), s);
*p = '\0';
return as_string_ref(std::begin(iov), p);
}
void to_token68(std::string &base64str) {
std::transform(std::begin(base64str), std::end(base64str),
std::begin(base64str), [](char c) {

View File

@@ -192,34 +192,56 @@ size_t quote_stringlen(const StringRef &target);
static constexpr char LOWER_XDIGITS[] = "0123456789abcdef";
template <std::weakly_incrementable OutputIt>
OutputIt format_hex(OutputIt it, std::span<const uint8_t> s) {
for (auto c : s) {
*it++ = LOWER_XDIGITS[c >> 4];
*it++ = LOWER_XDIGITS[c & 0xf];
// Converts a range [|first|, |last|) in hex format, and stores the
// result in another range, beginning at |result|. It returns an
// output iterator to the element past the last element stored.
template <std::input_iterator I, std::weakly_incrementable O>
requires(sizeof(std::iter_value_t<I>) == sizeof(uint8_t))
constexpr O format_hex(I first, I last, O result) noexcept {
for (; first != last; ++first) {
uint8_t c = *first;
*result++ = LOWER_XDIGITS[c >> 4];
*result++ = LOWER_XDIGITS[c & 0xf];
}
return it;
return result;
}
template <typename T, size_t N = std::dynamic_extent,
std::weakly_incrementable OutputIt>
OutputIt format_hex(OutputIt it, std::span<T, N> s) {
return format_hex(it, std::span<const uint8_t>{as_uint8_span(s)});
// Converts |R| in hex format, and stores the result in another range,
// beginning at |result|. It returns an output iterator to the
// element past the last element stored.
template <std::ranges::input_range R, std::weakly_incrementable O>
requires(sizeof(std::ranges::range_value_t<R>) == sizeof(uint8_t))
constexpr O format_hex(R &&r, O result) noexcept {
return format_hex(std::ranges::begin(r), std::ranges::end(r),
std::move(result));
}
std::string format_hex(std::span<const uint8_t> s);
// Converts |R| in hex format, and stores the result in a buffer
// allocated by |balloc|. It returns StringRef that is backed by the
// allocated buffer. The returned string is NULL terminated.
template <std::ranges::input_range R>
requires(sizeof(std::ranges::range_value_t<R>) == sizeof(uint8_t))
StringRef format_hex(BlockAllocator &balloc, R &&r) {
auto iov = make_byte_ref(balloc, std::ranges::distance(r) * 2 + 1);
auto p = format_hex(std::forward<R>(r), std::ranges::begin(iov));
template <typename T, size_t N = std::dynamic_extent>
std::string format_hex(std::span<T, N> s) {
return format_hex(std::span<const uint8_t>{as_uint8_span(s)});
*p = '\0';
return as_string_ref(std::ranges::begin(iov), p);
}
StringRef format_hex(BlockAllocator &balloc, std::span<const uint8_t> s);
// Converts |R| in hex format, and returns the result.
template <std::ranges::input_range R>
requires(sizeof(std::ranges::range_value_t<R>) == sizeof(uint8_t))
std::string format_hex(R &&r) {
std::string res;
template <typename T, size_t N = std::dynamic_extent>
StringRef format_hex(BlockAllocator &balloc, std::span<T, N> s) {
return format_hex(balloc, std::span<const uint8_t>{as_uint8_span(s)});
res.resize(std::ranges::distance(r) * 2);
format_hex(std::forward<R>(r), std::ranges::begin(res));
return res;
}
// decode_hex decodes hex string |s|, returns the decoded byte string.

View File

@@ -619,34 +619,16 @@ void test_util_random_alpha_digit(void) {
void test_util_format_hex(void) {
BlockAllocator balloc(4096, 4096);
assert_stdsv_equal("0ff0"sv,
util::format_hex(balloc, std::span{"\x0f\xf0"_sr}));
assert_stdsv_equal(""sv,
util::format_hex(balloc, std::span<const uint8_t>{}));
union T {
uint16_t x;
uint8_t y[2];
};
auto t = T{.y = {0xbe, 0xef}};
assert_stdstring_equal("beef", util::format_hex(std::span{&t.x, 1}));
assert_stdsv_equal("0ff0"sv, util::format_hex(balloc, "\x0f\xf0"_sr));
assert_stdsv_equal(""sv, util::format_hex(balloc, ""sv));
std::string o;
o.resize(4);
assert_true(std::end(o) ==
util::format_hex(std::begin(o), std::span{&t.x, 1}));
assert_stdstring_equal("beef", o);
struct S {
uint8_t x[8];
};
auto s = S{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf8}};
assert_stdstring_equal("01020304050607f8", util::format_hex(s.x));
assert_true(std::ranges::end(o) ==
util::format_hex("\xbe\xef"sv, std::ranges::begin(o)));
assert_stdstring_equal("beef"s, o);
assert_stdstring_equal("beef"s, util::format_hex("\xbe\xef"sv));
}
void test_util_is_hex_string(void) {