feat: add block unit and block-size option

This commit is contained in:
Erich Gubler authored and David Peter committed 2020-05-28 18:43:53 +02:00
1 parent 48ad95efe6
commit bcca1fae03
1 file changed
+37 -6
+37 -6
View File
@@ -43,6 +43,16 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
.value_name("N") .value_name("N")
.help("Skip first N bytes"), .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(
Arg::with_name("nosqueezing") Arg::with_name("nosqueezing")
.short("v") .short("v")
@@ -91,7 +101,14 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
None => Input::Stdin(stdin.lock()), 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::<u64>().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 { if let Some(skip) = skip_arg {
reader.seek(SeekFrom::Start(skip))?; reader.seek(SeekFrom::Start(skip))?;
@@ -101,7 +118,8 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
.value_of("length") .value_of("length")
.or_else(|| matches.value_of("bytes")); .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)) Box::new(reader.take(length))
} else { } else {
reader.into_inner() reader.into_inner()
@@ -123,7 +141,7 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
let display_offset = matches let display_offset = matches
.value_of("display_offset") .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)); .unwrap_or_else(|| skip_arg.unwrap_or(0));
let stdout = io::stdout(); let stdout = io::stdout();
@@ -161,7 +179,7 @@ fn main() {
} }
} }
fn parse_byte_count(n: &str) -> Option<u64> { fn parse_byte_count(n: &str, block_size: u64) -> Option<u64> {
const HEX_PREFIX: &'static str = "0x"; const HEX_PREFIX: &'static str = "0x";
let n = { let n = {
@@ -196,6 +214,7 @@ fn parse_byte_count(n: &str) -> Option<u64> {
("mib", 1024u64.pow(2)), ("mib", 1024u64.pow(2)),
("gib", 1024u64.pow(3)), ("gib", 1024u64.pow(3)),
("tib", 1024u64.pow(4)), ("tib", 1024u64.pow(4)),
("block", block_size),
] ]
.iter() .iter()
.cloned() .cloned()
@@ -218,13 +237,16 @@ fn parse_byte_count(n: &str) -> Option<u64> {
fn test_parse_byte_count() { fn test_parse_byte_count() {
macro_rules! success { macro_rules! success {
($input: expr, $expected: expr) => { ($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 { macro_rules! error {
($input: expr) => { ($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!("0xEE", 238);
success!("+0xFF", 255); success!("+0xFF", 255);
success!("1block", 512, 512);
success!("2block", 512, 1024);
success!("1block", 4, 4);
success!("2block", 4, 8);
// empty string is invalid // empty string is invalid
error!(""); error!("");
// These are also bad. // These are also bad.
error!("+"); error!("+");
error!("-"); error!("-");
error!("K");
error!("k");
error!("m");
error!("block");
// leading/trailing space is invalid // leading/trailing space is invalid
error!(" 0"); error!(" 0");
error!("0 "); error!("0 ");