hex

Hex stream reader / writer
git clone https://git.sinitax.com/sinitax/hex
Log | Files | Refs | LICENSE | sfeed.txt

hexv.c (2203B)


      1#include <fcntl.h>
      2#include <unistd.h>
      3#include <err.h>
      4#include <errno.h>
      5
      6#include <stdlib.h>
      7#include <string.h>
      8#include <stdio.h>
      9#include <stdint.h>
     10#include <stdbool.h>
     11
     12static const char hex[] = "0123456789abcdef";
     13
     14static int color = 0;
     15static int gradient[256] = {
     16	[0] = 241,
     17	[1 ... 31] = 242,
     18	[32 ... 63] = 244,
     19	[64 ... 95] = 246,
     20	[96 ... 127] = 247,
     21	[128 ... 159] = 248,
     22	[160 ... 191] = 250,
     23	[192 ... 223] = 252,
     24	[224 ... 254] = 254,
     25	[255] = 255,
     26};
     27
     28/* command-line arguments */
     29static bool newline_aware = false;
     30
     31void
     32colorhex(uint8_t c)
     33{
     34	if (gradient[c] != color) {
     35		color = gradient[c];
     36		printf("\x1b[38;5;%im", color);
     37	}
     38	putchar(hex[(c >> 4) & 0xf]);
     39	putchar(hex[(c >> 0) & 0xf]);
     40}
     41
     42void
     43printrow(char *row, size_t pos, size_t len)
     44{
     45	size_t i;
     46
     47	printf("%08lx: ", pos);
     48	for (i = 0; i < 16; i++) {
     49		if (i < len) {
     50			colorhex(row[i]);
     51		} else {
     52			printf("  ");
     53		}
     54		if ((i + 1) % 2 == 0)
     55			putchar(' ');
     56	}
     57	if (color != 0)
     58		printf("\x1b[0m");
     59	color = 0;
     60
     61	printf("  ");
     62
     63	for (i = 0; i < 16; i++) {
     64		if (i < len) {
     65			if (row[i] >= 0x20 && row[i] <= 126) {
     66				putchar(row[i]);
     67			} else {
     68				putchar('.');
     69			}
     70		} else {
     71			putchar(' ');
     72		}
     73	}
     74	printf("\n");
     75}
     76
     77void
     78tohex(int fd)
     79{
     80	size_t last, pos, i, k;
     81	ssize_t nread;
     82	char buf[4096];
     83	char row[16];
     84
     85	last = pos = 0;
     86	while (1) {
     87		nread = read(fd, buf, sizeof(buf));
     88		if (nread <= 0) break;
     89
     90		for (i = 0; i < nread; i++, pos++) {
     91			row[pos - last] = buf[i];
     92			if (pos == last + 15 || buf[i] == '\n' && newline_aware) {
     93				printrow(row, last, pos - last + 1);
     94				last = pos + 1;
     95			}
     96		}
     97	}
     98
     99	if (pos != last)
    100		printrow(row, last, pos - last);
    101}
    102
    103int
    104main(int argc, const char **argv)
    105{
    106	const char **arg, **farg;
    107	int fd;
    108
    109	if (argc < 1) return 1;
    110
    111	for (arg = argv + 1; *arg; arg++) {
    112		if (!strcmp(*arg, "-n") || !strcmp(*arg, "--newline-aware")) {
    113			newline_aware = true;
    114		} else {
    115			break;
    116		}
    117	}
    118
    119	if (*arg) {
    120		for (farg = arg; *farg; farg++) {
    121			if (farg != arg) printf("\n");
    122			fd = open(*farg, O_RDONLY);
    123			if (fd < 0) {
    124				fprintf(stderr, "hexv: open '%s': %s",
    125					*farg, strerror(errno));
    126				continue;
    127			}
    128			tohex(fd);
    129			close(fd);
    130		}
    131	} else {
    132		tohex(0);
    133	}
    134}
    135