30 enum class Direction : std::uint8_t
41 inline std::uint8_t hexDigit(
char ch_r )
45 case 'F':
case 'f':
return 15;
46 case 'E':
case 'e':
return 14;
47 case 'D':
case 'd':
return 13;
48 case 'C':
case 'c':
return 12;
49 case 'B':
case 'b':
return 11;
50 case 'A':
case 'a':
return 10;
62 throw std::invalid_argument(
str::Str() <<
"Not a hex digit '" << ch_r <<
"'" );
86 void compute(
const std::string & data_r,
const std::string & title_r,
unsigned height_r =
Auto,
unsigned width_r =
Auto )
90 _fp =
str::toUpper( data_r.size() <= 8 ? data_r : data_r.substr( data_r.size()-8 ) );
102 {
_w = 19;
_h = 11; }
109 _board = std::vector<std::uint8_t>(
_w*
_h, 0 );
115 for (
const char * ch = data_r.c_str(); *ch; )
117 std::uint8_t next4 =
bite( ch );
121 static const std::uint8_t stepMask(0x3);
122 move( Direction( next4 & stepMask ) );
123 move( Direction( (next4>>2) & stepMask ) );
124 move( Direction( (next4>>4) & stepMask ) );
125 move( Direction( (next4>>6) ) );
130 std::ostream &
dumpOn( std::ostream & str,
const std::string & prefix_r, Options options_r )
const
136 return str << prefix_r <<
"++" << endl << prefix_r <<
"++";
139 static const char * colorReset =
"\033[0m";
140 static const char * colorBg =
"\033[48;5;242m";
141 bool useColor = options_r.testFlag(
USE_COLOR );
145 for (
unsigned p = 0; p <
_board.size(); ++p )
147 if ( ( p %
_w ) == 0 )
150 str << ( useColor ? colorReset:
"" ) <<
'|';
151 str << endl << prefix_r <<
'|' << ( useColor ? colorBg :
"" );
155 str << ( useColor ? colorReset:
"" ) <<
'|';
163 static unsigned odd(
unsigned val_r )
164 {
return( val_r ==
Auto ? val_r : val_r|1U ); }
169 static std::uint8_t
bite(
const char *& ch_r )
171 std::uint8_t ret = hexDigit( *ch_r ) << 4;
173 ret |= hexDigit( *(ch_r++) );
179 void move( Direction direction_r )
181 switch ( direction_r )
228 throw std::invalid_argument(
str::Str() <<
"Bad Direction " <<
unsigned(direction_r) );
236 {
return(
_e == 0 ); }
240 {
return(
_e ==
_w-1 ); }
248 {
return(
_e ==
_board.size()-1 ); }
252 {
return(
_e <
_w ); }
260 {
return( (
_e %
_w ) == 0 ); }
264 {
return( (
_e %
_w ) == (_w-1) ); }
268 const char *
color( std::uint8_t idx_r )
const
270 static const std::vector<const char *> colors = {
295 static unsigned i = 0;
296 if ( ++i == colors.size() )
300 return ( idx_r < colors.size() ? colors[idx_r] : *colors.rbegin() );
304 std::ostream &
renderTitleOn( std::ostream & str,
const std::string & title_r )
const
306 std::string buffer(
_w+2,
'-' );
307 *buffer.begin() = *buffer.rbegin() =
'+';
309 if ( !title_r.empty() &&
_w >= 2 )
313 buffer[tpos++] =
'[';
315 buffer[tpos] = title_r[p];
318 return str << buffer;
322 std::ostream &
renderOn( std::ostream & str,
bool useColor_r,
unsigned pos_r )
const
324 static const std::string sshSet(
" .o+=*BOX@%&#/^" );
325 static const std::string gpgSet(
" .^:li?(fxXZ#MW&8%@" );
326 const std::string & charSet(
_renderSSH ? sshSet : gpgSet );
337 return str << (
_board[pos_r] < charSet.size() ? charSet[
_board[pos_r]] : *charSet.rbegin() );
342 static constexpr
const unsigned Auto = unsigned(-1);
360 static shared_ptr<Impl> _nullimpl(
new Impl );
370 : _pimpl(
Impl::nullimpl() )
393 std::ostringstream str;
394 dumpOn( str, prefix_r, options_r );
400 std::vector<std::string> ret;