xref: /haiku/src/system/kernel/debug/debug_hex_dump.cpp (revision dd11460a496599dcec7a7d71a36558c943e056ec)
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