source: trunk/SL/APP/hexdump.hxx

Last change on this file was 19612, checked in by westram, 11 days ago
  • insert module purposes.
File size: 4.3 KB
Line 
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
28CONSTEXPR_INLINE char nibble2hex(unsigned char c) { return "0123456789ABCDEF"[c&0x0f]; }
29inline void dump_hexbyte(GBS_strstruct& buf, unsigned char c) { buf.put(nibble2hex(c>>4)); buf.put(nibble2hex(c)); }
30
31class 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 {
80        arb_assert(wrapped());
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
90public:
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
Note: See TracBrowser for help on using the repository browser.