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