1 /*
2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include <debug_hex_dump.h>
8
9 #include <ctype.h>
10 #include <stdio.h>
11
12
13 namespace BKernel {
14
15
16 // #pragma mark - HexDumpDataProvider
17
18
~HexDumpDataProvider()19 HexDumpDataProvider::~HexDumpDataProvider()
20 {
21 }
22
23
24 bool
GetAddressString(char * buffer,size_t bufferSize) const25 HexDumpDataProvider::GetAddressString(char* buffer, size_t bufferSize) const
26 {
27 return false;
28 }
29
30
31 // #pragma mark - HexDumpBufferDataProvider
32
33
HexDumpBufferDataProvider(const void * data,size_t dataSize)34 HexDumpBufferDataProvider::HexDumpBufferDataProvider(const void* data,
35 size_t dataSize)
36 :
37 fData((const uint8*)data),
38 fDataSize(dataSize)
39 {
40 }
41
42
43 bool
HasMoreData() const44 HexDumpBufferDataProvider::HasMoreData() const
45 {
46 return fDataSize > 0;
47 }
48
49
50 uint8
NextByte()51 HexDumpBufferDataProvider::NextByte()
52 {
53 if (fDataSize == 0)
54 return '\0';
55
56 fDataSize--;
57 return *fData++;
58 }
59
60
61 bool
GetAddressString(char * buffer,size_t bufferSize) const62 HexDumpBufferDataProvider::GetAddressString(char* buffer,
63 size_t bufferSize) const
64 {
65 snprintf(buffer, bufferSize, "%p", fData);
66 return true;
67 }
68
69
70 // #pragma mark -
71
72
73 void
print_hex_dump(HexDumpDataProvider & data,size_t maxBytes,uint32 flags)74 print_hex_dump(HexDumpDataProvider& data, size_t maxBytes, uint32 flags)
75 {
76 static const size_t kBytesPerBlock = 4;
77 static const size_t kBytesPerLine = 16;
78
79 size_t i = 0;
80 for (; i < maxBytes && data.HasMoreData();) {
81 if (i > 0)
82 kputs("\n");
83
84 // print address
85 uint8 buffer[kBytesPerLine];
86 if ((flags & HEX_DUMP_FLAG_OMIT_ADDRESS) == 0
87 && data.GetAddressString((char*)buffer, sizeof(buffer))) {
88 kputs((char*)buffer);
89 kputs(": ");
90 }
91
92 // get the line data
93 size_t bytesInLine = 0;
94 for (; i < maxBytes && bytesInLine < kBytesPerLine
95 && data.HasMoreData();
96 i++) {
97 buffer[bytesInLine++] = data.NextByte();
98 }
99
100 // print hex representation
101 for (size_t k = 0; k < bytesInLine; k++) {
102 if (k > 0 && k % kBytesPerBlock == 0)
103 kputs(" ");
104 kprintf("%02x", buffer[k]);
105 }
106
107 // pad to align the text representation, if line is incomplete
108 if (bytesInLine < kBytesPerLine) {
109 int missingBytes = int(kBytesPerLine - bytesInLine);
110 kprintf("%*s",
111 2 * missingBytes + int(missingBytes / kBytesPerBlock), "");
112 }
113
114 // print character representation
115 kputs(" ");
116 for (size_t k = 0; k < bytesInLine; k++)
117 kprintf("%c", isprint(buffer[k]) ? buffer[k] : '.');
118 }
119
120 if (i > 0)
121 kputs("\n");
122 }
123
124
125 void
print_hex_dump(const void * data,size_t maxBytes,uint32 flags)126 print_hex_dump(const void* data, size_t maxBytes, uint32 flags)
127 {
128 HexDumpBufferDataProvider dataProvider(data, maxBytes);
129 print_hex_dump(dataProvider, maxBytes, flags);
130 }
131
132
133 } // namespace BKernel
134