14#include <zypp/base/Flags.h>
15#include <zypp/base/String.h>
16#include <zypp/base/NonCopyable.h>
31 enum class Direction : std::uint8_t
42 inline std::uint8_t hexDigit(
char ch_r )
46 case 'F':
case 'f':
return 15;
47 case 'E':
case 'e':
return 14;
48 case 'D':
case 'd':
return 13;
49 case 'C':
case 'c':
return 12;
50 case 'B':
case 'b':
return 11;
51 case 'A':
case 'a':
return 10;
63 throw std::invalid_argument(
str::Str() <<
"Not a hex digit '" << ch_r <<
"'" );
87 void compute(
const std::string & data_r,
const std::string & title_r,
unsigned height_r =
Auto,
unsigned width_r =
Auto )
91 _fp =
str::toUpper( data_r.size() <= 8 ? data_r : data_r.substr( data_r.size()-8 ) );
103 {
_w = 19;
_h = 11; }
110 _board = std::vector<std::uint8_t>(
_w*
_h, 0 );
116 for (
const char * ch = data_r.c_str(); *ch; )
118 std::uint8_t next4 =
bite( ch );
122 static const std::uint8_t stepMask(0x3);
123 move( Direction( next4 & stepMask ) );
124 move( Direction( (next4>>2) & stepMask ) );
125 move( Direction( (next4>>4) & stepMask ) );
126 move( Direction( (next4>>6) ) );
131 std::ostream &
dumpOn( std::ostream &
str,
const std::string & prefix_r, Options options_r )
const
137 return str << prefix_r <<
"++" << endl << prefix_r <<
"++";
140 static const char * colorReset =
"\033[0m";
141 static const char * colorBg =
"\033[48;5;242m";
142 bool useColor = options_r.testFlag(
USE_COLOR );
146 for (
unsigned p = 0; p <
_board.size(); ++p )
148 if ( ( p %
_w ) == 0 )
151 str << ( useColor ? colorReset:
"" ) <<
'|';
152 str << endl << prefix_r <<
'|' << ( useColor ? colorBg :
"" );
156 str << ( useColor ? colorReset:
"" ) <<
'|';
164 static unsigned odd(
unsigned val_r )
165 {
return( val_r ==
Auto ? val_r : val_r|1U ); }
170 static std::uint8_t
bite(
const char *& ch_r )
172 std::uint8_t ret = hexDigit( *ch_r ) << 4;
174 ret |= hexDigit( *(ch_r++) );
180 void move( Direction direction_r )
182 switch ( direction_r )
229 throw std::invalid_argument(
str::Str() <<
"Bad Direction " <<
unsigned(direction_r) );
237 {
return(
_e == 0 ); }
241 {
return(
_e ==
_w-1 ); }
249 {
return(
_e ==
_board.size()-1 ); }
253 {
return(
_e <
_w ); }
261 {
return( (
_e %
_w ) == 0 ); }
265 {
return( (
_e %
_w ) == (
_w-1) ); }
269 const char *
color( std::uint8_t idx_r )
const
271 static const std::vector<const char *> colors = {
296 static unsigned i = 0;
297 if ( ++i == colors.size() )
301 return ( idx_r < colors.size() ? colors[idx_r] : *colors.rbegin() );
307 std::string buffer(
_w+2,
'-' );
308 *buffer.begin() = *buffer.rbegin() =
'+';
310 if ( !title_r.empty() &&
_w >= 2 )
312 std::string::size_type tlen = std::min( title_r.size(), std::string::size_type(
_w-2) );
313 std::string::size_type tpos = (
_w-tlen)/2;
314 buffer[tpos++] =
'[';
315 for ( std::string::size_type p = 0; p < tlen; ++p, ++tpos )
316 buffer[tpos] = title_r[p];
319 return str << buffer;
323 std::ostream &
renderOn( std::ostream &
str,
bool useColor_r,
unsigned pos_r )
const
325 static const std::string sshSet(
" .o+=*BOX@%&#/^" );
326 static const std::string gpgSet(
" .^:li?(fxXZ#MW&8%@" );
327 const std::string & charSet(
_renderSSH ? sshSet : gpgSet );
338 return str << (
_board[pos_r] < charSet.size() ? charSet[
_board[pos_r]] : *charSet.rbegin() );
343 static constexpr const unsigned Auto = unsigned(-1);
361 static shared_ptr<Impl> _nullimpl(
new Impl );
371 : _pimpl(
Impl::nullimpl() )
376 {
_pimpl->compute( data_r, title_r ); }
380 {
_pimpl->compute( data_r, title_r, height_r ); }
384 {
_pimpl->compute( data_r, title_r, height_r, width_r ); }
390 {
return _pimpl->dumpOn(
str, prefix_r, options_r ); }
394 std::ostringstream
str;
401 std::vector<std::string> ret;
DrunkenBishop implementation.
bool atL() const
Whether _e is in the left column.
unsigned _s
start position
std::string _fp
fingerprint to render as bottom title
const char * color(std::uint8_t idx_r) const
ANSI color heatmap.
void compute(const std::string &data_r, const std::string &title_r, unsigned height_r=Auto, unsigned width_r=Auto)
Build up a new board.
static shared_ptr< Impl > nullimpl()
Offer default Impl.
std::ostream & dumpOn(std::ostream &str, const std::string &prefix_r, Options options_r) const
Render board to a stream.
bool atT() const
Whether _e is in the top row.
std::vector< std::uint8_t > _board
the board
std::string _tt
text to render as top title
bool atB() const
Whether _e is in the bottom row.
bool atTL() const
Whether _e is in the top left corner.
bool atBR() const
Whether _e is in the bottom right corner.
void move(Direction direction_r)
Move Bishop from _e into direction_r and update the _board.
std::ostream & renderTitleOn(std::ostream &str, const std::string &title_r) const
Render non empty title strings.
static std::uint8_t bite(const char *&ch_r)
Get next 4 moves (8 bit) from next 2 hex digits (1st digit != '\0' asserted, 0-pad if necessary).
bool atBL() const
Whether _e is in the bottom left corner.
static unsigned odd(unsigned val_r)
Increment even width/height values.
bool atR() const
Whether _e is in the right column.
bool _renderSSH
whether to render the ssh (or gpg) char set
std::ostream & renderOn(std::ostream &str, bool useColor_r, unsigned pos_r) const
Render board numbers to printable chars.
static constexpr const unsigned Auto
Request default width/height values.
Impl()
Default is an empty board.
bool atTR() const
Whether _e is in the top right corner.
RW_pointer< Impl > _pimpl
Implementation class.
std::string asString(Options options_r=Options()) const
Render board as string.
std::vector< std::string > asLines(Options options_r=Options()) const
Render to an array of lines.
DrunkenBishop()
Default ctor: empty board (1x1)
std::ostream & dumpOn(std::ostream &str, Options options_r=Options()) const
Render board to steam.
String related utilities and Regular expression matching.
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
std::string toUpper(const std::string &s)
Return uppercase version of s.
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", const Trim trim_r=NO_TRIM)
Split line_r into words.
Easy-to use interface to the ZYPP dependency resolver.
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...