xref: /haiku/src/system/kernel/debug/debug_hex_dump.cpp (revision 3b07762c548ec4016dea480d1061577cd15ec614)
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 
19 HexDumpDataProvider::~HexDumpDataProvider()
20 {
21 }
22 
23 
24 bool
25 HexDumpDataProvider::GetAddressString(char* buffer, size_t bufferSize) const
26 {
27 	return false;
28 }
29 
30 
31 // #pragma mark - HexDumpBufferDataProvider
32 
33 
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
44 HexDumpBufferDataProvider::HasMoreData() const
45 {
46 	return fDataSize > 0;
47 }
48 
49 
50 uint8
51 HexDumpBufferDataProvider::NextByte()
52 {
53 	if (fDataSize == 0)
54 		return '\0';
55 
56 	fDataSize--;
57 	return *fData++;
58 }
59 
60 
61 bool
62 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
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
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