commit 46d0b88eff89c5b054e238f0c299ca99f5201338
parent 7820b93c0fcf6cc0784bec297e55f0302b0a6b52
Author: Alexey Yerin <yyp@disroot.org>
Date: Sun, 28 Mar 2021 17:11:32 +0300
Add encoding::hex::dump
Diffstat:
3 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/encoding/hex/hex.ha b/encoding/hex/hex.ha
@@ -1,4 +1,6 @@
+use ascii;
use bytes;
+use fmt;
use io;
use strconv;
use strings;
@@ -61,3 +63,55 @@ export fn decode(s: str) ([]u8 | invalid) = {
decode("this is not hex") as invalid;
};
+
+// Outputs a dump of hex data to a stream alongside the offset and an ASCII
+// representation (if applicable).
+//
+// Example output:
+//
+// 00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
+// 00000010 03 00 3e 00 01 00 00 00 80 70 01 00 00 00 00 00 |..>......p......|
+export fn dump(out: *io::stream, data: []u8) (void | io::error) = {
+ let datalen = len(data): u32;
+
+ for (let off = 0u32; off < datalen; off += 16) {
+ fmt::fprintf(out, "{:08x} ", off)?;
+
+ let toff = 0z;
+ for (let i = 0z; i < 16 && off + i < datalen; i += 1) {
+ let val = data[off + i];
+ toff += fmt::fprintf(out, "{}{:02x} ",
+ if (i == 8) " " else "", val)?;
+ };
+
+ // Align ASCII representation, max width of hex part (48) +
+ // spacing around it
+ for (toff < 50; toff += 1) {
+ fmt::fprint(out, " ")?;
+ };
+
+ fmt::fprint(out, "|")?;
+ for (let i = 0z; i < 16 && off + i < datalen; i += 1) {
+ let r = data[off + i]: u32: rune;
+
+ fmt::fprint(out, if (ascii::isprint(r)) r else '.')?;
+ };
+ fmt::fprint(out, "|\n")?;
+ };
+};
+
+@test fn dump() void = {
+ let in: [_]u8 = [
+ 0x7F, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0xCA, 0xFE,
+ 0xBA, 0xBE, 0xDE, 0xAD, 0xF0, 0x0D, 0xCE, 0xFE, 0xBA, 0xBE,
+ 0xDE, 0xAD, 0xF0, 0x0D
+ ];
+
+ let sink = strio::dynamic();
+ dump(sink, in) as void;
+
+ let s = strio::finish(sink);
+ assert(s ==
+ "00000000 7f 45 4c 46 02 01 01 00 ca fe ba be de ad f0 0d |.ELF............|\n"
+ "00000010 ce fe ba be de ad f0 0d |........|\n");
+};
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -200,7 +200,7 @@ encoding_hex() {
printf '# encoding::hex\n'
gen_srcs encoding::hex \
hex.ha
- gen_ssa encoding::hex io strconv strio strings bytes
+ gen_ssa encoding::hex ascii bytes fmt io strconv strio strings
}
encoding_utf8() {
diff --git a/stdlib.mk b/stdlib.mk
@@ -295,7 +295,7 @@ $(HARECACHE)/dirs/dirs.ssa: $(stdlib_dirs_srcs) $(stdlib_rt) $(stdlib_fs) $(stdl
stdlib_encoding_hex_srcs= \
$(STDLIB)/encoding/hex/hex.ha
-$(HARECACHE)/encoding/hex/encoding_hex.ssa: $(stdlib_encoding_hex_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_strconv) $(stdlib_strio) $(stdlib_strings) $(stdlib_bytes)
+$(HARECACHE)/encoding/hex/encoding_hex.ssa: $(stdlib_encoding_hex_srcs) $(stdlib_rt) $(stdlib_ascii) $(stdlib_bytes) $(stdlib_fmt) $(stdlib_io) $(stdlib_strconv) $(stdlib_strio) $(stdlib_strings)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/encoding/hex
@HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::hex \
@@ -986,7 +986,7 @@ $(TESTCACHE)/dirs/dirs.ssa: $(testlib_dirs_srcs) $(testlib_rt) $(testlib_fs) $(t
testlib_encoding_hex_srcs= \
$(STDLIB)/encoding/hex/hex.ha
-$(TESTCACHE)/encoding/hex/encoding_hex.ssa: $(testlib_encoding_hex_srcs) $(testlib_rt) $(testlib_io) $(testlib_strconv) $(testlib_strio) $(testlib_strings) $(testlib_bytes)
+$(TESTCACHE)/encoding/hex/encoding_hex.ssa: $(testlib_encoding_hex_srcs) $(testlib_rt) $(testlib_ascii) $(testlib_bytes) $(testlib_fmt) $(testlib_io) $(testlib_strconv) $(testlib_strio) $(testlib_strings)
@printf 'HAREC \t$@\n'
@mkdir -p $(TESTCACHE)/encoding/hex
@HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nencoding::hex \