* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include <debug_hex_dump.h>
#include <ctype.h>
#include <stdio.h>
namespace BKernel {
HexDumpDataProvider::~HexDumpDataProvider()
{
}
bool
HexDumpDataProvider::GetAddressString(char* buffer, size_t bufferSize) const
{
return false;
}
HexDumpBufferDataProvider::HexDumpBufferDataProvider(const void* data,
size_t dataSize)
:
fData((const uint8*)data),
fDataSize(dataSize)
{
}
bool
HexDumpBufferDataProvider::HasMoreData() const
{
return fDataSize > 0;
}
uint8
HexDumpBufferDataProvider::NextByte()
{
if (fDataSize == 0)
return '\0';
fDataSize--;
return *fData++;
}
bool
HexDumpBufferDataProvider::GetAddressString(char* buffer,
size_t bufferSize) const
{
snprintf(buffer, bufferSize, "%p", fData);
return true;
}
void
print_hex_dump(HexDumpDataProvider& data, size_t maxBytes, uint32 flags)
{
static const size_t kBytesPerBlock = 4;
static const size_t kBytesPerLine = 16;
size_t i = 0;
for (; i < maxBytes && data.HasMoreData();) {
if (i > 0)
kputs("\n");
uint8 buffer[kBytesPerLine];
if ((flags & HEX_DUMP_FLAG_OMIT_ADDRESS) == 0
&& data.GetAddressString((char*)buffer, sizeof(buffer))) {
kputs((char*)buffer);
kputs(": ");
}
size_t bytesInLine = 0;
for (; i < maxBytes && bytesInLine < kBytesPerLine
&& data.HasMoreData();
i++) {
buffer[bytesInLine++] = data.NextByte();
}
for (size_t k = 0; k < bytesInLine; k++) {
if (k > 0 && k % kBytesPerBlock == 0)
kputs(" ");
kprintf("%02x", buffer[k]);
}
if (bytesInLine < kBytesPerLine) {
int missingBytes = int(kBytesPerLine - bytesInLine);
kprintf("%*s",
2 * missingBytes + int(missingBytes / kBytesPerBlock), "");
}
kputs(" ");
for (size_t k = 0; k < bytesInLine; k++)
kprintf("%c", isprint(buffer[k]) ? buffer[k] : '.');
}
if (i > 0)
kputs("\n");
}
void
print_hex_dump(const void* data, size_t maxBytes, uint32 flags)
{
HexDumpBufferDataProvider dataProvider(data, maxBytes);
print_hex_dump(dataProvider, maxBytes, flags);
}
}