#include "hexdump_pretty.h" #include #include #include #include #include #include #define LINELEN 0x8 static struct segment line_segments[LINELEN]; static size_t file_idx = 0; static size_t line_idx = 0; static size_t current_segment = 0; enum color next_color(void) { static uint8_t cc = 0; cc += 1; cc %= 6; return cc + 1; } void color_put(enum color c) { printf("\x1b[0;3%im", c); } void color_reset(void) { printf("\x1b[m"); } void cleanup_line(void) { for (int i = 0; i < current_segment; i++) { free(line_segments[i].data); } } void put_byte(uint8_t byte) { static bool flip = 0; printf("%02x", byte); flip = !flip; if (! flip) { printf(" "); } } void flush_line() { printf("%06lx: ", file_idx); file_idx += LINELEN; for (int i = 0; i < current_segment; i++) { color_put(line_segments[i].c); for (int b = 0; b < line_segments[i].len; b++) { put_byte(line_segments[i].data[b]); } color_reset(); } for (int i = 0; i < current_segment; i++) { color_put(line_segments[i].c); for (int b = 0; b < line_segments[i].len; b++) { uint8_t ch = line_segments[i].data[b]; if (isprint(ch)) { printf("%c", ch); } else { printf("."); } } color_reset(); } printf("\n"); } void add_segment(struct segment segment) { line_segments[current_segment++] = segment; line_idx += segment.len; if (line_idx == LINELEN) { flush_line(); cleanup_line(); current_segment = 0; line_idx = 0; } } /* * Buf MUST be a malloc:ed buffer, which is invalidated on this call. */ void write_chunk(uint8_t *buf, size_t len) { if (line_idx + len >= LINELEN) { enum color c = next_color(); size_t len1 = LINELEN - line_idx, len2 = len - len1; uint8_t *buf1 = malloc(len1), *buf2 = malloc(len2); memcpy(buf1, buf, len1); memcpy(buf2, buf + len1, len2); free(buf); struct segment seg1 = { .c = c, .len = len1, .data = buf1, }, seg2 = { .c = c, .len = len2, .data = buf2, }; add_segment(seg1); add_segment(seg2); } else { struct segment seg = { .c = next_color(), .len = len, .data = buf, }; add_segment(seg); } } void write_chunk_s(uint8_t *buf, size_t len) { assert (len >= 0); uint8_t *true_buf = malloc(len); memcpy(true_buf, buf, len); write_chunk(true_buf, len); }