Obsolete
/
libipc-old
Archived
3
0
Fork 0

Hexdump: complete rewrite, fixes all known problems.

master
Philippe Pittoli 2023-01-19 02:58:31 +01:00
parent 0feb31b4c7
commit b2bf66c436
1 changed files with 94 additions and 30 deletions

View File

@ -2,8 +2,7 @@ const std = @import("std");
const print = std.debug.print; const print = std.debug.print;
pub fn hexdump(stream: anytype, header: [] const u8, buffer: [] const u8) std.os.WriteError!void { pub fn hexdump(stream: anytype, header: [] const u8, buffer: [] const u8) std.os.WriteError!void {
try stream.writeAll("\n"); // Print a header.
if (header.len > 0) { if (header.len > 0) {
var hdr: [64] u8 = undefined; var hdr: [64] u8 = undefined;
var offset: usize = (hdr.len / 2) - ((header.len / 2) - 1); var offset: usize = (hdr.len / 2) - ((header.len / 2) - 1);
@ -17,52 +16,117 @@ pub fn hexdump(stream: anytype, header: [] const u8, buffer: [] const u8) std.os
var hexb: u32 = 0; var hexb: u32 = 0;
var ascii: [16] u8 = undefined; var ascii: [16] u8 = undefined;
// First line, first left side (simple number).
try stream.print("\n {d:0>4}: ", .{ hexb }); try stream.print("\n {d:0>4}: ", .{ hexb });
// Loop on all values in the buffer (i from 0 to buffer.len).
var i: u32 = 0; var i: u32 = 0;
while (i < buffer.len) : (i += 1) { while (i < buffer.len) : (i += 1) {
// Print actual hexadecimal value.
try stream.print("{X:0>2} ", .{ buffer[i] }); try stream.print("{X:0>2} ", .{ buffer[i] });
// What to print (simple ascii text, right side).
if (buffer[i] >= ' ' and buffer[i] <= '~') { if (buffer[i] >= ' ' and buffer[i] <= '~') {
ascii[(i % 16)] = buffer[i]; ascii[(i % 16)] = buffer[i];
} else { } else {
ascii[(i % 16)] = '.'; ascii[(i % 16)] = '.';
} }
if ((i + 1) % 8 == 0 or (i + 1) == buffer.len) { // Next input is a multiple of 8 = extra space.
if ((i + 1) % 8 == 0) {
try stream.writeAll(" "); try stream.writeAll(" ");
}
if ((i + 1) % 16 == 0) { // No next input: print the right amount of spaces.
hexb += 16; if ((i + 1) == buffer.len) {
// Each line is 16 bytes to print, each byte takes 3 characters.
if ((i + 1) != buffer.len) { var missing_spaces = 3 * (15 - (i%16));
try stream.print("{s}\n {d:0>4}: ", .{ ascii[0..ascii.len], hexb }); // Missing an extra space if the current index % 16 is less than 7.
} else { if ((i%16) < 7) { missing_spaces += 1; }
try stream.print("{s}\n", .{ ascii[0..ascii.len] }); while (missing_spaces > 0) : (missing_spaces -= 1) {
} try stream.writeAll(" ");
} else if ((i + 1) == buffer.len) {
var x: u32 = (i + 1) % 16;
while (x < 16) : (x += 1) {
try stream.writeAll(" ");
}
try stream.print(" {s}\n", .{ ascii[0..((i+1) % 16)] });
} }
} }
// Every 16 bytes: print ascii text and line return.
// Case 1: it's been 16 bytes AND it's the last byte to print.
if ((i + 1) % 16 == 0 and (i + 1) == buffer.len) {
try stream.print("{s}\n", .{ ascii[0..ascii.len] });
}
// Case 2: it's been 16 bytes but it's not the end of the buffer.
else if ((i + 1) % 16 == 0 and (i + 1) != buffer.len) {
try stream.print("{s}\n", .{ ascii[0..ascii.len] });
hexb += 16;
try stream.print(" {d:0>4}: ", .{ hexb });
}
// Case 3: not the end of the 16 bytes row but it's the end of the buffer.
else if ((i + 1) % 16 != 0 and (i + 1) == buffer.len) {
try stream.print(" {s}\n", .{ ascii[0..((i+1) % 16)] });
}
// Case 4: not the end of the 16 bytes row and not the end of the buffer.
// Do nothing.
} }
try stream.writeAll("\n"); try stream.writeAll("\n");
} }
// test "simple hexdump test" { test "36-byte hexdump test" {
// print("\n\nPrint hexdump, NO AUTOMATIC VERIFICATION, READ SOURCE CODE\n\n", .{}); print("\nPrint hexdump, NO AUTOMATIC VERIFICATION, READ SOURCE CODE\n", .{});
//
// var buffer = "hello this is a simple text to print"; var buffer = "hello this is a simple text to print";
// var hexbuf: [2000]u8 = undefined; var hexbuf: [2000]u8 = undefined;
// var hexfbs = std.io.fixedBufferStream(&hexbuf); var hexfbs = std.io.fixedBufferStream(&hexbuf);
// var hexwriter = hexfbs.writer(); var hexwriter = hexfbs.writer();
// try hexdump(hexwriter, "Hello World", buffer); try hexdump(hexwriter, "Hello World", buffer);
// print("{s}\n", .{hexfbs.getWritten()}); print("{s}\n", .{hexfbs.getWritten()});
//
// } }
test "32-byte hexdump test" {
print("\nPrint hexdump, NO AUTOMATIC VERIFICATION, READ SOURCE CODE\n", .{});
var buffer = "THIS IS THE END, MY ONLY... END";
var hexbuf: [2000]u8 = undefined;
var hexfbs = std.io.fixedBufferStream(&hexbuf);
var hexwriter = hexfbs.writer();
try hexdump(hexwriter, "Hello World", buffer);
print("{s}\n", .{hexfbs.getWritten()});
}
test "26-byte hexdump test" {
print("\nPrint hexdump, NO AUTOMATIC VERIFICATION, READ SOURCE CODE\n", .{});
var buffer = "hello this is another text";
var hexbuf: [2000]u8 = undefined;
var hexfbs = std.io.fixedBufferStream(&hexbuf);
var hexwriter = hexfbs.writer();
try hexdump(hexwriter, "Hello World", buffer);
print("{s}\n", .{hexfbs.getWritten()});
}
test "1-byte hexdump test" {
print("\nPrint hexdump, NO AUTOMATIC VERIFICATION, READ SOURCE CODE\n", .{});
var buffer = "h";
var hexbuf: [2000]u8 = undefined;
var hexfbs = std.io.fixedBufferStream(&hexbuf);
var hexwriter = hexfbs.writer();
try hexdump(hexwriter, "Hello World", buffer);
print("{s}\n", .{hexfbs.getWritten()});
}
test "0-byte hexdump test" {
print("\nPrint hexdump, NO AUTOMATIC VERIFICATION, READ SOURCE CODE\n", .{});
var buffer = "";
var hexbuf: [2000]u8 = undefined;
var hexfbs = std.io.fixedBufferStream(&hexbuf);
var hexwriter = hexfbs.writer();
try hexdump(hexwriter, "Hello World", buffer);
print("{s}\n", .{hexfbs.getWritten()});
}