summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2017-10-15 02:22:28 -0700
committeriximeow <me@iximeow.net>2017-10-15 02:22:28 -0700
commite242083d38edae25f332c672a45b31d6fb7f56f5 (patch)
tree23f1964ccb250a40216d94244ddb9572d86726df
parent47d58e6eaaf429251ec6efb69d859b63027f1424 (diff)
add binary edit mode, kind of
remove row_size as its no longer necessary fix impending bugs with row size mismatches
-rw-r--r--main.rs85
1 files 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<u8>) -> 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;