xo-indentlog: + hex printer
This commit is contained in:
parent
8d81f4fb91
commit
bdb39b8226
1 changed files with 144 additions and 0 deletions
144
include/xo/indentlog/print/hex.hpp
Normal file
144
include/xo/indentlog/print/hex.hpp
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/** @file hex.hpp **/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace xo {
|
||||
/**
|
||||
@class hex indentlog/print/hex.hpp
|
||||
|
||||
@brief Container for a (1-byte) value to be printed in hexadecimal
|
||||
|
||||
Example:
|
||||
@code
|
||||
#include "indentlog/print/hex.hpp"
|
||||
|
||||
std::ostream os = ...;
|
||||
os << hex(16 + 63); // output: 1f
|
||||
os << hex(16 + 63, true); // output: 1f(O)
|
||||
@endcode
|
||||
**/
|
||||
struct hex {
|
||||
/** @brief constructor; create stream-inserter instance */
|
||||
hex(std::uint8_t x, bool w_char = false) : x_{x}, with_char_{w_char} {}
|
||||
|
||||
/**
|
||||
@brief print hexadecimal byte-value on to stream.
|
||||
@param os print on this stream.
|
||||
|
||||
@tparam Stream typename for character stream.
|
||||
**/
|
||||
template <typename Stream>
|
||||
void print(Stream & os) const {
|
||||
std::uint8_t lo = x_ & 0xf;
|
||||
std::uint8_t hi = x_ >> 4;
|
||||
|
||||
char lo_ch = (lo < 10) ? '0' + lo : 'a' + lo - 10;
|
||||
char hi_ch = (hi < 10) ? '0' + hi : 'a' + hi - 10;
|
||||
|
||||
os << hi_ch << lo_ch;
|
||||
|
||||
if (with_char_) {
|
||||
os << "(";
|
||||
if (std::isprint(x_))
|
||||
os << static_cast<char>(x_);
|
||||
else
|
||||
os << "?";
|
||||
os << ")";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/** @brief value to print (in hexadecimal) **/
|
||||
std::uint8_t x_;
|
||||
/** @brief if true, follow with ascii character encoding **/
|
||||
bool with_char_;
|
||||
};
|
||||
|
||||
/**
|
||||
@brief stream inserter for an 8-bit quantity to be printed in hexadecimal.
|
||||
|
||||
@param os print on this stream
|
||||
@param ins package for value to insert
|
||||
**/
|
||||
template<typename Stream>
|
||||
Stream &
|
||||
operator<< (Stream & os, hex const & ins) {
|
||||
ins.print(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
/**
|
||||
@class hex_view indentlog/print/hex.hpp
|
||||
|
||||
@brief Container for a range (unowned) of 1-byte values to be printed in hexadecimal
|
||||
|
||||
Print a range of bytes on an arbitrary character stream.
|
||||
Does not use @c iomanips, so will not alter stream formatting flags if used with @c iostream.
|
||||
|
||||
Example:
|
||||
@code
|
||||
#include "indentlog/print/hex.hpp"
|
||||
|
||||
std::ostream os = ...;
|
||||
os << hex_view("hello", false); // output: [68 65 6c 6c 6f]
|
||||
os << hex_view("hello", true); // output: [68(h) 65(e) 6c(l) 6c(l) 6f(o)]
|
||||
@endcode
|
||||
**/
|
||||
struct hex_view {
|
||||
/** @brief constructor; create stream-inserter instance for a range of bytes **/
|
||||
hex_view(std::uint8_t const * lo, std::uint8_t const * hi, bool as_text)
|
||||
: lo_{lo}, hi_{hi}, as_text_{as_text} {}
|
||||
/** @brief constructor; create stream-inserter instance for a range of chars **/
|
||||
hex_view(char const * lo, char const * hi, bool as_text)
|
||||
: lo_{reinterpret_cast<std::uint8_t const *>(lo)},
|
||||
hi_{reinterpret_cast<std::uint8_t const *>(hi)},
|
||||
as_text_{as_text} {}
|
||||
|
||||
/**
|
||||
@brief print hexadecimal byte range on stream.
|
||||
@param os print on this stream
|
||||
|
||||
@tparam Stream typename for character stream.
|
||||
**/
|
||||
template <typename Stream>
|
||||
void print(Stream & os) const {
|
||||
os << "[";
|
||||
std::size_t i = 0;
|
||||
for (std::uint8_t const * p = lo_; p < hi_; ++p) {
|
||||
if (i > 0)
|
||||
os << " ";
|
||||
os << hex(*p, as_text_);
|
||||
++i;
|
||||
}
|
||||
os << "]";
|
||||
}
|
||||
|
||||
private:
|
||||
/** @brief print byte range starting at this address **/
|
||||
std::uint8_t const * lo_;
|
||||
/** @brief print byte range up to (but not including) this address **/
|
||||
std::uint8_t const * hi_;
|
||||
/** @brief if true also print ascii encoding (for printable codes),
|
||||
* \c ? otherwise. @see hex::with_char
|
||||
**/
|
||||
bool as_text_;
|
||||
};
|
||||
|
||||
/**
|
||||
@brief stream inserter for a range of 1-byte values to be printed in hexadecimal
|
||||
|
||||
@param os print on this stream.
|
||||
@param ins (container for) values to insert.
|
||||
**/
|
||||
template <typename Stream>
|
||||
Stream &
|
||||
operator<< (Stream & os, hex_view const & ins) {
|
||||
ins.print(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end hex.hpp */
|
||||
Loading…
Add table
Add a link
Reference in a new issue