-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdebug.hpp
More file actions
87 lines (70 loc) · 2.43 KB
/
Copy pathdebug.hpp
File metadata and controls
87 lines (70 loc) · 2.43 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
#pragma once
#include <ostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
namespace Debug {
namespace detail {
struct StreamState {
StreamState(std::ostream& stream) : stream_(stream), flags_(stream.flags()), fill_(stream.fill()) {
}
~StreamState() {
stream_.flags(flags_);
stream_.fill(fill_);
}
StreamState(const StreamState&) = delete;
private:
std::ostream &stream_;
decltype(stream_.flags()) flags_;
decltype(stream_.fill()) fill_;
};
inline unsigned char printable(unsigned char c)
{
if (c < 32 || c > 126) return '.';
return c;
}
}
template<size_t BPL = 16>
void hexdump(std::ostream &stream, const unsigned char* data, size_t data_size) {
static_assert(BPL % 2 == 0, "Bytes per line is not a multiply of two");
detail::StreamState guard{stream};
size_t offset = 0;
size_t remain = data_size;
const size_t bpl_half = BPL / 2;
while(remain > 0) {
const size_t bytesPerLine = remain < BPL ? remain : BPL;
stream << std::uppercase << std::hex << std::setfill('0') << std::setw(8) << offset << ' ';
for(size_t i = 0; i < bytesPerLine; i++) {
if (i != bpl_half)
stream.put(' ');
else
stream.put('|');
stream << std::setw(2) << static_cast<int>(data[i+offset]);
}
if (remain < BPL) {
const size_t padding = (BPL - remain)*3;
for(size_t i = 0; i < padding; i++) {
stream.put(' ');
}
}
stream << " | ";
for(size_t i = 0; i < bytesPerLine; i++) {
stream << detail::printable(data[i+offset]);
}
stream.put('\n');
remain -= bytesPerLine;
offset += bytesPerLine;
}
}
template<size_t BPL = 16, typename T>
void hexdump(std::ostream &stream, const std::vector<T>& arr) {
hexdump<BPL>(stream, arr.data(), arr.size());
}
template<size_t BPL = 16>
std::string hexdump_str(const unsigned char* data, size_t data_size) {
std::stringstream ss;
hexdump<BPL>(ss, data, data_size);
return ss.str();
}
}