diff options
-rw-r--r-- | main.rs | 77 |
1 files changed, 40 insertions, 37 deletions
@@ -1,8 +1,6 @@ -#![feature(slice_patterns)] -// eh, whatever, unstable features... - //use std::cmp::{min, max}; //use std::io::Write as IoWrite; +use std::collections::HashMap; use std::fmt::Write as FmtWrite; use std::io::{Seek, SeekFrom}; use std::fs; @@ -24,8 +22,6 @@ use termion::clear; use termion::cursor; fn main() { -// println!("hello"); -// let (w, h) = try!(termion::terminal_size()); match termion::terminal_size() { Ok((w, h)) => { if let Some(arg1) = env::args().nth(1) { @@ -101,6 +97,7 @@ impl CachingFileView { } } +/* struct NoCacheFileView { file: std::fs::File, filelen: u64 @@ -115,8 +112,6 @@ impl NoCacheFileView { return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "File is read-only")); } -// let f2: &'a fs::File = &f; - Ok(NoCacheFileView { file: f, filelen: metadata.len() @@ -124,13 +119,6 @@ impl NoCacheFileView { } } -trait FileView { - fn get_bytes(&mut self, offset: u64, len: u64) -> Vec<u8>; - fn size(&self) -> u64; -} - -const modal_width: usize = 24; - impl FileView for NoCacheFileView { fn get_bytes(&mut self, offset: u64, len: u64) -> Vec<u8> { let mut vec = Vec::with_capacity(len as usize); @@ -141,21 +129,38 @@ impl FileView for NoCacheFileView { } fn size(&self) -> u64 { self.filelen } } +*/ +trait FileView { + fn get_bytes(&mut self, offset: u64, len: u64) -> Vec<u8>; + fn size(&self) -> u64; +} + +const MODAL_WIDTH: usize = 24; + +// super naive, no idea how to track inserts/deletions yet struct Edits { - + edit_list: HashMap<u64, u8> } impl Edits { fn new() -> Edits { Edits { + edit_list: std::collections::HashMap::new() } } - fn remove(&mut self, cursor: u64, sub_elem: u8) { - + // TODO: this should accept the various kinds of edits and + // positions down to bit-level, then figure it out. + // + // consider: + // Bit(location, value) + // Base64(location, value) + // Byte(location, value) + fn remove(&mut self, cursor: u64) { + self.edit_list.remove(&cursor); } - fn record(&mut self, cursor: u64, sub_elem: u8, value: u8) { - + fn record(&mut self, cursor: u64, value: u8) { + self.edit_list.insert(cursor, value); } } @@ -214,7 +219,6 @@ struct Program<'a, 'b> { view: &'b mut FileView, input_buf: Vec<char>, state: Mode, - sub_elem: u8, edits: Edits, status: String, edit_views: Vec<&'b mut EditMode>, @@ -326,7 +330,6 @@ fn launch_interface(w: u16, h: u16, filename: String) { state: Mode::Edit, status: "".to_string(), input_buf: Vec::with_capacity(0), - sub_elem: 0, edits: Edits::new(), edit_views: vec![ &mut hexmode @@ -409,6 +412,9 @@ fn interface_loop(state: &mut Program) { Event::Key(Key::Char('q')) => { break; } + Event::Key(Key::Ctrl('\t')) => { + // switch to previous edit mode + } Event::Key(Key::Ctrl(x)) => { state.status = format!("ctrl {}", x); } @@ -416,9 +422,6 @@ fn interface_loop(state: &mut Program) { // switch to next edit mode } // would prefer shift+t - Event::Key(Key::Ctrl('\t')) => { - // switch to previous edit mode - } Event::Unsupported(vec) => { if vec.len() == 3 && vec[0] == 0x1b && vec[1] == 0x4f { match vec[2] { @@ -451,12 +454,12 @@ fn interface_loop(state: &mut Program) { Event::Key(Key::Char(x)) => { // TODO: how does this work on non-US keyboards? keyboards without a-fA-F? if (x >= '0' && x <= '9') || (x >= 'a' && x <= 'f') || (x >= 'A' && x <= 'F') { - state.edits.record(state.cursor, state.sub_elem, x as u8); + state.edits.record(state.cursor, x as u8); // edit the nibble under the cursor } } Event::Key(Key::Backspace) => { - state.edits.remove(state.cursor, state.sub_elem); + state.edits.remove(state.cursor); state.dec_cursor(1); } _ => { } @@ -475,7 +478,7 @@ fn interface_loop(state: &mut Program) { let addr_str = u64::from_str_radix(&buf_str, 16); match addr_str { Ok(addr) => { - if addr >= 0 && addr < state.view.size() { + if addr < state.view.size() { state.seek_to(addr); state.input_buf = Vec::with_capacity(0); state.state = Mode::Edit; @@ -487,7 +490,7 @@ fn interface_loop(state: &mut Program) { } } Err(s) => { - state.status = format!("Unable to parse address '{}'", buf_str); + state.status = format!("Unable to parse address '{}', error: {}", buf_str, s); state.input_buf = Vec::with_capacity(0); state.state = Mode::Edit; } @@ -504,7 +507,7 @@ fn interface_loop(state: &mut Program) { } Event::Key(Key::Char(x)) => { if (x >= '0' && x <= '9') || (x >= 'a' && x <= 'f') || (x >= 'A' && x <= 'F') { - if state.input_buf.len() < modal_width - 6 { + if state.input_buf.len() < MODAL_WIDTH - 6 { state.input_buf.push(x); } } @@ -625,9 +628,9 @@ fn render_interface(state: &mut Program) { }; write!(iface, "{} {} {}", addr, hex_line, ascii_line).unwrap(); for view in state.edit_views.iter() { - let slice_start = (width * i); + let slice_start = width * i; let slice_end = slice_start + width; - write!(iface, "\n{}", view.render_bytes(start as u64 + slice_start, buffer[(slice_start as usize)..(slice_end as usize)].iter())); + write!(iface, "\n{}", view.render_bytes(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(); @@ -639,12 +642,12 @@ fn render_interface(state: &mut Program) { Mode::ReadAddress => { let xmid = state.width as u16 / 2; let ymid = state.height as u16 / 2; - write!(state.screen, "{}{:-^2$}", cursor::Goto(xmid-12, ymid-2), "", modal_width); - write!(state.screen, "{}|{: ^2$}|", cursor::Goto(xmid-12, ymid-1), "Enter new addresss", modal_width - 2); - write!(state.screen, "{}| >{:_^2$} |", cursor::Goto(xmid-12, ymid-0), "", modal_width - 6); - write!(state.screen, "{}|{: ^2$}|", cursor::Goto(xmid-12, ymid+1), "", modal_width - 2); - write!(state.screen, "{}{:-^2$}", cursor::Goto(xmid-12, ymid+2), "", modal_width); - write!(state.screen, "{}{}", cursor::Goto(xmid-9, ymid-0), state.input_buf.iter().cloned().collect::<String>()); + write!(state.screen, "{}{:-^2$}", cursor::Goto(xmid-12, ymid-2), "", MODAL_WIDTH).unwrap(); + write!(state.screen, "{}|{: ^2$}|", cursor::Goto(xmid-12, ymid-1), "Enter new addresss", MODAL_WIDTH - 2).unwrap(); + write!(state.screen, "{}| >{:_^2$} |", cursor::Goto(xmid-12, ymid-0), "", MODAL_WIDTH - 6).unwrap(); + write!(state.screen, "{}|{: ^2$}|", cursor::Goto(xmid-12, ymid+1), "", MODAL_WIDTH - 2).unwrap(); + write!(state.screen, "{}{:-^2$}", cursor::Goto(xmid-12, ymid+2), "", MODAL_WIDTH).unwrap(); + write!(state.screen, "{}{}", cursor::Goto(xmid-9, ymid-0), state.input_buf.iter().cloned().collect::<String>()).unwrap(); } _ => {} } |