-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhexdump.hpp
More file actions
116 lines (99 loc) · 3.6 KB
/
Copy pathhexdump.hpp
File metadata and controls
116 lines (99 loc) · 3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* File: /lib/debug/hexdump.hpp
*
* This file is a part of cpplib project which is distributed under MIT License.
* See file LICENSE for full license details.
*
* Copyright (c) 2020-present Nikita Zuev (V.Slavski!) <[email protected]>
*/
#ifndef CPPLIB__lib__debug__hexdump__hpp
#define CPPLIB__lib__debug__hexdump__hpp
#include <cstdio>
#include <algorithm>
#include <limits>
#include "../../lib/types.hpp"
#include "../../lib/literals.hpp"
#include "../../lib/flags.hpp"
#include "../../lib/cstring.hpp"
#include "../../lib/data/buffer.hpp"
#include "../../lib/utils/cp437.hpp"
#include "../../lib/utils/string.hpp"
namespace lib::debug {
// DECLARATION lib::debug::hexdump
/** @brief Hexdump printer
* @note The idea of using CP437 codepage was taken from [Blinkenlights](https://github.com/jart/blink) project,
* developed by Justine Alexandra Roberts Tunney.
* @see https://github.com/jart/blink
*/
struct hexdump {
static constexpr usize COLUMNS = 16;
enum Options
{ NONE = 0x00
, ASCII = 0x01
, CP437 = 0x02
, OFFSET = 0x04
, ADDRESS = 0x08
, STDOUT = 0x10
, STDERR = 0x20
, internal = CP437 | ADDRESS | STDERR
, external = CP437 | OFFSET | STDOUT
};
hexdump( const data::cbuffer_t & buffer, Options options_ = internal, usize offset = 0 ) noexcept;
template< class T >
hexdump( const T * object, Options options = internal ) noexcept
: hexdump { {(const u8*) object, sizeof(*object)}, options }
{}
hexdump( const hexdump & ) = delete;
hexdump( hexdump && ) = delete;
private:
static const char * select_prefix( usize size, const Flag<Options> & options ) noexcept;
};
// INLINES lib::debug::hexdump
inline hexdump::hexdump( const data::cbuffer_t & buffer, Options options_/* = internal*/, usize offset/* = 0*/ ) noexcept {
Flag<Options> options {options_};
auto * f = options.check( STDOUT ) ? stdout : stderr;
const char * prefix = select_prefix( buffer.size(), options );
for ( auto i = 0_sz; i < buffer.size(); i += COLUMNS ) {
const auto prefix_value = options.check( ADDRESS ) ? (usize) &buffer[i] : i + offset;
::std::fprintf( f, prefix, prefix_value );
const auto count = ::std::min( buffer.size() - i, COLUMNS );
const auto & dump = hex( { &buffer[i], count }, " " );
::std::fprintf( f, "%s", dump.c_str() );
if ( not options.check( ASCII ) and not options.check( CP437 ) ) {
::std::fputc( '\n', f );
continue;
}
for ( auto j = count; j < COLUMNS; ++j )
::std::fputs( " "/*hex + space*/, f );
::std::fputs( " | ", f );
for ( auto j = 0_sz; j < count; ++j ) {
if ( options.check( ASCII ) ) {
const char c = (char) buffer[ i + j ];
::std::fputc( is_ascii_graphical( c ) ? c : ' ', f );
} else/* if ( options.check( CP437 ) )*/ {
const auto s = utils::cp437( buffer[ i + j ] );
::std::fputs( s./*c_str*/data(), f );
}
}
for ( auto j = count; j < COLUMNS; ++j )
::std::fputs( " "/*char + space*/, f );
::std::fputc( '\n', f );
}
}
/*static */inline const char * hexdump::select_prefix( usize size, const Flag<Options> & options ) noexcept {
if ( options.check( ADDRESS ) ) {
switch ( sizeof(usize) ) {
case sizeof(u32): return "%08x | ";
case sizeof(u64): return "%016x | ";
default: return "ERROR | ";
}
}
if ( not options.check( OFFSET ) )
return "";
if ( size <= ::std::numeric_limits<u8>::max() ) return "%02x | ";
if ( size <= ::std::numeric_limits<u16>::max() ) return "%04x | ";
if ( size <= ::std::numeric_limits<u32>::max() ) return "%08x | ";
if ( size <= ::std::numeric_limits<u64>::max() ) return "%016x | ";
return "ERROR | ";
}
} // namespace lib::debug
#endif // CPPLIB__lib__debug__hexdump__hpp