ARB
hexdump.hxx
Go to the documentation of this file.
1 // ================================================================= //
2 // //
3 // File : hexdump.hxx //
4 // Purpose : customizable memory hex/ascii dump //
5 // //
6 // Coded by Ralf Westram (coder@reallysoft.de) in September 2011 //
7 // Institute of Microbiology (Technical University Munich) //
8 // http://www.arb-home.de/ //
9 // //
10 // ================================================================= //
11 
12 #ifndef HEXDUMP_HXX
13 #define HEXDUMP_HXX
14 
15 #ifndef AW_ROOT_HXX
16 #include <aw_root.hxx>
17 #endif
18 #ifndef ARB_STRBUF_H
19 #include <arb_strbuf.h>
20 #endif
21 #ifndef _GLIBCXX_CCTYPE
22 #include <cctype>
23 #endif
24 
25 // -------------------
26 // hex dumper
27 
28 CONSTEXPR_INLINE char nibble2hex(unsigned char c) { return "0123456789ABCDEF"[c&0x0f]; }
29 inline void dump_hexbyte(GBS_strstruct& buf, unsigned char c) { buf.put(nibble2hex(c>>4)); buf.put(nibble2hex(c)); }
30 
31 class MemDump {
32  bool show_offset; // prefix every line with position info ?
33  bool hex; // dump hex ?
34  bool ascii; // dump ascii ?
35 
36  size_t width; // > 0 -> wrap lines every XXX positions
37  size_t separate; // > 0 -> separate by one additional space after every XXX bytes
38  bool space; // true -> space hex bytes
39 
40  bool is_separate_position(size_t pos) const { return separate && pos && !(pos%separate); }
41 
42  void dump_sep(GBS_strstruct& buf) const { buf.cat(" | "); }
43  void dump_offset(GBS_strstruct& buf, size_t off) const {
44  if (show_offset) {
45  dump_hexbyte(buf, off>>8);
46  dump_hexbyte(buf, off&0xff);
47  if (hex||ascii) dump_sep(buf);
48  }
49  }
50  void dump_hex(GBS_strstruct& buf, const char *mem, size_t off, size_t count, bool padded) const {
51  size_t i;
52  for (i = 0; i<count; ++i) {
53  if (is_separate_position(i)) buf.put(' ');
54  dump_hexbyte(buf, mem[off+i]);
55  if (space) buf.put(' ');
56  }
57  if (padded) {
58  for (; i<width; ++i) {
59  buf.nput(' ', 2+space+is_separate_position(i));
60  }
61  }
62  buf.cut_tail(space);
63  }
64  void dump_ascii(GBS_strstruct& buf, const char *mem, size_t off, size_t count) const {
65  for (size_t i = 0; i<count; ++i) {
66  if (is_separate_position(i)) buf.put(' ');
67  buf.put(isprint(mem[off+i]) ? mem[off+i] : '.');
68  }
69  }
70  void dump_line(GBS_strstruct& buf, const char *mem, size_t off, size_t count) const {
71  dump_offset(buf, off);
72  if (hex) {
73  dump_hex(buf, mem, off, count, ascii);
74  if (ascii) dump_sep(buf);
75  }
76  if (ascii) dump_ascii(buf, mem, off, count);
77  buf.put('\n');
78  }
79  void dump_wrapped(GBS_strstruct& buf, const char *mem, size_t size) const {
81  size_t off = 0;
82  while (size) {
83  size_t count = size<width ? size : width;
84  dump_line(buf, mem, off, count);
85  size -= count;
86  off += count;
87  }
88  }
89 
90 public:
91 
92  MemDump(bool show_offset_, bool hex_, bool ascii_, size_t width_ = 0, size_t separate_ = 0, bool space_ = true)
93  : show_offset(show_offset_),
94  hex(hex_),
95  ascii(ascii_),
96  width(width_),
97  separate(separate_),
98  space(space_)
99  {}
100 
101  bool wrapped() const { return width; }
102 
103  size_t mem_needed_for_dump(size_t bytes) const {
104  size_t sections = show_offset+hex+ascii;
105 
106  if (!sections) return 1;
107 
108  size_t perByte = hex*3+ascii;
109  size_t extraPerLine = (sections-1)*3+1;
110  size_t lines = width ? bytes/width+1 : 1;
111 
112  return bytes*perByte + lines*extraPerLine + 50;
113  }
114 
115  void dump_to(GBS_strstruct& buf, const char *mem, size_t size) const {
116  if (size) {
117  if (wrapped()) dump_wrapped(buf, mem, size);
118  else { // one-line dump
119  MemDump mod(*this);
120  mod.width = size;
121  mod.dump_wrapped(buf, mem, size);
122  }
123  }
124  }
125 };
126 
127 
128 
129 #else
130 #error hexdump.hxx included twice
131 #endif // HEXDUMP_HXX
#define arb_assert(cond)
Definition: arb_assert.h:245
void cut_tail(size_t byte_count)
Definition: arb_strbuf.h:145
void dump_hexbyte(GBS_strstruct &buf, unsigned char c)
Definition: hexdump.hxx:29
void nput(char c, size_t count)
Definition: arb_strbuf.h:180
void cat(const char *from)
Definition: arb_strbuf.h:199
bool wrapped() const
Definition: hexdump.hxx:101
CONSTEXPR_INLINE char nibble2hex(unsigned char c)
Definition: hexdump.hxx:28
size_t mem_needed_for_dump(size_t bytes) const
Definition: hexdump.hxx:103
#define CONSTEXPR_INLINE
Definition: cxxforward.h:111
void dump_to(GBS_strstruct &buf, const char *mem, size_t size) const
Definition: hexdump.hxx:115
MemDump(bool show_offset_, bool hex_, bool ascii_, size_t width_=0, size_t separate_=0, bool space_=true)
Definition: hexdump.hxx:92
void put(char c)
Definition: arb_strbuf.h:174