source: tags/ms_r18q1/AWT/awt_hexdump.hxx

Last change on this file was 15529, checked in by westram, 7 years ago
File size: 4.4 KB
Line 
1// ================================================================= //
2//                                                                   //
3//   File      : awt_hexdump.hxx                                     //
4//   Purpose   :                                                     //
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 AWT_HEXDUMP_HXX
13#define AWT_HEXDUMP_HXX
14
15#ifndef AWT_HXX
16#include "awt.hxx"
17#endif
18
19#ifndef AW_ROOT_HXX
20#include <aw_root.hxx>
21#endif
22#ifndef ARB_STRBUF_H
23#include <arb_strbuf.h>
24#endif
25#ifndef _GLIBCXX_CCTYPE
26#include <cctype>
27#endif
28
29// -------------------
30//      hex dumper
31
32CONSTEXPR_INLINE char nibble2hex(unsigned char c) { return "0123456789ABCDEF"[c&0x0f]; }
33inline void dump_hexbyte(GBS_strstruct& buf, unsigned char c) { buf.put(nibble2hex(c>>4)); buf.put(nibble2hex(c)); }
34
35class MemDump {
36    bool show_offset;   // prefix every line with position info ?
37    bool hex;           // dump hex ?
38    bool ascii;         // dump ascii ?
39
40    size_t width;       // > 0   -> wrap lines every XXX positions
41    size_t separate;    // > 0   -> separate by one additional space after every XXX bytes
42    bool   space;       // true -> space hex bytes
43
44    bool is_separate_position(size_t pos) const { return separate && pos && !(pos%separate); }
45
46    void dump_sep(GBS_strstruct& buf) const { buf.cat(" | "); }
47    void dump_offset(GBS_strstruct& buf, size_t off) const {
48        if (show_offset) {
49            dump_hexbyte(buf, off>>8);
50            dump_hexbyte(buf, off&0xff);
51            if (hex||ascii) dump_sep(buf);
52        }
53    }
54    void dump_hex(GBS_strstruct& buf, const char *mem, size_t off, size_t count, bool padded) const {
55        size_t i;
56        for (i = 0; i<count; ++i) {
57            if (is_separate_position(i)) buf.put(' ');
58            dump_hexbyte(buf, mem[off+i]);
59            if (space) buf.put(' ');
60        }
61        if (padded) {
62            for (; i<width; ++i) {
63                buf.nput(' ', 3+is_separate_position(i));
64            }
65        }
66        buf.cut_tail(space);
67    }
68    void dump_ascii(GBS_strstruct& buf, const char *mem, size_t off, size_t count) const {
69        for (size_t i = 0; i<count; ++i) {
70            if (is_separate_position(i)) buf.put(' ');
71            buf.put(isprint(mem[off+i]) ? mem[off+i] : '.');
72        }
73    }
74    void dump_line(GBS_strstruct& buf, const char *mem, size_t off, size_t count) const {
75        dump_offset(buf, off);
76        if (hex) {
77            dump_hex(buf, mem, off, count, ascii);
78            if (ascii) dump_sep(buf);
79        }
80        if (ascii) dump_ascii(buf, mem, off, count);
81        buf.put('\n');
82    }
83    void dump_wrapped(GBS_strstruct& buf, const char *mem, size_t size) const {
84        awt_assert(wrapped());
85        size_t off = 0;
86        while (size) {
87            size_t count = size<width ? size : width;
88            dump_line(buf, mem, off, count);
89            size -= count;
90            off  += count;
91        }
92    }
93
94public:
95
96    MemDump(bool show_offset_, bool hex_, bool ascii_, size_t  width_ = 0, size_t  separate_ = 0, bool space_ = true)
97        : show_offset(show_offset_),
98          hex(hex_),
99          ascii(ascii_),
100          width(width_),
101          separate(separate_), 
102          space(space_)
103    {}
104
105    bool wrapped() const { return width; }
106   
107    size_t mem_needed_for_dump(size_t bytes) const {
108        size_t sections = show_offset+hex+ascii;
109
110        if (!sections) return 1;
111
112        size_t perByte      = hex*3+ascii;
113        size_t extraPerLine = (sections-1)*3+1;
114        size_t lines        = width ? bytes/width+1 : 1;
115
116        return bytes*perByte + lines*extraPerLine + 50;
117    }
118
119    void dump_to(GBS_strstruct& buf, const char *mem, size_t size) const {
120        if (size) {
121            if (wrapped()) dump_wrapped(buf, mem, size);
122            else { // one-line dump
123                MemDump mod(*this);
124                mod.width = size;
125                mod.dump_wrapped(buf, mem, size);
126            }
127        }
128    }
129};
130
131
132
133#else
134#error awt_hexdump.hxx included twice
135#endif // AWT_HEXDUMP_HXX
Note: See TracBrowser for help on using the repository browser.