From fdf0992b76aa267df76246bdc95eb5650a757d74 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 26 Apr 2016 03:37:41 -0400 Subject: implement process_string and get_string_plaintext --- src/screen.rs | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- tests/basic.rs | 6 ++++- 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"); } } -- cgit v1.2.3-54-g00ecf