diff --git a/contrib/epee/include/hex.h b/contrib/epee/include/hex.h index d9eb93d51..d27c127c1 100644 --- a/contrib/epee/include/hex.h +++ b/contrib/epee/include/hex.h @@ -67,6 +67,9 @@ namespace epee return out; } + //! Write `src` as hex to `out`. `out` must be exactly 2x in size. + static bool buffer(span out, const span src) noexcept; + //! Append `src` as hex to `out`. static void buffer(std::ostream& out, const span src); diff --git a/contrib/epee/src/hex.cpp b/contrib/epee/src/hex.cpp index edc7d46f4..625f37c2f 100644 --- a/contrib/epee/src/hex.cpp +++ b/contrib/epee/src/hex.cpp @@ -69,6 +69,14 @@ namespace epee std::string to_hex::string(const span src) { return convert(src); } epee::wipeable_string to_hex::wipeable_string(const span src) { return convert(src); } + bool to_hex::buffer(span out, const span src) noexcept + { + if (out.size() % 2 != 0 || out.size() / 2 != src.size()) + return false; + to_hex::buffer_unchecked(out.data(), src); + return true; + } + void to_hex::buffer(std::ostream& out, const span src) { write_hex(std::ostreambuf_iterator{out}, src); diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp index 185cb73b1..c776fbcc9 100644 --- a/tests/unit_tests/epee_utils.cpp +++ b/tests/unit_tests/epee_utils.cpp @@ -1241,6 +1241,22 @@ TEST(ToHex, ArrayFromPod) ); } +TEST(ToHex, Buffer) +{ + static constexpr const std::uint8_t source[] = {0xFF, 0x00, 0xAB, 0x01}; + const std::vector expected{'f', 'f', '0', '0', 'a', 'b', '0', '1'}; + + std::vector buffer; + buffer.resize(expected.size()); + EXPECT_TRUE(epee::to_hex::buffer(epee::to_mut_span(buffer), source)); + EXPECT_EQ(expected, buffer); + + buffer.pop_back(); + EXPECT_FALSE(epee::to_hex::buffer(epee::to_mut_span(buffer), source)); + buffer.pop_back(); + EXPECT_FALSE(epee::to_hex::buffer(epee::to_mut_span(buffer), source)); +} + TEST(ToHex, Ostream) { std::stringstream out;