mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-08 17:50:31 +01:00
add hexdump utility
This commit is contained in:
parent
83ee2942fc
commit
26ffd8cbb2
|
|
@ -4,6 +4,7 @@ find_package(Git)
|
|||
|
||||
|
||||
add_library(${PROJECT_NAME} OBJECT
|
||||
src/hexdump.cpp
|
||||
src/mem.cpp
|
||||
src/Version.cpp
|
||||
)
|
||||
|
|
|
|||
8
rx/include/rx/hexdump.hpp
Normal file
8
rx/include/rx/hexdump.hpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <span>
|
||||
|
||||
namespace rx {
|
||||
void hexdump(std::span<std::byte> bytes);
|
||||
} // namespace rx
|
||||
85
rx/src/hexdump.cpp
Normal file
85
rx/src/hexdump.cpp
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
#include "hexdump.hpp"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
void rx::hexdump(std::span<std::byte> bytes) {
|
||||
unsigned sizeWidth = 1;
|
||||
|
||||
{
|
||||
std::size_t size = bytes.size() / 0x10;
|
||||
|
||||
while (size > 0) {
|
||||
sizeWidth++;
|
||||
size /= 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
flockfile(stderr);
|
||||
std::fprintf(stderr, "%s ", std::string(sizeWidth, ' ').c_str());
|
||||
for (unsigned i = 0; i < 16; ++i) {
|
||||
std::fprintf(stderr, " %02x", i);
|
||||
}
|
||||
std::fprintf(stderr, "\n%s ", std::string(sizeWidth, ' ').c_str());
|
||||
for (unsigned i = 0; i < 16; ++i) {
|
||||
std::fprintf(stderr, " --");
|
||||
}
|
||||
|
||||
std::byte zeros[16]{};
|
||||
|
||||
bool wasAllZeros = true;
|
||||
bool dotsPrinted = false;
|
||||
for (std::size_t i = 0; i < bytes.size(); ++i) {
|
||||
if (i % 16 == 0) {
|
||||
if (i > 0) {
|
||||
if (wasAllZeros && bytes.size() - i > 16) {
|
||||
if (std::memcmp(bytes.data() + i, zeros, 16) == 0) {
|
||||
if (!dotsPrinted) {
|
||||
dotsPrinted = true;
|
||||
std::printf("\n...");
|
||||
}
|
||||
i += 15;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dotsPrinted) {
|
||||
std::fprintf(stderr, " | ");
|
||||
|
||||
for (std::size_t j = i - 16; j < i; ++j) {
|
||||
auto c = unsigned(bytes[j]);
|
||||
std::fprintf(stderr, "%c",
|
||||
(std::isprint(c) && c != '\n') ? c : '.');
|
||||
}
|
||||
}
|
||||
}
|
||||
std::fprintf(stderr, "\n");
|
||||
std::fprintf(stderr, "%0*zx ", sizeWidth, i);
|
||||
wasAllZeros = true;
|
||||
dotsPrinted = false;
|
||||
}
|
||||
|
||||
std::fprintf(stderr, " %02x", unsigned(bytes[i]));
|
||||
|
||||
if (bytes[i] != std::byte{0}) {
|
||||
wasAllZeros = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bytes.empty()) {
|
||||
for (std::size_t i = 0; i < (16 - (bytes.size() % 16)) % 16; ++i) {
|
||||
std::fprintf(stderr, " ");
|
||||
}
|
||||
std::fprintf(stderr, " | ");
|
||||
|
||||
for (std::size_t j = bytes.size() -
|
||||
std::min(bytes.size(),
|
||||
(bytes.size() % 16 ? bytes.size() % 16 : 16));
|
||||
j < bytes.size(); ++j) {
|
||||
auto c = unsigned(bytes[j]);
|
||||
std::fprintf(stderr, "%c", (std::isprint(c) && c != '\n') ? c : '.');
|
||||
}
|
||||
}
|
||||
std::fprintf(stderr, "\n");
|
||||
funlockfile(stderr);
|
||||
}
|
||||
Loading…
Reference in a new issue