From 85213a843566b82b05626efd97c48644b04935d2 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Wed, 27 Apr 2016 01:50:04 -0400 Subject: start implementing cells --- src/cell.rs | 30 ++++++++++++++++++++++++++++++ src/ffi.rs | 6 ++++++ src/lib.rs | 2 ++ src/screen.rs | 12 ++++++++++++ src/types.rs | 1 + tests/basic.rs | 14 ++++++++++++++ 6 files changed, 65 insertions(+) create mode 100644 src/cell.rs diff --git a/src/cell.rs b/src/cell.rs new file mode 100644 index 0000000..7590e98 --- /dev/null +++ b/src/cell.rs @@ -0,0 +1,30 @@ +use libc; +use std; + +use types; + +pub struct Cell(*mut types::CellImpl); + +#[repr(C)] +struct CellPrefix { + pub contents: [libc::c_char; 8], + pub len: libc::size_t, +} + +impl Cell { + pub fn new(cell_impl: *mut types::CellImpl) -> Cell { + Cell(cell_impl) + } + + pub fn contents(&self) -> &str { + let Cell(cell_impl) = *self; + let contents: &[u8] = unsafe { + let prefix: *mut CellPrefix = std::mem::transmute(cell_impl); + std::slice::from_raw_parts( + &(*prefix).contents as *const i8 as *const u8, + (*prefix).len + ) + }; + std::str::from_utf8(contents).unwrap() + } +} diff --git a/src/ffi.rs b/src/ffi.rs index 1b984b5..e498361 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -32,6 +32,12 @@ extern "C" { rows: libc::c_int, ); + pub fn vt100_screen_cell_at( + screen: *mut types::ScreenImpl, + row: libc::c_int, + col: libc::c_int, + ) -> *mut types::CellImpl; + pub fn vt100_wrapper_rows(screen: *mut types::ScreenImpl) -> libc::c_int; pub fn vt100_wrapper_cols(screen: *mut types::ScreenImpl) -> libc::c_int; } diff --git a/src/lib.rs b/src/lib.rs index 71fc540..aa7d488 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,9 @@ extern crate libc; +mod cell; mod ffi; mod screen; mod types; pub use screen::Screen; +pub use cell::Cell; diff --git a/src/screen.rs b/src/screen.rs index da96a6a..d3e026f 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -1,6 +1,7 @@ use libc; use std; +use cell; use ffi; use types; @@ -91,6 +92,17 @@ impl Screen { }.to_vec(); std::string::String::from_utf8(rust_plaintext).unwrap() } + + pub fn cell(&self, row: i32, col: i32) -> Option { + let Screen(screen_impl) = *self; + if row < 0 || row >= self.rows() || col < 0 || col >= self.cols() { + return None + } + let cell_impl = unsafe { + ffi::vt100_screen_cell_at(screen_impl, row, col) + }; + Some(cell::Cell::new(cell_impl)) + } } impl Drop for Screen { diff --git a/src/types.rs b/src/types.rs index a5ac590..fca7f97 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,6 +1,7 @@ use libc; pub enum ScreenImpl {} +pub enum CellImpl {} #[repr(C)] pub struct Loc { diff --git a/tests/basic.rs b/tests/basic.rs index 7312928..27b688d 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -25,4 +25,18 @@ mod tests { assert_eq!(screen.rows(), 34); assert_eq!(screen.cols(), 8); } + + #[test] + fn cell_contents() { + let mut screen = vt100::Screen::new(24, 80); + let input = b"foo\x1b[31m\x1b[32mb\x1b[3;7;42ma\x1b[23mr"; + screen.process(input); + assert_eq!(screen.cell(0, 0).unwrap().contents(), "f"); + assert_eq!(screen.cell(0, 1).unwrap().contents(), "o"); + assert_eq!(screen.cell(0, 2).unwrap().contents(), "o"); + assert_eq!(screen.cell(0, 3).unwrap().contents(), "b"); + assert_eq!(screen.cell(0, 4).unwrap().contents(), "a"); + assert_eq!(screen.cell(0, 5).unwrap().contents(), "r"); + assert_eq!(screen.cell(0, 6).unwrap().contents(), ""); + } } -- cgit v1.2.3