Skip to content

Commit

Permalink
BWF: Add UnHex (hexadecimal encoding to raw bytes).
Browse files Browse the repository at this point in the history
  • Loading branch information
SolidWallOfCode committed Aug 5, 2023
1 parent 1229630 commit 6ad7075
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 2 deletions.
19 changes: 19 additions & 0 deletions code/include/swoc/bwf_ex.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,23 @@ SubText<ARG>
Optional(TextView fmt, ARG &&arg) {
return detail::Optional(meta::CaseArg, fmt, std::forward<ARG>(arg));
}

/** Convert from ASCII hexadecimal to raw bytes.
*
* E.g. if the source span contains "4576696c20446176652052756c7a" then "Evil Dave Rulz" is the output.
* For format specifier support, on lhe max width is used. Any @c MemSpan compatible class can be used
* as the target, including @c std::string and @c std::string_view.
*
* @code
* void f(std::string const& str) {
* w.print("{}", bwf::UnHex(str));
* // ...
* @endcode
*/
struct UnHex {
UnHex(MemSpan<void const> const& span) : _span(span) {}
MemSpan<void const> _span; ///< Source span.
};
} // namespace bwf

/** Repeatedly output a pattern.
Expand Down Expand Up @@ -237,6 +254,8 @@ BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, bwf::Errno const
*/
BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, bwf::Date const &date);

BufferWriter &bwformat(BufferWriter &w, bwf::Spec const& spec, bwf::UnHex const& obj);

/** Output a nested formatted string.
*
* @tparam Args Argument pack for @a subtext.
Expand Down
15 changes: 13 additions & 2 deletions code/src/bw_format.cc
Original file line number Diff line number Diff line change
Expand Up @@ -960,8 +960,8 @@ bwformat(BufferWriter &w, bwf::Spec const &spec, bwf::Pattern const &pattern) {
return w;
}

swoc::BufferWriter &
bwformat(swoc::BufferWriter &w, swoc::bwf::Spec const &spec, std::error_code const &ec) {
BufferWriter &
bwformat(BufferWriter &w, bwf::Spec const &spec, std::error_code const &ec) {
static const auto G_CAT = &std::generic_category();
static const auto S_CAT = &std::system_category();

Expand All @@ -984,6 +984,17 @@ bwformat(swoc::BufferWriter &w, swoc::bwf::Spec const &spec, std::error_code con
return w;
}

BufferWriter&
bwformat(BufferWriter &w, bwf::Spec const& spec, bwf::UnHex const& obj) {
auto span { obj._span };
size_t limit = spec._max;
while (span.size() >= 2 && limit--) {
auto b = svto_radix<16>(span.clip_prefix(2).rebind<char const>());
w.write(b);
}
return w;
}

}} // namespace swoc::SWOC_VERSION_NS

namespace std {
Expand Down
12 changes: 12 additions & 0 deletions unit_tests/test_bw_format.cc
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,18 @@ TEST_CASE("BWFormat numerics", "[bwprint][bwformat]") {
bw.clear().print("|{:>16.2x}|", sv);
REQUIRE(bw.view() == "| 6162|");

swoc::MemSpan<void const> cvs{"Evil Dave Rulz"_tv};
TextView const edr_in_hex{"4576696c20446176652052756c7a"};
bw.clear().format(swoc::bwf::Spec(":x"), cvs);
REQUIRE(bw.view() == edr_in_hex);
bw.clear().format(swoc::bwf::Spec::DEFAULT, swoc::bwf::UnHex(edr_in_hex));
REQUIRE(bw.view() == "Evil Dave Rulz");
bw.clear().format(swoc::bwf::Spec::DEFAULT, swoc::bwf::UnHex("112233445566778800"));
REQUIRE(memcmp(bw.view(), "\x11\x22\x33\x44\x55\x66\x77\x88\x00"_tv) == 0);
// Check if max width in the spec works - should leave bytes from the previous.
bw.clear().format(swoc::bwf::Spec{":,2"}, swoc::bwf::UnHex("deadbeef"));
REQUIRE(memcmp(TextView(bw.data(), 4), "\xde\xad\x33\x44"_tv) == 0);

// Substrings by argument adjustment.
bw.clear().print("|{:<0,7x}|", sv.prefix(4));
REQUIRE(bw.view() == "|6162633|");
Expand Down

0 comments on commit 6ad7075

Please sign in to comment.