From e242083d38edae25f332c672a45b31d6fb7f56f5 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 15 Oct 2017 02:22:28 -0700 Subject: add binary edit mode, kind of remove row_size as its no longer necessary fix impending bugs with row size mismatches --- main.rs | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/main.rs b/main.rs index 18df243..848c041 100644 --- a/main.rs +++ b/main.rs @@ -174,6 +174,49 @@ trait EditMode { fn inc_sub_elem(&mut self, amount: u64); } +struct BinaryMode { + sub_elem_idx: u8 +} + +impl EditMode for BinaryMode { + fn render_bytes(&self, cursor: u64, start: u64, bytes: std::slice::Iter) -> String { + let mut text = "".to_owned(); +// let mut ascii_text = "".to_owned(); + let col_size = 1; + let mut i: usize = 0; + for b in bytes { + if cursor == start + i as u64 { + text.push_str(&format!("{}", color::Fg(color::Yellow))); +// ascii_text.push_str(&format!("{}", color::Fg(color::Yellow))); + text.push_str(&format!("{:08b}", b)); +// ascii_text.push_str(&format!("{}", ascii_or_dot(b.to_owned()) as char)); + text.push_str(&format!("{}", color::Fg(color::Reset))); +// ascii_text.push_str(&format!("{}", color::Fg(color::Reset))); + } else { + text.push_str(&format!("{:08b}", b)); +// ascii_text.push_str(&format!("{}", ascii_or_dot(b.to_owned()) as char)); + } + if i % col_size == (col_size - 1) { + text.push_str(" "); + } else { + text.push_str(" "); + } + i = i + 1; + } + format!(" {}", text).to_owned() + } + fn element_width(&self, display_width: u16) -> u64 { + // left pad by 12, 9 chars wide per byte + (display_width as u64 - 12 - 12) / 9 + } + fn dec_sub_elem(&mut self, amount: u64) { + self.sub_elem_idx = self.sub_elem_idx - amount as u8; + } + fn inc_sub_elem(&mut self, amount: u64) { + self.sub_elem_idx = self.sub_elem_idx + amount as u8; + } +} + struct HexMode { sub_elem_idx: u8 } @@ -184,12 +227,19 @@ impl EditMode for HexMode { let mut ascii_text = "".to_owned(); let col_size = 4; let mut i: usize = 0; + let selected = true; for b in bytes { if cursor == start + i as u64 { text.push_str(&format!("{}", color::Fg(color::Yellow))); ascii_text.push_str(&format!("{}", color::Fg(color::Yellow))); + if selected { + text.push_str(&format!("{}", termion::style::Bold)); + } text.push_str(&format!("{:02x}", b)); ascii_text.push_str(&format!("{}", ascii_or_dot(b.to_owned()) as char)); + if selected { + text.push_str(&format!("{}", termion::style::Reset)); + } text.push_str(&format!("{}", color::Fg(color::Reset))); ascii_text.push_str(&format!("{}", color::Fg(color::Reset))); } else { @@ -219,7 +269,6 @@ impl EditMode for HexMode { struct Program<'a, 'b> { filename: String, width: u16, - row_size: u16, height: u16, seek: u64, cursor: u64, @@ -269,12 +318,8 @@ impl <'a, 'b> Program<'a, 'b> { self.height as u64 - self.view_interface_height() } - fn view_byte_width(&self) -> u64 { - self.row_size as u64 - } - fn bytes_per_line(&self) -> u64 { - let mut min = self.view_byte_width(); + let mut min = self.width as u64; for view in self.edit_views.iter() { min = std::cmp::min(min, view.element_width(self.width)); } @@ -293,7 +338,7 @@ impl <'a, 'b> Program<'a, 'b> { * */ let hex_view_height = self.lines_to_draw(); - let bytes_per_line = self.view_byte_width(); + let bytes_per_line = self.bytes_per_line(); let render_lim = bytes_per_line * hex_view_height; if self.cursor >= self.seek + render_lim { // know a priori that buf size is height * width. TODO: fix. // we've sought past the end, so reset seek to what would have been the start of this @@ -320,11 +365,11 @@ fn launch_interface(w: u16, h: u16, filename: String) { //let initial_buf = populate_buf(&filename, 0, w as u64 * h as u64); let mut hexmode = HexMode { sub_elem_idx: 0 }; + let mut binmode = BinaryMode { sub_elem_idx: 0 }; let mut state = Program { filename: filename.to_string(), width: w, - row_size: ((w - 13) / 17) * 4, height: h, old_term: termios, new_term: new_termios, @@ -338,7 +383,8 @@ fn launch_interface(w: u16, h: u16, filename: String) { input_buf: Vec::with_capacity(0), edits: Edits::new(), edit_views: vec![ - &mut hexmode + &mut hexmode, + &mut binmode ], current_edit_idx: 0 }; @@ -374,11 +420,11 @@ fn interface_loop(state: &mut Program) { state.state = Mode::ReadAddress; } Event::Key(Key::Up) => { - let amount = state.row_size; // why can't this be inlined? + let amount = state.bytes_per_line(); // why can't this be inlined? state.dec_cursor(amount as u64); } Event::Key(Key::Down) => { - let amount = state.row_size; + let amount = state.bytes_per_line(); state.inc_cursor(amount as u64); } Event::Key(Key::Left) => { @@ -388,11 +434,11 @@ fn interface_loop(state: &mut Program) { state.inc_cursor(1); } Event::Key(Key::PageDown) => { - let amount = state.view_byte_width() * state.lines_to_draw(); + let amount = state.bytes_per_line() * state.lines_to_draw(); if state.view.size() - state.cursor < amount { state.cursor = state.view.size() - 1; state.seek = std::cmp::min( - state.view.size() - (state.view.size() % state.view_byte_width()), + state.view.size() - (state.view.size() % state.bytes_per_line()), state.seek + amount ) } else { @@ -401,7 +447,7 @@ fn interface_loop(state: &mut Program) { } } Event::Key(Key::PageUp) => { - let amount = state.view_byte_width() * state.lines_to_draw(); + let amount = state.bytes_per_line() * state.lines_to_draw(); if state.cursor < amount { state.cursor = 0; state.seek = 0; @@ -555,7 +601,7 @@ fn ascii_or_dot(c: u8) -> u8 { fn render_interface(state: &mut Program) { // println!("{}", clear::All); write!(state.screen, "{}{}", cursor::Goto(1, 1), clear::CurrentLine).unwrap(); - let bufsz = state.lines_to_draw() * state.view_byte_width(); + let bufsz = state.lines_to_draw() * state.bytes_per_line(); writeln!(state.screen, "Dimensions: {}x{} Seek: 0x{:x}, Cursor: 0x{:x} - file: {}, 0x{:x} bytes", state.width, state.height, state.seek, state.cursor, state.filename, state.view.size()).unwrap(); if state.status.len() > 0 { writeln!(state.screen, "{}{} {}", cursor::Goto(1, 2), clear::CurrentLine, state.status).unwrap(); @@ -573,13 +619,14 @@ fn render_interface(state: &mut Program) { let width = state.bytes_per_line(); for i in 0..state.lines_to_draw() { - for view in state.edit_views.iter() { + for j in 0..state.edit_views.len() { + let view = &state.edit_views[j]; let slice_start = width * i; let slice_end = slice_start + width; write!(iface, "{}", view.render_bytes(state.cursor, start as u64 + slice_start, buffer[(slice_start as usize)..(slice_end as usize)].iter())).unwrap(); - } - if i < state.lines_to_draw() - 1 { - write!(iface, "\n").unwrap(); + if i < state.lines_to_draw() - 1 || j < (state.edit_views.len() - 1) { + write!(iface, "\n").unwrap(); + } } } let height = state.view_interface_height() as u16; -- cgit v1.1