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