Add a hex dump utility for use in KDL commands

This commit is contained in:
Ingo Weinhold 2013-11-25 12:25:19 +01:00
parent 4192f44dc4
commit dd11460a49
3 changed files with 189 additions and 0 deletions

View File

@ -0,0 +1,55 @@
/*
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_DEBUG_HEX_DUMP_H
#define _KERNEL_DEBUG_HEX_DUMP_H
#include <debug.h>
namespace BKernel {
enum {
HEX_DUMP_FLAG_OMIT_ADDRESS = 0x01
};
class HexDumpDataProvider {
public:
virtual ~HexDumpDataProvider();
virtual bool HasMoreData() const = 0;
virtual uint8 NextByte() = 0;
virtual bool GetAddressString(char* buffer,
size_t bufferSize) const;
};
class HexDumpBufferDataProvider : public HexDumpDataProvider {
public:
HexDumpBufferDataProvider(const void* data,
size_t dataSize);
virtual bool HasMoreData() const;
virtual uint8 NextByte();
virtual bool GetAddressString(char* buffer,
size_t bufferSize) const;
private:
const uint8* fData;
size_t fDataSize;
};
void print_hex_dump(HexDumpDataProvider& data, size_t maxBytes,
uint32 flags = 0);
void print_hex_dump(const void* data, size_t maxBytes, uint32 flags = 0);
} // namespace BKernel
#endif /* _KERNEL_DEBUG_HEX_DUMP_H */

View File

@ -15,6 +15,7 @@ KernelMergeObject kernel_debug.o :
debug_builtin_commands.cpp
debug_commands.cpp
debug_heap.cpp
debug_hex_dump.cpp
debug_paranoia.cpp
debug_parser.cpp
debug_variables.cpp

View File

@ -0,0 +1,133 @@
/*
* 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 {
// #pragma mark - HexDumpDataProvider
HexDumpDataProvider::~HexDumpDataProvider()
{
}
bool
HexDumpDataProvider::GetAddressString(char* buffer, size_t bufferSize) const
{
return false;
}
// #pragma mark - HexDumpBufferDataProvider
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;
}
// #pragma mark -
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");
// print address
uint8 buffer[kBytesPerLine];
if ((flags & HEX_DUMP_FLAG_OMIT_ADDRESS) == 0
&& data.GetAddressString((char*)buffer, sizeof(buffer))) {
kputs((char*)buffer);
kputs(": ");
}
// get the line data
size_t bytesInLine = 0;
for (; i < maxBytes && bytesInLine < kBytesPerLine
&& data.HasMoreData();
i++) {
buffer[bytesInLine++] = data.NextByte();
}
// print hex representation
for (size_t k = 0; k < bytesInLine; k++) {
if (k > 0 && k % kBytesPerBlock == 0)
kputs(" ");
kprintf("%02x", buffer[k]);
}
// pad to align the text representation, if line is incomplete
if (bytesInLine < kBytesPerLine) {
int missingBytes = int(kBytesPerLine - bytesInLine);
kprintf("%*s",
2 * missingBytes + int(missingBytes / kBytesPerBlock), "");
}
// print character representation
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);
}
} // namespace BKernel