aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2016-04-26 03:37:41 -0400
committerJesse Luehrs <doy@tozt.net>2016-04-26 03:37:41 -0400
commitfdf0992b76aa267df76246bdc95eb5650a757d74 (patch)
tree45369fb67395a5cb0837fde719ceef07377b6626
parent2a05dd6e062b68f0940992903b4874c3d68a4f50 (diff)
downloadvt100-rust-fdf0992b76aa267df76246bdc95eb5650a757d74.tar.gz
vt100-rust-fdf0992b76aa267df76246bdc95eb5650a757d74.zip
implement process_string and get_string_plaintext
-rw-r--r--src/screen.rs76
-rw-r--r--tests/basic.rs6
2 files changed, 77 insertions, 5 deletions
diff --git a/src/screen.rs b/src/screen.rs
index 5fedee1..c8b5b8d 100644
--- a/src/screen.rs
+++ b/src/screen.rs
@@ -1,15 +1,23 @@
use libc;
+use std;
enum ScreenImpl {}
+
+#[repr(C)]
+struct Loc {
+ pub row: libc::c_int,
+ pub col: libc::c_int,
+}
+
pub struct Screen {
- pub rows: u32,
- pub cols: u32,
+ pub rows: i32,
+ pub cols: i32,
screen_impl: *mut ScreenImpl,
}
impl Screen {
- pub fn new(rows: u32, cols: u32) -> Screen {
+ pub fn new(rows: i32, cols: i32) -> Screen {
let screen_impl = unsafe {
vt100_screen_new(rows as libc::c_int, cols as libc::c_int)
};
@@ -19,6 +27,50 @@ impl Screen {
screen_impl: screen_impl,
}
}
+
+ pub fn process(&mut self, s: &str) -> u64 {
+ unsafe {
+ vt100_screen_process_string(
+ self.screen_impl,
+ s.as_ptr() as *const libc::c_char,
+ s.len()
+ ) as u64
+ }
+ }
+
+ pub fn window_contents(&self,
+ row_start: i32,
+ col_start: i32,
+ row_end: i32,
+ col_end: i32
+ ) -> String {
+ let row_start = std::cmp::min(std::cmp::max(row_start, 0), self.rows - 1);
+ let col_start = std::cmp::min(std::cmp::max(col_start, 0), self.cols - 1);
+ let row_end = std::cmp::min(std::cmp::max(row_end, 0), self.rows - 1);
+ let col_end = std::cmp::min(std::cmp::max(col_end, 0), self.cols - 1);
+
+ let start_loc = Loc { row: row_start, col: col_start };
+ let end_loc = Loc { row: row_end, col: col_end };
+
+ let mut plaintext: *mut libc::c_char = unsafe { std::mem::uninitialized() };
+ let mut len: libc::size_t = unsafe { std::mem::uninitialized() };
+ unsafe {
+ vt100_screen_get_string_plaintext(
+ self.screen_impl,
+ &start_loc as *const Loc,
+ &end_loc as *const Loc,
+ &mut plaintext as *mut *mut libc::c_char,
+ &mut len as *mut libc::size_t,
+ )
+ };
+ let rust_plaintext = unsafe {
+ std::slice::from_raw_parts(
+ plaintext as *mut libc::c_uchar,
+ len
+ )
+ }.to_vec();
+ std::string::String::from_utf8(rust_plaintext).unwrap()
+ }
}
impl Drop for Screen {
@@ -28,8 +80,24 @@ impl Drop for Screen {
}
extern "C" {
- fn vt100_screen_new(rows: libc::c_int, cols: libc::c_int) -> *mut ScreenImpl;
+ fn vt100_screen_new(
+ rows: libc::c_int,
+ cols: libc::c_int
+ ) -> *mut ScreenImpl;
fn vt100_screen_delete(screen: *mut ScreenImpl);
+
+ fn vt100_screen_process_string(
+ screen: *mut ScreenImpl,
+ buf: *const libc::c_char,
+ len: libc::size_t,
+ ) -> libc::c_int;
+ fn vt100_screen_get_string_plaintext(
+ screen: *mut ScreenImpl,
+ start: *const Loc,
+ end: *const Loc,
+ outp: *mut *mut libc::c_char,
+ outlen: *mut libc::size_t,
+ );
}
#[cfg(test)]
diff --git a/tests/basic.rs b/tests/basic.rs
index 68f718a..9178ded 100644
--- a/tests/basic.rs
+++ b/tests/basic.rs
@@ -6,8 +6,12 @@ mod tests {
#[test]
fn object_creation() {
- let screen = vt100::Screen::new(24, 80);
+ let mut screen = vt100::Screen::new(24, 80);
assert_eq!(screen.rows, 24);
assert_eq!(screen.cols, 80);
+
+ let input = "foo\x1b[31m\x1b[32mb\x1b[3;7;42ma\x1b[23mr";
+ screen.process(input);
+ assert_eq!(screen.window_contents(0, 0, 0, 50), "foobar\n");
}
}