From bcca1fae03293a3b0d2a5675b6814094d6b4a09e Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 20 May 2020 09:35:43 -0600 Subject: [PATCH] feat: add `block` unit and `block-size` option --- src/bin/hexyl.rs | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/src/bin/hexyl.rs b/src/bin/hexyl.rs index 7170081..82797a4 100644 --- a/src/bin/hexyl.rs +++ b/src/bin/hexyl.rs @@ -43,6 +43,16 @@ fn run() -> Result<(), Box> { .value_name("N") .help("Skip first N bytes"), ) + .arg( + Arg::with_name("block_size") + .long("block-size") + .takes_value(true) + .value_name("SIZE") + .help( + "Sets the size of the `block` unit to SIZE. Examples: \ + --block-size=1024, --block-size=4kB", + ), + ) .arg( Arg::with_name("nosqueezing") .short("v") @@ -91,7 +101,14 @@ fn run() -> Result<(), Box> { None => Input::Stdin(stdin.lock()), }; - let skip_arg = matches.value_of("skip").and_then(parse_byte_count); + let block_size = matches + .value_of("block_size") + .and_then(|bs| bs.parse::().ok()) + .unwrap_or(512); + + let skip_arg = matches + .value_of("skip") + .and_then(|s| parse_byte_count(s, block_size)); if let Some(skip) = skip_arg { reader.seek(SeekFrom::Start(skip))?; @@ -101,7 +118,8 @@ fn run() -> Result<(), Box> { .value_of("length") .or_else(|| matches.value_of("bytes")); - let mut reader = if let Some(length) = length_arg.and_then(parse_byte_count) { + let mut reader = if let Some(length) = length_arg.and_then(|s| parse_byte_count(s, block_size)) + { Box::new(reader.take(length)) } else { reader.into_inner() @@ -123,7 +141,7 @@ fn run() -> Result<(), Box> { let display_offset = matches .value_of("display_offset") - .and_then(parse_byte_count) + .and_then(|s| parse_byte_count(s, block_size)) .unwrap_or_else(|| skip_arg.unwrap_or(0)); let stdout = io::stdout(); @@ -161,7 +179,7 @@ fn main() { } } -fn parse_byte_count(n: &str) -> Option { +fn parse_byte_count(n: &str, block_size: u64) -> Option { const HEX_PREFIX: &'static str = "0x"; let n = { @@ -196,6 +214,7 @@ fn parse_byte_count(n: &str) -> Option { ("mib", 1024u64.pow(2)), ("gib", 1024u64.pow(3)), ("tib", 1024u64.pow(4)), + ("block", block_size), ] .iter() .cloned() @@ -218,13 +237,16 @@ fn parse_byte_count(n: &str) -> Option { fn test_parse_byte_count() { macro_rules! success { ($input: expr, $expected: expr) => { - assert_eq!(parse_byte_count($input), Some($expected)); + success!($input, 512, $expected) + }; + ($input: expr, $block_size: expr, $expected: expr) => { + assert_eq!(parse_byte_count($input, $block_size), Some($expected)); }; } macro_rules! error { ($input: expr) => { - assert_eq!(parse_byte_count($input), None); + assert_eq!(parse_byte_count($input, 512), None); }; } @@ -248,11 +270,20 @@ fn test_parse_byte_count() { success!("0xEE", 238); success!("+0xFF", 255); + success!("1block", 512, 512); + success!("2block", 512, 1024); + success!("1block", 4, 4); + success!("2block", 4, 8); + // empty string is invalid error!(""); // These are also bad. error!("+"); error!("-"); + error!("K"); + error!("k"); + error!("m"); + error!("block"); // leading/trailing space is invalid error!(" 0"); error!("0 ");