Adds --columns for Print using custom width #13

This commit is contained in:
Sharif Haason authored and David Peter committed 2022-09-11 21:45:06 +02:00
1 parent 55cf7b034c
commit b9348ffb1d
4 files changed
+114 -93

No files matched your search

+2
View File
@@ -16,6 +16,7 @@ fn main() {
let show_position_panel = true; let show_position_panel = true;
let use_squeezing = false; let use_squeezing = false;
let border_style = BorderStyle::Unicode; let border_style = BorderStyle::Unicode;
let columns = 2;
let mut printer = Printer::new( let mut printer = Printer::new(
&mut handle, &mut handle,
@@ -24,6 +25,7 @@ fn main() {
show_position_panel, show_position_panel,
border_style, border_style,
use_squeezing, use_squeezing,
columns,
); );
printer.print_all(&input[..]).unwrap(); printer.print_all(&input[..]).unwrap();
} }
+24 -1
View File
@@ -4,7 +4,7 @@ extern crate clap;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fs::File; use std::fs::File;
use std::io::{self, prelude::*, SeekFrom}; use std::io::{self, prelude::*, SeekFrom};
use std::num::NonZeroI64; use std::num::{NonZeroI64, NonZeroU8};
use clap::{crate_name, crate_version, AppSettings, Arg, ColorChoice, Command}; use clap::{crate_name, crate_version, AppSettings, Arg, ColorChoice, Command};
@@ -149,6 +149,17 @@ fn run() -> Result<(), AnyhowError> {
A negative value is valid and calculates an offset relative to the \ A negative value is valid and calculates an offset relative to the \
end of the file.", end of the file.",
), ),
)
.arg(
Arg::new("columns")
.short('w')
.long("columns")
.takes_value(true)
.value_name("N")
.help(
"Sets the number of hex data columns to be displayed. \
Cannot be used with other width-setting options.",
),
); );
let matches = command.get_matches(); let matches = command.get_matches();
@@ -267,6 +278,17 @@ fn run() -> Result<(), AnyhowError> {
.transpose()? .transpose()?
.unwrap_or(0); .unwrap_or(0);
let columns = matches
.value_of("columns")
.map(|s| {
s.parse::<NonZeroU8>().map(u8::from).context(anyhow!(
"failed to parse `--columns` arg {:?} as unsigned nonzero integer",
s
))
})
.transpose()?
.unwrap_or(2);
let stdout = io::stdout(); let stdout = io::stdout();
let mut stdout_lock = stdout.lock(); let mut stdout_lock = stdout.lock();
@@ -277,6 +299,7 @@ fn run() -> Result<(), AnyhowError> {
show_position_panel, show_position_panel,
border_style, border_style,
squeeze, squeeze,
columns,
); );
printer.display_offset(skip_offset + display_offset); printer.display_offset(skip_offset + display_offset);
printer.print_all(&mut reader).map_err(|e| anyhow!(e))?; printer.print_all(&mut reader).map_err(|e| anyhow!(e))?;
+71 -75
View File
@@ -154,6 +154,8 @@ pub struct Printer<'a, Writer: Write> {
byte_char_panel: Vec<String>, byte_char_panel: Vec<String>,
squeezer: Squeezer, squeezer: Squeezer,
display_offset: u64, display_offset: u64,
/// The number of panels to draw.
columns: u8,
} }
impl<'a, Writer: Write> Printer<'a, Writer> { impl<'a, Writer: Write> Printer<'a, Writer> {
@@ -164,6 +166,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
show_position_panel: bool, show_position_panel: bool,
border_style: BorderStyle, border_style: BorderStyle,
use_squeeze: bool, use_squeeze: bool,
columns: u8,
) -> Printer<'a, Writer> { ) -> Printer<'a, Writer> {
Printer { Printer {
idx: 1, idx: 1,
@@ -175,7 +178,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
show_position_panel, show_position_panel,
border_style, border_style,
header_was_printed: false, header_was_printed: false,
byte_hex_panel: (0u8..=u8::max_value()) byte_hex_panel: (0u8..=u8::MAX)
.map(|i| { .map(|i| {
let byte_hex = format!("{:02x} ", i); let byte_hex = format!("{:02x} ", i);
if show_color { if show_color {
@@ -187,7 +190,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
.collect(), .collect(),
byte_char_panel: show_char_panel byte_char_panel: show_char_panel
.then(|| { .then(|| {
(0u8..=u8::max_value()) (0u8..=u8::MAX)
.map(|i| { .map(|i| {
let byte_char = format!("{}", Byte(i).as_char()); let byte_char = format!("{}", Byte(i).as_char());
if show_color { if show_color {
@@ -199,8 +202,9 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
.collect() .collect()
}) })
.unwrap_or_default(), .unwrap_or_default(),
squeezer: Squeezer::new(use_squeeze), squeezer: Squeezer::new(use_squeeze, 8 * columns as u64),
display_offset: 0, display_offset: 0,
columns,
} }
} }
@@ -223,10 +227,20 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
write!(self.writer, "{}", l).ok(); write!(self.writer, "{}", l).ok();
} }
write!(self.writer, "{h25}{c}{h25}", c = c, h25 = h25).ok(); for _ in 0..self.columns - 1 {
write!(self.writer, "{h25}{c}", h25 = h25, c = c).ok();
}
if self.show_char_panel {
write!(self.writer, "{h25}{c}", h25 = h25, c = c).ok();
} else {
write!(self.writer, "{h25}", h25 = h25).ok();
}
if self.show_char_panel { if self.show_char_panel {
writeln!(self.writer, "{c}{h8}{c}{h8}{r}", c = c, h8 = h8, r = r).ok(); for _ in 0..self.columns - 1 {
write!(self.writer, "{h8}{c}", h8 = h8, c = c).ok();
}
writeln!(self.writer, "{h8}{r}", h8 = h8, r = r).ok();
} else { } else {
writeln!(self.writer, "{r}", r = r).ok(); writeln!(self.writer, "{r}", r = r).ok();
} }
@@ -287,36 +301,25 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
self.byte_char_panel[b as usize] self.byte_char_panel[b as usize]
); );
if idx == 8 { if idx % 8 == 0 && idx % (u64::from(self.columns * 8)) != 0 {
let _ = write!(&mut self.buffer_line, "{}", self.border_style.inner_sep()); let _ = write!(&mut self.buffer_line, "{}", self.border_style.inner_sep());
} }
idx += 1; idx += 1;
} }
if len < 8 { if len < usize::from(8 * self.columns) {
let _ = writeln!( let _ = write!(&mut self.buffer_line, "{0:1$}", "", 8 - len % 8);
&mut self.buffer_line, for _ in 0..(usize::from(8 * self.columns) - (len + (8 - len % 8))) / 8 {
"{0:1$}{3}{0:2$}{4}", let _ = write!(&mut self.buffer_line, "{2}{0:1$}", "", 8, self.border_style.inner_sep());
"", }
8 - len,
8,
self.border_style.inner_sep(),
self.border_style.outer_sep(),
);
} else {
let _ = writeln!(
&mut self.buffer_line,
"{0:1$}{2}",
"",
16 - len,
self.border_style.outer_sep()
);
} }
let _ = writeln!(&mut self.buffer_line, "{}", self.border_style.outer_sep());
} }
pub fn print_byte(&mut self, b: u8) -> io::Result<()> { pub fn print_byte(&mut self, b: u8) -> io::Result<()> {
if self.idx % 16 == 1 { if self.idx % u64::from(self.columns * 8) == 1 {
self.print_header(); self.print_header();
self.print_position_panel(); self.print_position_panel();
} }
@@ -326,14 +329,10 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
self.squeezer.process(b, self.idx); self.squeezer.process(b, self.idx);
match self.idx % 16 { if self.idx % u64::from(self.columns * 8) == 0 {
8 => { self.print_textline()?;
let _ = write!(&mut self.buffer_line, "{} ", self.border_style.inner_sep()); } else if self.idx % 8 == 0 {
} let _ = write!(&mut self.buffer_line, "{} ", self.border_style.inner_sep());
0 => {
self.print_textline()?;
}
_ => {}
} }
self.idx += 1; self.idx += 1;
@@ -347,16 +346,15 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
if len == 0 { if len == 0 {
if self.squeezer.active() { if self.squeezer.active() {
self.print_position_panel(); self.print_position_panel();
let _ = writeln!( write!(&mut self.buffer_line, "{0:1$}", "", 24)?;
&mut self.buffer_line, for _ in 0..self.columns - 1 {
"{0:1$}{4}{0:2$}{5}{0:3$}{4}{0:3$}{5}", write!(&mut self.buffer_line, "{2}{0:1$}", "", 25, self.border_style.inner_sep())?;
"", }
24, write!(&mut self.buffer_line, "{2}{0:1$}", "", 8, self.border_style.outer_sep())?;
25, for _ in 0..self.columns - 1 {
8, write!(&mut self.buffer_line, "{2}{0:1$}", "", 8, self.border_style.inner_sep())?;
self.border_style.inner_sep(), }
self.border_style.outer_sep(), writeln!(&mut self.buffer_line, "{}", self.border_style.outer_sep())?;
);
self.writer.write_all(&self.buffer_line)?; self.writer.write_all(&self.buffer_line)?;
} }
return Ok(()); return Ok(());
@@ -364,28 +362,17 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
let squeeze_action = self.squeezer.action(); let squeeze_action = self.squeezer.action();
// print empty space on last line
if squeeze_action != SqueezeAction::Delete { if squeeze_action != SqueezeAction::Delete {
if len < 8 { if len < usize::from(8 * self.columns) {
let _ = write!( write!(&mut self.buffer_line, "{0:1$}", "", 3 * (8 - len % 8))?;
&mut self.buffer_line, // dbg!(usize::from(8 * self.columns) - (len + (8 - len % 8)));
"{0:1$}{3}{0:2$}{4}", for _ in 0..(usize::from(8 * self.columns) - (len + (8 - len % 8))) / 8 {
"", write!(&mut self.buffer_line, "{2}{0:1$}", "", 1 + 3 * 8, self.border_style.inner_sep())?;
3 * (8 - len), }
1 + 3 * 8,
self.border_style.inner_sep(),
self.border_style.outer_sep(),
);
} else {
let _ = write!(
&mut self.buffer_line,
"{0:1$}{2}",
"",
3 * (16 - len),
self.border_style.outer_sep()
);
} }
write!(&mut self.buffer_line, "{}", self.border_style.outer_sep())?;
} }
self.print_char_panel(); self.print_char_panel();
match squeeze_action { match squeeze_action {
@@ -397,17 +384,26 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
} else { } else {
String::from("*") String::from("*")
}; };
let _ = writeln!(
&mut self.buffer_line, write!(&mut self.buffer_line, "{3}{0}{1:2$}{3}", asterisk, "", 7, self.border_style.outer_sep())?;
"{5}{0}{1:2$}{5}{1:3$}{6}{1:3$}{5}{1:4$}{6}{1:4$}{5}",
asterisk, for i in 0..self.columns {
"", write!(&mut self.buffer_line, "{0:1$}", "", 25)?;
7, if i != self.columns - 1 {
25, write!(&mut self.buffer_line, "{}", self.border_style.inner_sep())?;
8, } else {
self.border_style.outer_sep(), write!(&mut self.buffer_line, "{}", self.border_style.outer_sep())?;
self.border_style.inner_sep(), }
); }
for i in 0..self.columns {
write!(&mut self.buffer_line, "{0:1$}", "", 8)?;
if i != self.columns - 1 {
write!(&mut self.buffer_line, "{}", self.border_style.inner_sep())?;
} else {
writeln!(&mut self.buffer_line, "{}", self.border_style.outer_sep())?;
}
}
} }
SqueezeAction::Delete => self.buffer_line.clear(), SqueezeAction::Delete => self.buffer_line.clear(),
SqueezeAction::Ignore => (), SqueezeAction::Ignore => (),
@@ -484,7 +480,7 @@ mod tests {
fn assert_print_all_output<Reader: Read>(input: Reader, expected_string: String) { fn assert_print_all_output<Reader: Read>(input: Reader, expected_string: String) {
let mut output = vec![]; let mut output = vec![];
let mut printer = Printer::new(&mut output, false, true, true, BorderStyle::Unicode, true); let mut printer = Printer::new(&mut output, false, true, true, BorderStyle::Unicode, true, 2);
printer.print_all(input).unwrap(); printer.print_all(input).unwrap();
@@ -529,7 +525,7 @@ mod tests {
let mut output = vec![]; let mut output = vec![];
let mut printer: Printer<Vec<u8>> = let mut printer: Printer<Vec<u8>> =
Printer::new(&mut output, false, true, true, BorderStyle::Unicode, true); Printer::new(&mut output, false, true, true, BorderStyle::Unicode, true, 2);
printer.display_offset(0xdeadbeef); printer.display_offset(0xdeadbeef);
printer.print_all(input).unwrap(); printer.print_all(input).unwrap();
+17 -17
View File
@@ -22,6 +22,7 @@ enum SqueezeState {
pub struct Squeezer { pub struct Squeezer {
state: SqueezeState, state: SqueezeState,
byte: u8, byte: u8,
lsize: u64,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@@ -31,11 +32,8 @@ pub enum SqueezeAction {
Delete, Delete,
} }
/// line size
const LSIZE: u64 = 16;
impl Squeezer { impl Squeezer {
pub fn new(enabled: bool) -> Squeezer { pub fn new(enabled: bool, lsize: u64) -> Squeezer {
Squeezer { Squeezer {
state: if enabled { state: if enabled {
SqueezeState::Probe SqueezeState::Probe
@@ -43,6 +41,7 @@ impl Squeezer {
SqueezeState::Disabled SqueezeState::Disabled
}, },
byte: 0, byte: 0,
lsize,
} }
} }
@@ -53,7 +52,7 @@ impl Squeezer {
} }
let eq = b == self.byte; let eq = b == self.byte;
if i % LSIZE == 0 { if i % self.lsize == 0 {
if !eq { if !eq {
self.state = Probe; self.state = Probe;
} else { } else {
@@ -68,9 +67,9 @@ impl Squeezer {
}; };
} }
} else if !eq { } else if !eq {
if i % LSIZE == 1 { if i % self.lsize == 1 {
self.state = Probe; self.state = Probe;
} else if i % LSIZE != 1 { } else if i % self.lsize != 1 {
self.state = NoSqueeze; self.state = NoSqueeze;
} }
} }
@@ -111,13 +110,14 @@ impl Squeezer {
mod tests { mod tests {
use super::*; use super::*;
const LSIZE_USIZE: usize = LSIZE as usize; const LSIZE: u64 = 16;
const LSIZE_USIZE: usize = 16;
#[test] #[test]
fn three_same_lines() { fn three_same_lines() {
const LINES: usize = 3; const LINES: usize = 3;
let v = vec![0u8; LINES * LSIZE_USIZE]; let v = vec![0u8; LINES * LSIZE_USIZE];
let mut s = Squeezer::new(true); let mut s = Squeezer::new(true, LSIZE);
// just initialized // just initialized
assert_eq!(s.action(), SqueezeAction::Ignore); assert_eq!(s.action(), SqueezeAction::Ignore);
s.advance(); s.advance();
@@ -144,7 +144,7 @@ mod tests {
fn incomplete_while_squeeze() { fn incomplete_while_squeeze() {
// fourth line only has 12 bytes and should be printed // fourth line only has 12 bytes and should be printed
let v = vec![0u8; 3 * LSIZE_USIZE + 12]; let v = vec![0u8; 3 * LSIZE_USIZE + 12];
let mut s = Squeezer::new(true); let mut s = Squeezer::new(true, LSIZE);
// just initialized // just initialized
assert_eq!(s.action(), SqueezeAction::Ignore); assert_eq!(s.action(), SqueezeAction::Ignore);
s.advance(); s.advance();
@@ -175,7 +175,7 @@ mod tests {
v.extend(vec![1u8; 16]); v.extend(vec![1u8; 16]);
v.extend(vec![2u8; 16]); v.extend(vec![2u8; 16]);
let mut s = Squeezer::new(true); let mut s = Squeezer::new(true, LSIZE);
// just initialized // just initialized
assert_eq!(s.action(), SqueezeAction::Ignore); assert_eq!(s.action(), SqueezeAction::Ignore);
s.advance(); s.advance();
@@ -206,7 +206,7 @@ mod tests {
let mut v = vec![0u8; (LINES - 1) * LSIZE_USIZE]; let mut v = vec![0u8; (LINES - 1) * LSIZE_USIZE];
v.extend(vec![1u8; 16]); v.extend(vec![1u8; 16]);
let mut s = Squeezer::new(true); let mut s = Squeezer::new(true, LSIZE);
// just initialized // just initialized
assert_eq!(s.action(), SqueezeAction::Ignore); assert_eq!(s.action(), SqueezeAction::Ignore);
s.advance(); s.advance();
@@ -237,7 +237,7 @@ mod tests {
v.extend(vec![0u8; 8]); v.extend(vec![0u8; 8]);
v.extend(vec![1u8; 8]); v.extend(vec![1u8; 8]);
let mut s = Squeezer::new(true); let mut s = Squeezer::new(true, LSIZE);
// just initialized // just initialized
assert_eq!(s.action(), SqueezeAction::Ignore); assert_eq!(s.action(), SqueezeAction::Ignore);
s.advance(); s.advance();
@@ -270,7 +270,7 @@ mod tests {
v.extend(vec![0u8; 8]); v.extend(vec![0u8; 8]);
v.extend(vec![1u8; 8]); v.extend(vec![1u8; 8]);
let mut s = Squeezer::new(true); let mut s = Squeezer::new(true, LSIZE);
// just initialized // just initialized
assert_eq!(s.action(), SqueezeAction::Ignore); assert_eq!(s.action(), SqueezeAction::Ignore);
s.advance(); s.advance();
@@ -309,7 +309,7 @@ mod tests {
v.extend(vec![20u8; 16]); // print v.extend(vec![20u8; 16]); // print
v.extend(vec![0u8; 12]); // print, only 12 bytes v.extend(vec![0u8; 12]); // print, only 12 bytes
let mut s = Squeezer::new(true); let mut s = Squeezer::new(true, LSIZE);
// just initialized // just initialized
assert_eq!(s.action(), SqueezeAction::Ignore); assert_eq!(s.action(), SqueezeAction::Ignore);
s.advance(); s.advance();
@@ -351,7 +351,7 @@ mod tests {
v.extend(vec![20u8; 16]); v.extend(vec![20u8; 16]);
v.extend(vec![20u8; 16]); v.extend(vec![20u8; 16]);
let mut s = Squeezer::new(true); let mut s = Squeezer::new(true, LSIZE);
// just initialized // just initialized
assert_eq!(s.action(), SqueezeAction::Ignore); assert_eq!(s.action(), SqueezeAction::Ignore);
s.advance(); s.advance();
@@ -383,7 +383,7 @@ mod tests {
v.extend(vec![20u8; 15]); v.extend(vec![20u8; 15]);
v.extend(vec![20u8; 16]); v.extend(vec![20u8; 16]);
let mut s = Squeezer::new(true); let mut s = Squeezer::new(true, LSIZE);
// just initialized // just initialized
assert_eq!(s.action(), SqueezeAction::Ignore); assert_eq!(s.action(), SqueezeAction::Ignore);
s.advance(); s.advance();