hexyl: add display offset option

This commit is contained in:
Tom Milligan authored and David Peter committed 2019-10-07 23:36:53 +02:00
1 parent 23f199ffbd
commit d64053771c
2 files changed
+61 -12

No files matched your search

+23 -7
View File
@@ -69,6 +69,14 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
.possible_values(&["unicode", "ascii", "none"])
.default_value("unicode")
.help("Whether to draw a border with unicode or ASCII characters, or none at all"),
)
.arg(
Arg::with_name("display_offset")
.short("o")
.long("display-offset")
.takes_value(true)
.value_name("OFFSET")
.help("Add OFFSET to the displayed file position."),
);
let matches = app.get_matches_safe()?;
@@ -82,13 +90,7 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
let length_arg = matches.value_of("length").or(matches.value_of("bytes"));
if let Some(length) = length_arg.and_then(|n| {
if n.starts_with("0x") {
u64::from_str_radix(n.trim_start_matches("0x"), 16).ok()
} else {
n.parse::<u64>().ok()
}
}) {
if let Some(length) = length_arg.and_then(parse_hex_or_int) {
reader = Box::new(reader.take(length));
}
@@ -106,6 +108,11 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
let squeeze = !matches.is_present("nosqueezing");
let display_offset = matches
.value_of("display_offset")
.and_then(parse_hex_or_int)
.unwrap_or(0);
// Set up Ctrl-C handler
let cancelled = Arc::new(AtomicBool::new(false));
let c = cancelled.clone();
@@ -119,6 +126,7 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
let mut stdout_lock = stdout.lock();
let mut printer = Printer::new(&mut stdout_lock, show_color, border_style, squeeze);
printer.display_offset(display_offset as usize);
printer.print_all(&mut reader, Some(cancelled))?;
Ok(())
@@ -148,3 +156,11 @@ fn main() {
std::process::exit(1);
}
}
fn parse_hex_or_int(n: &str) -> Option<u64> {
if n.starts_with("0x") {
u64::from_str_radix(n.trim_start_matches("0x"), 16).ok()
} else {
n.parse::<u64>().ok()
}
}
+38 -5
View File
@@ -155,6 +155,7 @@ pub struct Printer<'a, Writer: Write> {
byte_hex_table: Vec<String>,
byte_char_table: Vec<String>,
squeezer: Squeezer,
display_offset: usize,
}
impl<'a, Writer: Write> Printer<'a, Writer> {
@@ -193,9 +194,15 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
})
.collect(),
squeezer: Squeezer::new(use_squeeze),
display_offset: 0,
}
}
pub fn display_offset(&mut self, display_offset: usize) -> &mut Self {
self.display_offset = display_offset;
self
}
pub fn header(&mut self) {
if let Some(border_elements) = self.border_style.header_elems() {
let h = border_elements.horizontal_line;
@@ -241,7 +248,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
}
let style = COLOR_OFFSET.normal();
let byte_index = format!("{:08x}", self.idx - 1);
let byte_index = format!("{:08x}", (self.idx - 1) + self.display_offset);
let formatted_string = if self.show_color {
format!("{}", style.paint(byte_index))
} else {
@@ -456,19 +463,45 @@ mod tests {
#[test]
fn empty_file_passes() {
let input = io::empty();
let expected_string = "┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
let expected_string =
"┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘
".to_owned();
"
.to_owned();
assert_print_all_output(input, expected_string);
}
#[test]
fn short_input_passes() {
let input = io::Cursor::new(b"spam");
let expected_string = "┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
let expected_string =
"┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 73 70 61 6d ┊ │spam ┊ │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘
".to_owned();
"
.to_owned();
assert_print_all_output(input, expected_string);
}
#[test]
fn display_offset() {
let input = io::Cursor::new(b"spamspamspamspamspam");
let expected_string =
"┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│deadbeef│ 73 70 61 6d 73 70 61 6d ┊ 73 70 61 6d 73 70 61 6d │spamspam┊spamspam│
│deadbeff│ 73 70 61 6d ┊ │spam ┊ │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘
"
.to_owned();
let mut output = vec![];
let mut printer: Printer<Vec<u8>> =
Printer::new(&mut output, false, BorderStyle::Unicode, true);
printer.display_offset(0xdeadbeef);
printer.print_all(input, None).unwrap();
let actual_string: &str = str::from_utf8(&output).unwrap();
assert_eq!(actual_string, expected_string)
}
}