From 156865b3829261239915ac0bdfb5d1139fc9b2e0 Mon Sep 17 00:00:00 2001 From: Sharif Haason Date: Thu, 22 Jun 2023 11:55:51 -0400 Subject: [PATCH 1/6] Add fallback case for squeezing all identical lines --- src/lib.rs | 58 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2edae33..061cb74 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,7 +36,7 @@ pub enum Endianness { Big, } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] enum Squeezer { Print, Delete, @@ -281,7 +281,8 @@ pub struct Printer<'a, Writer: Write> { display_offset: u64, /// The number of panels to draw. panels: u64, - squeeze_byte: usize, + squeeze_byte: Option, + squeeze_line: Vec, /// The number of octets per group. group_size: u8, /// The number of digits used to write the base. @@ -332,7 +333,8 @@ impl<'a, Writer: Write> Printer<'a, Writer> { }, display_offset: 0, panels, - squeeze_byte: 0x00, + squeeze_byte: None, + squeeze_line: vec![0; 8 * panels as usize], group_size, base_digits: match base { Base::Binary => 8, @@ -632,19 +634,38 @@ impl<'a, Writer: Write> Printer<'a, Writer> { self.print_header()?; } + // write!(self.writer, "{:?}", self.squeezer)?; + //write!(self.writer, "{:?}", self.squeeze_line)?; + // write!( + // self.writer, + // "{:#X} {:#X}", + // self.squeeze_line[0], self.line_buf[0] + // )?; + // squeeze is active, check if the line is the same // skip print if still squeezed, otherwise print and deactivate squeeze if matches!(self.squeezer, Squeezer::Print | Squeezer::Delete) { - if self - .line_buf - .chunks_exact(std::mem::size_of::()) - .all(|w| usize::from_ne_bytes(w.try_into().unwrap()) == self.squeeze_byte) - { + if let Some(byte) = self.squeeze_byte { + if self + .line_buf + .chunks_exact(std::mem::size_of::()) + .all(|w| usize::from_ne_bytes(w.try_into().unwrap()) == byte) + { + if self.squeezer == Squeezer::Delete { + self.idx += 8 * self.panels; + continue; + } + } else { + self.squeeze_byte = None; + self.squeezer = Squeezer::Ignore; + } + } else if self.line_buf == self.squeeze_line { if self.squeezer == Squeezer::Delete { self.idx += 8 * self.panels; continue; } } else { + write!(self.writer, "self")?; self.squeezer = Squeezer::Ignore; } } @@ -673,15 +694,24 @@ impl<'a, Writer: Write> Printer<'a, Writer> { // repeat the first byte in the line until it's a usize // compare that usize with each usize chunk in the line // if they are all the same, change squeezer to print - let repeat_byte = (self.line_buf[0] as usize) * (usize::MAX / 255); - if !matches!(self.squeezer, Squeezer::Disabled | Squeezer::Delete) - && self + let repeat_byte = usize::from_ne_bytes( + self.line_buf[0..std::mem::size_of::()] + .try_into() + .unwrap(), + ); + if !matches!(self.squeezer, Squeezer::Disabled | Squeezer::Delete) { + if self .line_buf .chunks_exact(std::mem::size_of::()) .all(|w| usize::from_ne_bytes(w.try_into().unwrap()) == repeat_byte) - { - self.squeezer = Squeezer::Print; - self.squeeze_byte = repeat_byte; + { + self.squeezer = Squeezer::Print; + self.squeeze_byte = Some(repeat_byte); + } else if self.line_buf == self.squeeze_line { + self.squeezer = Squeezer::Print; + } else { + self.squeeze_line = self.line_buf.clone(); + } }; }; From a25d5be35bbc42764fa5b1487a8cde4ed6f8bd11 Mon Sep 17 00:00:00 2001 From: Sharif Haason Date: Mon, 21 Aug 2023 17:10:10 -0400 Subject: [PATCH 2/6] Clarify docs --- src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 061cb74..0e7fbf0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -691,9 +691,6 @@ impl<'a, Writer: Write> Printer<'a, Writer> { self.squeezer = Squeezer::Delete; } - // repeat the first byte in the line until it's a usize - // compare that usize with each usize chunk in the line - // if they are all the same, change squeezer to print let repeat_byte = usize::from_ne_bytes( self.line_buf[0..std::mem::size_of::()] .try_into() @@ -705,10 +702,13 @@ impl<'a, Writer: Write> Printer<'a, Writer> { .chunks_exact(std::mem::size_of::()) .all(|w| usize::from_ne_bytes(w.try_into().unwrap()) == repeat_byte) { + // fast calculation for when repeat fits in usize self.squeezer = Squeezer::Print; self.squeeze_byte = Some(repeat_byte); } else if self.line_buf == self.squeeze_line { + // slow check if entire line is identical self.squeezer = Squeezer::Print; + self.squeeze_byte = None; } else { self.squeeze_line = self.line_buf.clone(); } From 5d8e02015d0662cf9ab3c9e791e02ebe6dd0921c Mon Sep 17 00:00:00 2001 From: Sharif Haason Date: Mon, 21 Aug 2023 17:13:03 -0400 Subject: [PATCH 3/6] Remove debug lines --- src/lib.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0e7fbf0..f024d72 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -634,14 +634,6 @@ impl<'a, Writer: Write> Printer<'a, Writer> { self.print_header()?; } - // write!(self.writer, "{:?}", self.squeezer)?; - //write!(self.writer, "{:?}", self.squeeze_line)?; - // write!( - // self.writer, - // "{:#X} {:#X}", - // self.squeeze_line[0], self.line_buf[0] - // )?; - // squeeze is active, check if the line is the same // skip print if still squeezed, otherwise print and deactivate squeeze if matches!(self.squeezer, Squeezer::Print | Squeezer::Delete) { From 575f57ec82661bf8a28594e0ea5e525f9a884271 Mon Sep 17 00:00:00 2001 From: Sharif Haason Date: Tue, 12 Dec 2023 12:01:18 -0500 Subject: [PATCH 4/6] Print position panel on leftover no matter what --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index f024d72..3e45747 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -729,8 +729,8 @@ impl<'a, Writer: Write> Printer<'a, Writer> { writeln!(self.writer)?; } else if let Some(n) = leftover { // last line is incomplete - self.print_position_panel()?; self.squeezer = Squeezer::Ignore; + self.print_position_panel()?; self.print_bytes()?; self.squeezer = Squeezer::Print; for i in n..8 * self.panels as usize { From 4159c5deebd1812a9af15855b184fe6815c77060 Mon Sep 17 00:00:00 2001 From: Sharif Haason Date: Tue, 12 Dec 2023 12:03:14 -0500 Subject: [PATCH 5/6] Remove debugging lines --- src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3e45747..a60fd1d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,7 +36,7 @@ pub enum Endianness { Big, } -#[derive(Debug, PartialEq)] +#[derive(PartialEq)] enum Squeezer { Print, Delete, @@ -657,7 +657,6 @@ impl<'a, Writer: Write> Printer<'a, Writer> { continue; } } else { - write!(self.writer, "self")?; self.squeezer = Squeezer::Ignore; } } From 3f6be38004f473bec54457730205c1bf2db70772 Mon Sep 17 00:00:00 2001 From: Sharif Haason Date: Tue, 12 Dec 2023 12:25:43 -0500 Subject: [PATCH 6/6] Add test for identical lines --- src/lib.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index a60fd1d..a5b60c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -934,4 +934,41 @@ mod tests { let actual_string: &str = str::from_utf8(&output).unwrap(); assert_eq!(actual_string, expected_string) } + + #[test] + fn identical_lines() { + let input = io::Cursor::new( + "abcdefg\ngfedcba\nhijklmn\nhijklmn\nhijklmn\nhijklmn\nopqrstu\nvwxyzab\n", + ); + let expected_string = "\ +┌────────┬─────────────────────────┬────────┐ +│00000000│ 61 62 63 64 65 66 67 0a │abcdefg_│ +│00000008│ 67 66 65 64 63 62 61 0a │gfedcba_│ +│00000010│ 68 69 6a 6b 6c 6d 6e 0a │hijklmn_│ +│* │ │ │ +│00000030│ 6f 70 71 72 73 74 75 0a │opqrstu_│ +│00000038│ 76 77 78 79 7a 61 62 0a │vwxyzab_│ +└────────┴─────────────────────────┴────────┘ +" + .to_owned(); + let mut output = vec![]; + let mut printer: Printer> = Printer::new( + &mut output, + false, + true, + true, + BorderStyle::Unicode, + true, + 1, + 1, + Base::Hexadecimal, + Endianness::Big, + CharacterTable::Default, + ); + + printer.print_all(input).unwrap(); + + let actual_string: &str = str::from_utf8(&output).unwrap(); + assert_eq!(actual_string, expected_string) + } }