shithub: hx

Download patch

ref: 8485655705e7752e75716896ff96d25deaf9fa0c
author: Sigrid Haflínudóttir <[email protected]>
date: Sat Dec 28 08:16:46 EST 2019

add stuff

--- /dev/null
+++ b/LICENSE
@@ -1,0 +1,1 @@
+Public domain.
--- /dev/null
+++ b/README.md
@@ -1,0 +1,17 @@
+# hx
+
+A faster version of `hexdump -C` that I constantly use.
+
+Comparison on a 1.8Gb file, `time <command> >/dev/null`:
+
+| hexdump -C file | hx file        |
+|:----------------|:---------------|
+| real 3m56.715s  | real 0m6.111s  |
+| user 3m55.839s  | user 0m5.235s  |
+| sus  0m0.847s   | sys  0m0.489s  |
+
+Around 40 times faster, eh?
+
+# Building
+
+`gcc -Wall -Wextra -O2 -s -g0 hx.c -o hx`
--- /dev/null
+++ b/hx.c
@@ -1,0 +1,163 @@
+#ifdef __linux__
+#define _GNU_SOURCE
+#else
+#define _DEFAULT_SOURCE
+#endif
+#define _FILE_OFFSET_BITS 64
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+enum
+{
+	Bufsz = 4*1024*1024,
+	Linesz = 87,
+};
+
+static unsigned char *buf;
+static const char b2h[] = (
+	"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
+	"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
+	"404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
+	"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
+	"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"
+	"a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
+	"c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
+	"e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
+);
+
+static int
+hx(int fd)
+{
+	size_t addr;
+	ssize_t sz, i;
+	char s[65536], c;
+	unsigned char line[16];
+	int wroff, off, eof, wrlen, lineoff, r;
+
+#ifdef __linux__
+		readahead(fd, 0, Bufsz);
+#endif
+
+	lineoff = 0;
+	off = 0;
+	eof = 0;
+	for (addr = 0; eof == 0 && (sz = read(fd, buf, Bufsz)) > 0;) {
+		for (i = 0; i < sz; ) {
+			if (off >= (int)sizeof(s)-Linesz) {
+				wrlen = off - (off % Linesz);
+				for (wroff = 0; wroff < wrlen; wroff += r) {
+					if ((r = write(1, s+wroff, wrlen-wroff)) < 0) {
+						sz = -1;
+						break;
+					}
+				}
+				memmove(s, s+wrlen, off-wrlen);
+				off -= wrlen;
+			}
+
+			if (lineoff == 0) {
+				s[off++] = b2h[((addr>>55) & 0x1fe)];
+				s[off++] = b2h[((addr>>55) & 0x1fe)+1];
+				s[off++] = b2h[((addr>>47) & 0x1fe)];
+				s[off++] = b2h[((addr>>47) & 0x1fe)+1];
+				s[off++] = b2h[((addr>>39) & 0x1fe)];
+				s[off++] = b2h[((addr>>39) & 0x1fe)+1];
+				s[off++] = b2h[((addr>>31) & 0x1fe)];
+				s[off++] = b2h[((addr>>31) & 0x1fe)+1];
+				s[off++] = b2h[((addr>>23) & 0x1fe)];
+				s[off++] = b2h[((addr>>23) & 0x1fe)+1];
+				s[off++] = b2h[((addr>>15) & 0x1fe)];
+				s[off++] = b2h[((addr>>15) & 0x1fe)+1];
+				s[off++] = b2h[((addr>>7) & 0x1fe)];
+				s[off++] = b2h[((addr>>7) & 0x1fe)+1];
+				s[off++] = b2h[((addr<<1) & 0x1fe)];
+				s[off++] = b2h[((addr<<1) & 0x1fe)+1];
+				s[off++] = ' ';
+				s[off++] = ' ';
+			}
+
+			for (; i < sz && lineoff < 16; i++, addr++) {
+				if (lineoff < 16)
+					line[lineoff++] = buf[i];
+				s[off++] = b2h[(int)buf[i]*2+0];
+				s[off++] = b2h[(int)buf[i]*2+1];
+				s[off++] = ' ';
+				if (lineoff == 8)
+					s[off++] = ' ';
+			}
+
+			if (lineoff == 16) {
+asci:
+				s[off++] = ' ';
+				s[off++] = '|';
+				for (lineoff = 0; lineoff < 16; lineoff++) {
+					c = line[lineoff];
+					if (c < 0x20 || c > 0x7e)
+						c = '.';
+					s[off++] = c;
+				}
+				s[off++] = '|';
+				s[off++] = '\n';
+				lineoff = 0;
+			}
+		}
+
+#ifdef __linux__
+		readahead(fd, addr, Bufsz);
+#endif
+	}
+
+	if (sz >= 0) {
+		if (eof == 0 && lineoff > 0 && lineoff < 16) {
+			eof = 1;
+			for (; lineoff < 16; lineoff++) {
+				line[lineoff] = 0;
+				s[off++] = ' ';
+				s[off++] = ' ';
+				s[off++] = ' ';
+			}
+			i = sz = 0;
+			goto asci;
+		}
+		for (wroff = 0; wroff < off; wroff += r) {
+			if ((r = write(1, s+wroff, off-wroff)) < 0) {
+				sz = -1;
+				break;
+			}
+		}
+	}
+
+	return sz != 0;
+}
+
+int
+main(int argc, char **argv)
+{
+	int i, fd, res;
+
+	res = 0;
+
+	if ((buf = malloc(Bufsz)) == NULL) {
+		perror("buf");
+		res = 1;
+	}
+
+	for (i = 1; i < argc && res == 0; i++) {
+		if ((fd = open(argv[i], O_RDONLY)) < 0) {
+			perror(argv[i]);
+			res = 1;
+		} else {
+			if ((res = hx(fd)) != 0)
+				perror(argv[1]);
+			close(fd);
+		}
+	}
+
+	memset(buf, 0, Bufsz);
+	free(buf);
+
+	return res;
+}