You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hexview/src/hex.cpp

140 lines
5.0 KiB

4 years ago
#include <fmt/format.h>
#include <span.hpp>
4 years ago
#include <hex.hpp>
4 years ago
4 years ago
const static constexpr char ascii_map[256] = {
4 years ago
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
4 years ago
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
4 years ago
};
4 years ago
constexpr const static char* hex_map[256] = {
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
"30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
"50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
"60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
"70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
"80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
"90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df",
"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff",
};
#ifndef FIXED_ROW_SIZE
#include <alloca.h>
#endif
#ifdef FIXED_ROW_SIZE
4 years ago
constexpr const int ROW_SZ = FIXED_ROW_SIZE;
#endif
4 years ago
template<typename... S>
inline __attribute__((always_inline)) void prints(const S&... strings)
{
(fputs((const char*)strings, stdout), ...);
}
inline void hex02(std::uint8_t byte, char buffer[2])
{
buffer[0] =hex_map[byte][0];
buffer[1] =hex_map[byte][1];
}
template<std::size_t N>
4 years ago
inline __attribute__((always_inline)) void print_exact(const char* ar)
{
fwrite(ar, 1, N, stdout);
}
4 years ago
template<std::size_t N>
inline __attribute__((always_inline)) void print_exact(const char (&ar)[N])
{
fwrite(ar, N, 1, stdout);
}
4 years ago
inline static void u64_to_hex(std::uint64_t num, char* s)
{
hv::lookup_hex_string(num, s);
}
4 years ago
namespace hv {
void print_screen(const span<unsigned char> memory, unsigned long offset)
{
#ifndef FIXED_ROW_SIZE
#define S (2+ROW_SZ)
#define P_EX(n, buf) fwrite(buf, 1, n, stdout)
int ROW_SZ = 24;
#else
#define S
#define P_EX(n, buf) print_exact(buf)
#endif
char posbuf[3 + 16 + 2];
4 years ago
posbuf[0] = '\n';
posbuf[1] = '0';
posbuf[2] = 'x';
#ifdef DEBUG
std::memset(posbuf+3, '0', 16);
#endif
4 years ago
posbuf[3 + 16] = ' ';
posbuf[3 + 16 + 1] = ' ';
u64_to_hex(offset, posbuf+3);
prints(posbuf+1);
char hxbuf[3] = { ' ', ' ', ' ' };
4 years ago
std::size_t i=0;
char r_ascii[2 + ROW_SZ];
r_ascii[0] = ' ';
r_ascii[1] = ' ';
char* ascii = r_ascii + 2;
4 years ago
const auto memsize = memory.size();
4 years ago
for(;i<memsize;i++) {
4 years ago
if (i && i % ROW_SZ == 0) { //TODO: Change to i +=16 so we don't have to branch here on every byte. Make sure to not overrun buffer tho
P_EX(S, r_ascii);
4 years ago
u64_to_hex(i+offset, posbuf+3);
print_exact(posbuf);
}
4 years ago
unsigned char idx = memory[i];
hex02(idx, hxbuf);
print_exact(hxbuf);
4 years ago
4 years ago
ascii[i%ROW_SZ] = ascii_map[idx];
}
4 years ago
if (memsize % ROW_SZ != 0)
{
4 years ago
auto rest = memsize % ROW_SZ;
ascii[rest] = 0;
constexpr const char output[3] = { ' ', ' ', ' ' };
for(std::size_t j=0;j< ROW_SZ - rest;j++)
print_exact(output);
prints((const char*) r_ascii);
}
else {
P_EX(S, r_ascii);
}
}
4 years ago
}