summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.rs77
1 files changed, 40 insertions, 37 deletions
diff --git a/main.rs b/main.rs
index 80a2a1e..7f1c4df 100644
--- a/main.rs
+++ b/main.rs
@@ -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();
}
_ => {}
}