<commit_before>// #![feature(phase)]
// #[phase(plugin, link)] extern crate log;

use racer::codecleaner::{code_chunks,CodeIndicesIter};
// use codecleaner::{code_chunks,CodeIndicesIter};
// mod codecleaner;

#[cfg(test)] use racer::testutils::{rejustify, slice};

pub struct StmtIndicesIter<'a> {
    src: &'a str,
    it: CodeIndicesIter<'a>,
    pos: uint,
    start: uint,
    end: uint,
    bracelevel: int,
    parenlevel: int,
    is_macro: bool,
    enddelim: u8
}

impl<'a> Iterator<(uint, uint)> for StmtIndicesIter<'a> {
    #[inline]
    fn next(&mut self) -> Option<(uint, uint)> {
        let semicolon: u8 = ";".as_bytes()[0];
        let hash: u8 = "#".as_bytes()[0];
        let openbrace: u8 = "{".as_bytes()[0];
        let closebrace: u8 = "}".as_bytes()[0];
        let openparen: u8 = "(".as_bytes()[0];
        let closeparen: u8 = ")".as_bytes()[0];
        let closesqbrace: u8 = "]".as_bytes()[0];
        let bang: u8 = "!".as_bytes()[0];
        let whitespace = " \t\n".as_bytes();

        let __u: u8 = "u".as_bytes()[0];
        let __s: u8 = "s".as_bytes()[0];
        let __e: u8 = "e".as_bytes()[0];

        let src_bytes = self.src.as_bytes();

        loop {

            if self.end <= self.pos {
                // get the next chunk of code
                match self.it.next() {
                    Some((start, end)) => {
                        self.end = end;
                        if self.start == self.pos {
                            self.start = start;
                        }
                        self.pos = start;
                    }
                    None => {
                        return None
                    }
                }
            }

            // if this is a new stmt block, skip the whitespace
            if self.pos == self.start {
                while self.pos < self.end {
                    if !whitespace.contains(&src_bytes[self.pos]) {
                        break;
                    } else {
                        self.pos += 1;
                    }
                }
                self.start = self.pos;
            }

            // if the statement starts with 'macro_rules!' then we're in a macro
            // We need to know this because a closeparen can terminate a macro
            if (self.end - self.pos) > 12 &&
               self.src.slice(self.pos, self.pos+12) == "macro_rules!" {
                self.is_macro = true;
            }

            // iterate through the chunk, looking for stmt end
            while self.pos < self.end {
                if src_bytes[self.pos] == openparen {

                    // macros can be terminated by closeparen if opened by one
                    if self.is_macro &&
                        self.bracelevel == 0 &&
                        self.parenlevel == 0 {
                        self.enddelim = closeparen;
                    }

                    // also macro invocations can too
                    if self.pos > 0 && src_bytes[self.pos-1] == bang &&
                        self.bracelevel == 0 &&
                        self.parenlevel == 0 {
                        self.enddelim = closeparen;
                    }

                    self.parenlevel += 1;

                } else if src_bytes[self.pos] == closeparen {
                    self.parenlevel -= 1;

                } else if src_bytes[self.pos] == openbrace {
                    // if we are top level and stmt is not a 'use' then
                    // closebrace finishes the stmt
                    if self.bracelevel == 0 &&
                        self.parenlevel == 0 &&
                       !(is_a_use_stmt(self.src, self.start, self.pos)) {
                           self.enddelim = closebrace;
                    }
                    self.bracelevel += 1;

                } else if src_bytes[self.pos] == closebrace {
                    self.bracelevel -= 1;
                    // have we reached the end of the scope?
                    if self.bracelevel < 0 {
                        return None;
                    }
                }

                // attribute   #[foo = bar]
                if self.bracelevel == 0 && self.start == self.pos &&
                    src_bytes[self.pos] == hash {
                    self.enddelim = closesqbrace;
                }

                if self.bracelevel == 0 && self.parenlevel == 0 &&
                   src_bytes[self.pos] == self.enddelim {
                    let start = self.start;
                    self.start = self.pos+1;
                    self.pos = self.pos+1;
                    self.enddelim = semicolon;
                    self.is_macro = false;
                    return Some((start, self.pos));
                }

                self.pos += 1;
            }
        }
    }
}

fn is_a_use_stmt(src: &str, start: uint, pos: uint) -> bool {
    let src_bytes = src.as_bytes();
    let whitespace = " {\t\n".as_bytes();
    (pos > 3 && src_bytes.slice(start, start+3) == "use".as_bytes() &&
     whitespace.contains(&src_bytes[start+3])) ||
        (pos > 7 && src_bytes.slice(start, start+7) == "pub use".as_bytes() &&
                      whitespace.contains(&src_bytes[start+7]))
}

pub fn iter_stmts<'a>(src: &'a str) -> StmtIndicesIter<'a> {
    let semicolon: u8 = ";".as_bytes()[0];
    StmtIndicesIter{src: src, it: code_chunks(src),
                    pos: 0, start: 0, end: 0, bracelevel: 0,
                    parenlevel: 0, enddelim: semicolon, is_macro: false}
}

#[test]
fn iterates_single_use_stmts() {
    let src = rejustify("
    use std::Foo; // a comment
    use std::Bar;
    ");
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("use std::Foo;", slice(src.as_slice(), it.next().unwrap()));
    assert_eq!("use std::Bar;", slice(src.as_slice(), it.next().unwrap()));
}

#[test]
fn iterates_use_stmt_over_two_lines() {
    let src = rejustify("
    use std::{Foo,
              Bar}; // a comment
    ");
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("use std::{Foo,
          Bar};", slice(src.as_slice(), it.next().unwrap()));
}

#[test]
fn iterates_use_stmt_without_the_prefix() {
    let src = rejustify("
    pub use {Foo,
              Bar}; // this is also legit apparently
    ");
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("pub use {Foo,
          Bar};", slice(src.as_slice(), it.next().unwrap()));
}

#[test]
fn iterates_while_stmt() {
    let src = rejustify("
    while self.pos < 3 { }
    ");
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("while self.pos < 3 { }", slice(src.as_slice(), it.next().unwrap()));
}

#[test]
fn iterates_lambda_arg() {
    let src = rejustify("
    myfn(|n|{});
    ");
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("myfn(|n|{});", slice(src.as_slice(), it.next().unwrap()));
}

#[test]
fn iterates_macro() {
    let src = "
    mod foo;
    macro_rules! otry(
        ($e:expr) => (match $e { Some(e) => e, None => return })
    )
    mod bar;
    ";
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("mod foo;", slice(src.as_slice(), it.next().unwrap()));
    assert_eq!("macro_rules! otry(
        ($e:expr) => (match $e { Some(e) => e, None => return })
    )", slice(src.as_slice(), it.next().unwrap()));
    assert_eq!("mod bar;", slice(src.as_slice(), it.next().unwrap()));
}

#[test]
fn iterates_macro_invocation() {
    let src = "
    mod foo;
    local_data_key!(local_stdout: Box<Writer + Send>)  // no ';'
    mod bar;
    ";
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("mod foo;", slice(src.as_slice(), it.next().unwrap()));
    assert_eq!("local_data_key!(local_stdout: Box<Writer + Send>)", slice(src.as_slice(), it.next().unwrap()));
    assert_eq!("mod bar;", slice(src.as_slice(), it.next().unwrap()));
}

// #[test]
// fn iterates_if_else_stmt() {
//     let src = rejustify("
//     if self.pos < 3 { } else { }
//     ");
//     let mut it = iter_stmts(src.as_slice());
//     assert_eq!("if self.pos < 3 { } else { }", slice(src.as_slice(), it.next().unwrap()));
// }

#[test]
fn iterates_inner_scope() {
    let src = "
    while self.pos < 3 {
       let a = 35;
       return a + 35;  // should iterate this
    }
    {
       b = foo;       // but not this
    }
    ";

    let scope = src.as_slice().slice_from(25);
    //println!("blah{}",scope);
    let mut it = iter_stmts(scope);

    assert_eq!("let a = 35;", slice(scope, it.next().unwrap()));
    assert_eq!("return a + 35;", slice(scope, it.next().unwrap()));
    assert_eq!(None, it.next());
}

#[test]
fn iterates_module_attribute() {
    let src = rejustify("
    #![license = \"BSD\"]
    #[test]
    ");
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("#![license = \"BSD\"]", slice(src.as_slice(), it.next().unwrap()));
    assert_eq!("#[test]", slice(src.as_slice(), it.next().unwrap()));
}

// fn main() {
//     use std::io::BufferedReader;
//     use std::io::File;
//     use std::str;

//     let filetxt = BufferedReader::new(File::open(&Path::new("/usr/local/src/rust/src/libstd/io/stdio.rs"))).read_to_end().unwrap();
//     let src = str::from_utf8(filetxt.as_slice()).unwrap();

//     for (start,end) in iter_stmts(src) {
//         println!("BLOB |{}|",src.slice(start,end));
//     }

// }
<commit_msg>Attempt to make racer work in presence of DOS carriage returns<commit_after>// #![feature(phase)]
// #[phase(plugin, link)] extern crate log;

use racer::codecleaner::{code_chunks,CodeIndicesIter};
// use codecleaner::{code_chunks,CodeIndicesIter};
// mod codecleaner;

#[cfg(test)] use racer::testutils::{rejustify, slice};

pub struct StmtIndicesIter<'a> {
    src: &'a str,
    it: CodeIndicesIter<'a>,
    pos: uint,
    start: uint,
    end: uint,
    bracelevel: int,
    parenlevel: int,
    is_macro: bool,
    enddelim: u8
}

impl<'a> Iterator<(uint, uint)> for StmtIndicesIter<'a> {
    #[inline]
    fn next(&mut self) -> Option<(uint, uint)> {
        let semicolon: u8 = ";".as_bytes()[0];
        let hash: u8 = "#".as_bytes()[0];
        let openbrace: u8 = "{".as_bytes()[0];
        let closebrace: u8 = "}".as_bytes()[0];
        let openparen: u8 = "(".as_bytes()[0];
        let closeparen: u8 = ")".as_bytes()[0];
        let closesqbrace: u8 = "]".as_bytes()[0];
        let bang: u8 = "!".as_bytes()[0];
        let whitespace = " \t\r\n".as_bytes();

        let __u: u8 = "u".as_bytes()[0];
        let __s: u8 = "s".as_bytes()[0];
        let __e: u8 = "e".as_bytes()[0];

        let src_bytes = self.src.as_bytes();

        loop {

            if self.end <= self.pos {
                // get the next chunk of code
                match self.it.next() {
                    Some((start, end)) => {
                        self.end = end;
                        if self.start == self.pos {
                            self.start = start;
                        }
                        self.pos = start;
                    }
                    None => {
                        return None
                    }
                }
            }

            // if this is a new stmt block, skip the whitespace
            if self.pos == self.start {
                while self.pos < self.end {
                    if !whitespace.contains(&src_bytes[self.pos]) {
                        break;
                    } else {
                        self.pos += 1;
                    }
                }
                self.start = self.pos;
            }

            // if the statement starts with 'macro_rules!' then we're in a macro
            // We need to know this because a closeparen can terminate a macro
            if (self.end - self.pos) > 12 &&
               self.src.slice(self.pos, self.pos+12) == "macro_rules!" {
                self.is_macro = true;
            }

            // iterate through the chunk, looking for stmt end
            while self.pos < self.end {
                if src_bytes[self.pos] == openparen {

                    // macros can be terminated by closeparen if opened by one
                    if self.is_macro &&
                        self.bracelevel == 0 &&
                        self.parenlevel == 0 {
                        self.enddelim = closeparen;
                    }

                    // also macro invocations can too
                    if self.pos > 0 && src_bytes[self.pos-1] == bang &&
                        self.bracelevel == 0 &&
                        self.parenlevel == 0 {
                        self.enddelim = closeparen;
                    }

                    self.parenlevel += 1;

                } else if src_bytes[self.pos] == closeparen {
                    self.parenlevel -= 1;

                } else if src_bytes[self.pos] == openbrace {
                    // if we are top level and stmt is not a 'use' then
                    // closebrace finishes the stmt
                    if self.bracelevel == 0 &&
                        self.parenlevel == 0 &&
                       !(is_a_use_stmt(self.src, self.start, self.pos)) {
                           self.enddelim = closebrace;
                    }
                    self.bracelevel += 1;

                } else if src_bytes[self.pos] == closebrace {
                    self.bracelevel -= 1;
                    // have we reached the end of the scope?
                    if self.bracelevel < 0 {
                        return None;
                    }
                }

                // attribute   #[foo = bar]
                if self.bracelevel == 0 && self.start == self.pos &&
                    src_bytes[self.pos] == hash {
                    self.enddelim = closesqbrace;
                }

                if self.bracelevel == 0 && self.parenlevel == 0 &&
                   src_bytes[self.pos] == self.enddelim {
                    let start = self.start;
                    self.start = self.pos+1;
                    self.pos = self.pos+1;
                    self.enddelim = semicolon;
                    self.is_macro = false;
                    return Some((start, self.pos));
                }

                self.pos += 1;
            }
        }
    }
}

fn is_a_use_stmt(src: &str, start: uint, pos: uint) -> bool {
    let src_bytes = src.as_bytes();
    let whitespace = " {\t\r\n".as_bytes();
    (pos > 3 && src_bytes.slice(start, start+3) == "use".as_bytes() &&
     whitespace.contains(&src_bytes[start+3])) ||
        (pos > 7 && src_bytes.slice(start, start+7) == "pub use".as_bytes() &&
                      whitespace.contains(&src_bytes[start+7]))
}

pub fn iter_stmts<'a>(src: &'a str) -> StmtIndicesIter<'a> {
    let semicolon: u8 = ";".as_bytes()[0];
    StmtIndicesIter{src: src, it: code_chunks(src),
                    pos: 0, start: 0, end: 0, bracelevel: 0,
                    parenlevel: 0, enddelim: semicolon, is_macro: false}
}

#[test]
fn iterates_single_use_stmts() {
    let src = rejustify("
    use std::Foo; // a comment
    use std::Bar;
    ");
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("use std::Foo;", slice(src.as_slice(), it.next().unwrap()));
    assert_eq!("use std::Bar;", slice(src.as_slice(), it.next().unwrap()));
}

#[test]
fn iterates_use_stmt_over_two_lines() {
    let src = rejustify("
    use std::{Foo,
              Bar}; // a comment
    ");
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("use std::{Foo,
          Bar};", slice(src.as_slice(), it.next().unwrap()));
}

#[test]
fn iterates_use_stmt_without_the_prefix() {
    let src = rejustify("
    pub use {Foo,
              Bar}; // this is also legit apparently
    ");
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("pub use {Foo,
          Bar};", slice(src.as_slice(), it.next().unwrap()));
}

#[test]
fn iterates_while_stmt() {
    let src = rejustify("
    while self.pos < 3 { }
    ");
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("while self.pos < 3 { }", slice(src.as_slice(), it.next().unwrap()));
}

#[test]
fn iterates_lambda_arg() {
    let src = rejustify("
    myfn(|n|{});
    ");
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("myfn(|n|{});", slice(src.as_slice(), it.next().unwrap()));
}

#[test]
fn iterates_macro() {
    let src = "
    mod foo;
    macro_rules! otry(
        ($e:expr) => (match $e { Some(e) => e, None => return })
    )
    mod bar;
    ";
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("mod foo;", slice(src.as_slice(), it.next().unwrap()));
    assert_eq!("macro_rules! otry(
        ($e:expr) => (match $e { Some(e) => e, None => return })
    )", slice(src.as_slice(), it.next().unwrap()));
    assert_eq!("mod bar;", slice(src.as_slice(), it.next().unwrap()));
}

#[test]
fn iterates_macro_invocation() {
    let src = "
    mod foo;
    local_data_key!(local_stdout: Box<Writer + Send>)  // no ';'
    mod bar;
    ";
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("mod foo;", slice(src.as_slice(), it.next().unwrap()));
    assert_eq!("local_data_key!(local_stdout: Box<Writer + Send>)", slice(src.as_slice(), it.next().unwrap()));
    assert_eq!("mod bar;", slice(src.as_slice(), it.next().unwrap()));
}

// #[test]
// fn iterates_if_else_stmt() {
//     let src = rejustify("
//     if self.pos < 3 { } else { }
//     ");
//     let mut it = iter_stmts(src.as_slice());
//     assert_eq!("if self.pos < 3 { } else { }", slice(src.as_slice(), it.next().unwrap()));
// }

#[test]
fn iterates_inner_scope() {
    let src = "
    while self.pos < 3 {
       let a = 35;
       return a + 35;  // should iterate this
    }
    {
       b = foo;       // but not this
    }
    ";

    let scope = src.as_slice().slice_from(25);
    //println!("blah{}",scope);
    let mut it = iter_stmts(scope);

    assert_eq!("let a = 35;", slice(scope, it.next().unwrap()));
    assert_eq!("return a + 35;", slice(scope, it.next().unwrap()));
    assert_eq!(None, it.next());
}

#[test]
fn iterates_module_attribute() {
    let src = rejustify("
    #![license = \"BSD\"]
    #[test]
    ");
    let mut it = iter_stmts(src.as_slice());
    assert_eq!("#![license = \"BSD\"]", slice(src.as_slice(), it.next().unwrap()));
    assert_eq!("#[test]", slice(src.as_slice(), it.next().unwrap()));
}

// fn main() {
//     use std::io::BufferedReader;
//     use std::io::File;
//     use std::str;

//     let filetxt = BufferedReader::new(File::open(&Path::new("/usr/local/src/rust/src/libstd/io/stdio.rs"))).read_to_end().unwrap();
//     let src = str::from_utf8(filetxt.as_slice()).unwrap();

//     for (start,end) in iter_stmts(src) {
//         println!("BLOB |{}|",src.slice(start,end));
//     }

// }
<|endoftext|>


<commit_before>const USAGE: &'static str = "
Usage: life bench [--size N] [--gens N]
       life --help
Conway's Game of Life.

Commands:
    bench           Run the benchmark in different modes and print the timings.
Options:
    --size N        Size of the game board (N x N) [default: 200]
    --gens N        Simulate N generations [default: 100]
    -h, --help      Show this message.
";

use rand::{thread_rng, Rng};
use std::iter::repeat;
use std::num::Wrapping;
use std::sync::Arc;
use time;

use docopt::Docopt;
use rayon::prelude::*;

#[cfg(test)]
mod bench;

#[derive(RustcDecodable)]
pub struct Args {
    cmd_bench: bool,
    flag_size: usize,
    flag_gens: usize,
}

#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Board {
    board: Vec<bool>,
    survive: Arc<Vec<usize>>,
    born: Arc<Vec<usize>>,
    rows: usize,
    cols: usize
}

impl Board {
    pub fn new(rows: usize, cols: usize) -> Board {
        let born = vec![3];
        let survive = vec![2, 3];

        Board::new_with_custom_rules(rows, cols, born, survive)
    }

    fn new_with_custom_rules(rows: usize, cols: usize, born: Vec<usize>, survive: Vec<usize>) -> Board {
        let new_board = repeat(false).take(rows * cols).collect();

        Board { board  : new_board,
                born   : Arc::new(born),
                survive: Arc::new(survive),
                rows   : rows,
                cols   : cols }
    }

    fn len(&self) -> usize {
        self.rows * self.cols
    }

    fn next_board(&self, new_board: Vec<bool>) -> Board {
        assert!(new_board.len() == self.len());

        Board { board  : new_board,
                born   : self.born.clone(),
                survive: self.survive.clone(),
                rows   : self.rows,
                cols   : self.cols }
    }

    pub fn random(&self) -> Board {
        let new_brd = thread_rng().gen_iter::<bool>().take(self.len()).collect();

        self.next_board(new_brd)
    }

    pub fn next_generation(&self) -> Board {
        let new_brd = (0..self.len()).map(|cell| self.successor_cell(cell)).collect();

        self.next_board(new_brd)
    }

    pub fn parallel_next_generation(&self) -> Board {
        let new_brd = (0..self.len())
            .into_par_iter()
            .map(|cell| self.successor_cell(cell))
            .collect();

        self.next_board(new_brd)
    }

    fn cell_live(&self, x: usize, y: usize) -> bool {
        !(x >= self.cols || y >= self.rows) && self.board[y * self.cols + x]
    }

    fn living_neighbors(&self, x: usize, y: usize) -> usize {
        let Wrapping(x_1) = Wrapping(x) - Wrapping(1);
        let Wrapping(y_1) = Wrapping(y) - Wrapping(1);
        let neighbors = [
            self.cell_live(x_1, y_1), self.cell_live(x, y_1), self.cell_live(x+1, y_1),
            self.cell_live(x_1, y+0),                         self.cell_live(x+1, y+0),
            self.cell_live(x_1, y+1), self.cell_live(x, y+1), self.cell_live(x+1, y+1),
        ];
        neighbors.iter().filter(|&x| *x).count()
    }

    fn successor_cell(&self, cell: usize) -> bool {
        self.successor(cell % self.cols, cell / self.cols)
    }

    fn successor(&self, x: usize, y: usize) -> bool {
        let neighbors = self.living_neighbors(x, y);
        if self.cell_live(x, y) {
            self.survive.contains(&neighbors)
        } else {
            self.born.contains(&neighbors)
        }
    }
}

#[test]
fn test_life() {
    let mut brd1 = Board::new(200, 200).random();
    let mut brd2 = brd1.clone();

    for _ in 0..100 {
        brd1 = brd1.next_generation();
        brd2 = brd2.parallel_next_generation();

        assert_eq!(brd1, brd2);
    }
}

fn generations(board: Board, gens: usize) {
    let mut brd = board;
    for _ in 0..gens { brd = brd.next_generation(); }
}

fn parallel_generations(board: Board, gens: usize) {
    let mut brd = board;
    for _ in 0..gens { brd = brd.parallel_next_generation(); }
}

fn measure(f: fn(Board, usize) -> (), args: &Args) -> u64 {
    let (n, gens) = (args.flag_size, args.flag_gens);
    let brd = Board::new(n, n).random();
    let start = time::precise_time_ns();

    f(brd, gens);

    time::precise_time_ns() - start
}

pub fn main(args: &[String]) {
    let args: Args =
        Docopt::new(USAGE)
            .and_then(|d| d.argv(args).decode())
            .unwrap_or_else(|e| e.exit());

    if args.cmd_bench {
        let serial = measure(generations, &args);
        println!("  serial: {:10} ns", serial);

        let parallel = measure(parallel_generations, &args);
        println!("parallel: {:10} ns -> {:.2}x speedup", parallel,
                 serial as f64 / parallel as f64);
    }
}
<commit_msg>No need for a turbofish<commit_after>const USAGE: &'static str = "
Usage: life bench [--size N] [--gens N]
       life --help
Conway's Game of Life.

Commands:
    bench           Run the benchmark in different modes and print the timings.
Options:
    --size N        Size of the game board (N x N) [default: 200]
    --gens N        Simulate N generations [default: 100]
    -h, --help      Show this message.
";

use rand::{thread_rng, Rng};
use std::iter::repeat;
use std::num::Wrapping;
use std::sync::Arc;
use time;

use docopt::Docopt;
use rayon::prelude::*;

#[cfg(test)]
mod bench;

#[derive(RustcDecodable)]
pub struct Args {
    cmd_bench: bool,
    flag_size: usize,
    flag_gens: usize,
}

#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Board {
    board: Vec<bool>,
    survive: Arc<Vec<usize>>,
    born: Arc<Vec<usize>>,
    rows: usize,
    cols: usize
}

impl Board {
    pub fn new(rows: usize, cols: usize) -> Board {
        let born = vec![3];
        let survive = vec![2, 3];

        Board::new_with_custom_rules(rows, cols, born, survive)
    }

    fn new_with_custom_rules(rows: usize, cols: usize, born: Vec<usize>, survive: Vec<usize>) -> Board {
        let new_board = repeat(false).take(rows * cols).collect();

        Board { board  : new_board,
                born   : Arc::new(born),
                survive: Arc::new(survive),
                rows   : rows,
                cols   : cols }
    }

    fn len(&self) -> usize {
        self.rows * self.cols
    }

    fn next_board(&self, new_board: Vec<bool>) -> Board {
        assert!(new_board.len() == self.len());

        Board { board  : new_board,
                born   : self.born.clone(),
                survive: self.survive.clone(),
                rows   : self.rows,
                cols   : self.cols }
    }

    pub fn random(&self) -> Board {
        let new_brd = thread_rng().gen_iter().take(self.len()).collect();

        self.next_board(new_brd)
    }

    pub fn next_generation(&self) -> Board {
        let new_brd = (0..self.len()).map(|cell| self.successor_cell(cell)).collect();

        self.next_board(new_brd)
    }

    pub fn parallel_next_generation(&self) -> Board {
        let new_brd = (0..self.len())
            .into_par_iter()
            .map(|cell| self.successor_cell(cell))
            .collect();

        self.next_board(new_brd)
    }

    fn cell_live(&self, x: usize, y: usize) -> bool {
        !(x >= self.cols || y >= self.rows) && self.board[y * self.cols + x]
    }

    fn living_neighbors(&self, x: usize, y: usize) -> usize {
        let Wrapping(x_1) = Wrapping(x) - Wrapping(1);
        let Wrapping(y_1) = Wrapping(y) - Wrapping(1);
        let neighbors = [
            self.cell_live(x_1, y_1), self.cell_live(x, y_1), self.cell_live(x+1, y_1),
            self.cell_live(x_1, y+0),                         self.cell_live(x+1, y+0),
            self.cell_live(x_1, y+1), self.cell_live(x, y+1), self.cell_live(x+1, y+1),
        ];
        neighbors.iter().filter(|&x| *x).count()
    }

    fn successor_cell(&self, cell: usize) -> bool {
        self.successor(cell % self.cols, cell / self.cols)
    }

    fn successor(&self, x: usize, y: usize) -> bool {
        let neighbors = self.living_neighbors(x, y);
        if self.cell_live(x, y) {
            self.survive.contains(&neighbors)
        } else {
            self.born.contains(&neighbors)
        }
    }
}

#[test]
fn test_life() {
    let mut brd1 = Board::new(200, 200).random();
    let mut brd2 = brd1.clone();

    for _ in 0..100 {
        brd1 = brd1.next_generation();
        brd2 = brd2.parallel_next_generation();

        assert_eq!(brd1, brd2);
    }
}

fn generations(board: Board, gens: usize) {
    let mut brd = board;
    for _ in 0..gens { brd = brd.next_generation(); }
}

fn parallel_generations(board: Board, gens: usize) {
    let mut brd = board;
    for _ in 0..gens { brd = brd.parallel_next_generation(); }
}

fn measure(f: fn(Board, usize) -> (), args: &Args) -> u64 {
    let (n, gens) = (args.flag_size, args.flag_gens);
    let brd = Board::new(n, n).random();
    let start = time::precise_time_ns();

    f(brd, gens);

    time::precise_time_ns() - start
}

pub fn main(args: &[String]) {
    let args: Args =
        Docopt::new(USAGE)
            .and_then(|d| d.argv(args).decode())
            .unwrap_or_else(|e| e.exit());

    if args.cmd_bench {
        let serial = measure(generations, &args);
        println!("  serial: {:10} ns", serial);

        let parallel = measure(parallel_generations, &args);
        println!("parallel: {:10} ns -> {:.2}x speedup", parallel,
                 serial as f64 / parallel as f64);
    }
}
<|endoftext|>


<commit_before>use solitaire::card::*;

use std::char;
use std::cmp;
use std::iter::range_inclusive;

#[deriving(PartialEq, Show)]
pub struct Deck {
    pub d: Vec<Card>,
}

impl Iterator<uint> for Deck {
    fn next(&mut self) -> Option<uint> {
        Some(self.gen_keystream_letter())
    }
}

impl Deck {
    pub fn new() -> Deck {
        let per_suit = 13;
        let mut deck = Deck { d: Vec::new() };
        for i in range_inclusive(1, per_suit) {
            deck.d.push(Clubs(i));
        }
        for i in range_inclusive(1, per_suit) {
            deck.d.push(Diamonds(i));
        }
        for i in range_inclusive(1, per_suit) {
            deck.d.push(Hearts(i));
        }
        for i in range_inclusive(1, per_suit) {
            deck.d.push(Spades(i));
        }

        deck.d.push(JokerA);
        deck.d.push(JokerB);
        return deck;
    }

    pub fn with_key(key: &str) -> Deck {
        let mut deck = Deck::new();
        let a = 'A' as uint - 1;
        let k = key.chars()
                   .filter(|x| char::is_alphabetic(*x))
                   .map(|x| char::to_uppercase(x))
                   .collect::<String>();
        for e in k.as_bytes().iter() {
            deck.with_key_helper(*e as uint - a);
        }

        return deck;
    }

    fn with_key_helper(&mut self, i: uint) {
        self.move_joker(JokerA, 1);
        self.move_joker(JokerB, 2);
        self.triple_cut();
        self.count_cut();
        let mut new = Vec::with_capacity(self.d.len());
        new.push_all(self.d.slice(i, self.d.len()-1));
        new.push_all(self.d.slice(0, i));
        new.push(*self.d.last().unwrap());
        self.d = new;
    }

    pub fn encrypt(&mut self, plain: &str) -> String {
        let a = 'A' as u8;
        plain.chars().map(|x|
                          match char::is_alphabetic(x) {
                              true => (((x as u8 - a + self.gen_keystream_letter() as u8) % 26) + a) as char,
                              false => x,
                          }).collect::<String>()
    }

    pub fn gen_keystream_letter(&mut self) -> uint {
        self.move_joker(JokerA, 1);
        self.move_joker(JokerB, 2);
        self.triple_cut();
        self.count_cut();
        let i = self.d[0].count_index();
        match self.d[i].count_index() {
            53 => self.gen_keystream_letter(),
            i => i,
        }
    }

    pub fn move_joker(&mut self, j: Card, count: int) {
        let mut i = self.d.as_slice().position_elem(&j).unwrap();
        for _ in range(0i, count) {
            if i < self.d.len()-1 {
                self.d.as_mut_slice().swap(i, i+1);
            } else {
                // if card is the last card in the deck, move below the first card of the deck
                // every card needs to be moved... maybe this should have been a linked list
                let mut new = Vec::with_capacity(self.d.len());
                new.push(self.d[0]);
                new.push(*self.d.last().unwrap());
                new.push_all(self.d.slice(1, self.d.len()-1));
                self.d = new;
            }
            i = if i != self.d.len()-1 {
                i + 1
            } else {
                1
            };
        }
    }

    pub fn triple_cut(&mut self) {
        let mut new = Vec::with_capacity(self.d.len());
        let ai = self.d.as_slice().position_elem(&JokerA).unwrap();
        let bi = self.d.as_slice().position_elem(&JokerB).unwrap();
        let first = cmp::min(ai, bi);
        let secnd = cmp::max(ai, bi);
        new.push_all(self.d.slice(secnd+1, self.d.len()));
        new.push_all(self.d.slice(first, secnd + 1));
        new.push_all(self.d.slice(0, first));
        self.d = new;
    }

    pub fn count_cut(&mut self) {
        // cut after c
        let i = self.d.last().unwrap().count_index();
        let mut new = Vec::with_capacity(self.d.len());
        new.push_all(self.d.slice(i, self.d.len()-1));
        new.push_all(self.d.slice(0, i));
        new.push(*self.d.last().unwrap());
        self.d = new;
    }

}

#[test]
fn new_deck() {
    let d = Deck::new();
    assert_eq!(d, Deck { d: vec![Clubs(1), Clubs(2), Clubs(3), Clubs(4), Clubs(5), Clubs(6), Clubs(7), Clubs(8), Clubs(9), Clubs(10), Clubs(11), Clubs(12), Clubs(13), Diamonds(1), Diamonds(2), Diamonds(3), Diamonds(4), Diamonds(5), Diamonds(6), Diamonds(7), Diamonds(8), Diamonds(9), Diamonds(10), Diamonds(11), Diamonds(12), Diamonds(13), Hearts(1), Hearts(2), Hearts(3), Hearts(4), Hearts(5), Hearts(6), Hearts(7), Hearts(8), Hearts(9), Hearts(10), Hearts(11), Hearts(12), Hearts(13), Spades(1), Spades(2), Spades(3), Spades(4), Spades(5), Spades(6), Spades(7), Spades(8), Spades(9), Spades(10), Spades(11), Spades(12), Spades(13), JokerA, JokerB] });
}

#[test]
fn move_joker() {
    let mut d = Deck{ d: vec![Clubs(1), Clubs(2), JokerA] };
    d.move_joker(JokerA, 1);
    assert_eq!(d.d, vec![Clubs(1), JokerA, Clubs(2)]);

    let mut d = Deck{ d: vec![Clubs(1), Clubs(2), Hearts(3), JokerA, JokerB] };
    d.move_joker(JokerA, 1);
    d.move_joker(JokerB, 2);
    assert_eq!(d.d, vec![Clubs(1), JokerB, Clubs(2), Hearts(3), JokerA]);
}

#[test]
fn triple_cut() {
    let tests = vec![
        (vec![Clubs(1), JokerA, Clubs(2), JokerB, Clubs(3)], vec![Clubs(3), JokerA, Clubs(2), JokerB, Clubs(1)]),
        (vec![Clubs(1), Hearts(1), JokerA, Clubs(2), JokerB, Clubs(3), Hearts(3)], vec![Clubs(3), Hearts(3), JokerA, Clubs(2), JokerB, Clubs(1), Hearts(1)]),
        (vec![JokerA, JokerB], vec![JokerA, JokerB]),
        ];

    for test in tests.iter() {
        let (initial, expect) = test.clone();
        let mut got = Deck{ d: initial };
        got.triple_cut();
        assert_eq!(got.d, expect);
    }
}

#[test]
fn gen_keystream_letter() {
    let mut d = Deck::new();
    let expects = vec![4, 49, 10, 24, 8, 51, 44, 6, 4, 33];
    for e in expects.iter() {
        assert_eq!(d.gen_keystream_letter(), *e);
    }
}

#[test]
fn count_cut() {
    let mut d = Deck{ d: vec![Clubs(7), Clubs(3), Clubs(13), Clubs(14), Clubs(15), Clubs(16), Clubs(17), Clubs(18), Clubs(4), Clubs(5), Clubs(8), Clubs(9)]};
    let expect = Deck{ d: vec![Clubs(5), Clubs(8), Clubs(7), Clubs(3), Clubs(13), Clubs(14), Clubs(15), Clubs(16), Clubs(17), Clubs(18), Clubs(4), Clubs(9)] };
    d.count_cut();
    assert_eq!(d, expect);
}

#[test]
fn key() {
    let mut d = Deck::with_key("FOO");
    let expects = vec![8, 19, 7, 25, 20, 9, 8, 22, 32, 43, 5, 26, 17, 38, 48];
    for e in expects.iter() {
        assert_eq!(d.gen_keystream_letter(), *e);
    }
}
<commit_msg>Add tests for keys from Schneier's site<commit_after>use solitaire::card::*;

use std::char;
use std::cmp;
use std::iter::range_inclusive;

#[deriving(PartialEq, Show)]
pub struct Deck {
    pub d: Vec<Card>,
}

impl Iterator<uint> for Deck {
    fn next(&mut self) -> Option<uint> {
        Some(self.gen_keystream_letter())
    }
}

impl Deck {
    pub fn new() -> Deck {
        let per_suit = 13;
        let mut deck = Deck { d: Vec::new() };
        for i in range_inclusive(1, per_suit) {
            deck.d.push(Clubs(i));
        }
        for i in range_inclusive(1, per_suit) {
            deck.d.push(Diamonds(i));
        }
        for i in range_inclusive(1, per_suit) {
            deck.d.push(Hearts(i));
        }
        for i in range_inclusive(1, per_suit) {
            deck.d.push(Spades(i));
        }

        deck.d.push(JokerA);
        deck.d.push(JokerB);
        return deck;
    }

    pub fn with_key(key: &str) -> Deck {
        let mut deck = Deck::new();
        let a = 'A' as uint - 1;
        let k = key.chars()
                   .filter(|x| char::is_alphabetic(*x))
                   .map(|x| char::to_uppercase(x))
                   .collect::<String>();
        for e in k.as_bytes().iter() {
            deck.with_key_helper(*e as uint - a);
        }

        return deck;
    }

    fn with_key_helper(&mut self, i: uint) {
        self.move_joker(JokerA, 1);
        self.move_joker(JokerB, 2);
        self.triple_cut();
        self.count_cut();
        let mut new = Vec::with_capacity(self.d.len());
        new.push_all(self.d.slice(i, self.d.len()-1));
        new.push_all(self.d.slice(0, i));
        new.push(*self.d.last().unwrap());
        self.d = new;
    }

    pub fn encrypt(&mut self, plain: &str) -> String {
        let a = 'A' as u8;
        plain.chars().map(|x|
                          match char::is_alphabetic(x) {
                              true => (((x as u8 - a + self.gen_keystream_letter() as u8) % 26) + a) as char,
                              false => x,
                          }).collect::<String>()
    }

    pub fn gen_keystream_letter(&mut self) -> uint {
        self.move_joker(JokerA, 1);
        self.move_joker(JokerB, 2);
        self.triple_cut();
        self.count_cut();
        let i = self.d[0].count_index();
        match self.d[i].count_index() {
            53 => self.gen_keystream_letter(),
            i => i,
        }
    }

    pub fn move_joker(&mut self, j: Card, count: int) {
        let mut i = self.d.as_slice().position_elem(&j).unwrap();
        for _ in range(0i, count) {
            if i < self.d.len()-1 {
                self.d.as_mut_slice().swap(i, i+1);
            } else {
                // if card is the last card in the deck, move below the first card of the deck
                // every card needs to be moved... maybe this should have been a linked list
                let mut new = Vec::with_capacity(self.d.len());
                new.push(self.d[0]);
                new.push(*self.d.last().unwrap());
                new.push_all(self.d.slice(1, self.d.len()-1));
                self.d = new;
            }
            i = if i != self.d.len()-1 {
                i + 1
            } else {
                1
            };
        }
    }

    pub fn triple_cut(&mut self) {
        let mut new = Vec::with_capacity(self.d.len());
        let ai = self.d.as_slice().position_elem(&JokerA).unwrap();
        let bi = self.d.as_slice().position_elem(&JokerB).unwrap();
        let first = cmp::min(ai, bi);
        let secnd = cmp::max(ai, bi);
        new.push_all(self.d.slice(secnd+1, self.d.len()));
        new.push_all(self.d.slice(first, secnd + 1));
        new.push_all(self.d.slice(0, first));
        self.d = new;
    }

    pub fn count_cut(&mut self) {
        // cut after c
        let i = self.d.last().unwrap().count_index();
        let mut new = Vec::with_capacity(self.d.len());
        new.push_all(self.d.slice(i, self.d.len()-1));
        new.push_all(self.d.slice(0, i));
        new.push(*self.d.last().unwrap());
        self.d = new;
    }

}

#[test]
fn new_deck() {
    let d = Deck::new();
    assert_eq!(d, Deck { d: vec![Clubs(1), Clubs(2), Clubs(3), Clubs(4), Clubs(5), Clubs(6), Clubs(7), Clubs(8), Clubs(9), Clubs(10), Clubs(11), Clubs(12), Clubs(13), Diamonds(1), Diamonds(2), Diamonds(3), Diamonds(4), Diamonds(5), Diamonds(6), Diamonds(7), Diamonds(8), Diamonds(9), Diamonds(10), Diamonds(11), Diamonds(12), Diamonds(13), Hearts(1), Hearts(2), Hearts(3), Hearts(4), Hearts(5), Hearts(6), Hearts(7), Hearts(8), Hearts(9), Hearts(10), Hearts(11), Hearts(12), Hearts(13), Spades(1), Spades(2), Spades(3), Spades(4), Spades(5), Spades(6), Spades(7), Spades(8), Spades(9), Spades(10), Spades(11), Spades(12), Spades(13), JokerA, JokerB] });
}

#[test]
fn move_joker() {
    let mut d = Deck{ d: vec![Clubs(1), Clubs(2), JokerA] };
    d.move_joker(JokerA, 1);
    assert_eq!(d.d, vec![Clubs(1), JokerA, Clubs(2)]);

    let mut d = Deck{ d: vec![Clubs(1), Clubs(2), Hearts(3), JokerA, JokerB] };
    d.move_joker(JokerA, 1);
    d.move_joker(JokerB, 2);
    assert_eq!(d.d, vec![Clubs(1), JokerB, Clubs(2), Hearts(3), JokerA]);
}

#[test]
fn triple_cut() {
    let tests = vec![
        (vec![Clubs(1), JokerA, Clubs(2), JokerB, Clubs(3)], vec![Clubs(3), JokerA, Clubs(2), JokerB, Clubs(1)]),
        (vec![Clubs(1), Hearts(1), JokerA, Clubs(2), JokerB, Clubs(3), Hearts(3)], vec![Clubs(3), Hearts(3), JokerA, Clubs(2), JokerB, Clubs(1), Hearts(1)]),
        (vec![JokerA, JokerB], vec![JokerA, JokerB]),
        ];

    for test in tests.iter() {
        let (initial, expect) = test.clone();
        let mut got = Deck{ d: initial };
        got.triple_cut();
        assert_eq!(got.d, expect);
    }
}

#[test]
fn gen_keystream_letter() {
    let mut d = Deck::new();
    let expects = vec![4, 49, 10, 24, 8, 51, 44, 6, 4, 33];
    for e in expects.iter() {
        assert_eq!(d.gen_keystream_letter(), *e);
    }
}

#[test]
fn count_cut() {
    let mut d = Deck{ d: vec![Clubs(7), Clubs(3), Clubs(13), Clubs(14), Clubs(15), Clubs(16), Clubs(17), Clubs(18), Clubs(4), Clubs(5), Clubs(8), Clubs(9)]};
    let expect = Deck{ d: vec![Clubs(5), Clubs(8), Clubs(7), Clubs(3), Clubs(13), Clubs(14), Clubs(15), Clubs(16), Clubs(17), Clubs(18), Clubs(4), Clubs(9)] };
    d.count_cut();
    assert_eq!(d, expect);
}

#[test]
fn key() {
    let mut d = Deck::with_key("FOO");
    let expects = vec![8, 19, 7, 25, 20, 9, 8, 22, 32, 43, 5, 26, 17, 38, 48];
    for e in expects.iter() {
        assert_eq!(d.gen_keystream_letter(), *e);
    }
}

#[test]
fn encrypt() {
    let tests = vec![
        ("", "AAAAAAAAAAAAAAA", "EXKYIZSGEHUNTIQ"),
        ("F", "AAAAAAAAAAAAAAA", "XYIUQBMHKKJBEGY"),
        ("FO", "AAAAAAAAAAAAAAA", "TUJYMBERLGXNDIW"),
        ("FOO", "AAAAAAAAAAAAAAA", "ITHZUJIWGRFARMW"),
        ("A", "AAAAAAAAAAAAAAA", "XODALGSCULIQNSC"),
        ("aa", "AAAAAAAAAAAAAAA", "OHGWMXXCAIMCIQP"),
        ("aaa", "AAAAAAAAAAAAAAA", "DCSQYHBQZNGDRUT"),
        ("b", "AAAAAAAAAAAAAAA", "XQEEMOITLZVDSQS"),
        ("bc", "AAAAAAAAAAAAAAA", "QNGRKQIHCLGWSCE"),
        ("bcd", "AAAAAAAAAAAAAAA", "FMUBYBMAXHNQXCJ"),
        ("cryptonomicon", "AAAAAAAAAAAAAAAAAAAAAAAAA", "SUGSRSXSWQRMXOHIPBFPXARYQ"),
        ];
    for &(key, plain, cipher) in tests.iter() {
        let mut d = Deck::with_key(key);
        let out = d.encrypt(plain);
        assert_eq!(out.as_slice(), cipher);
    }
}
<|endoftext|>


<commit_before>
use std::iter;
use std::io::{Write};
use std::io;

use encoding::types::{EncodingRef, EncoderTrap};
use encoding::all::{UTF_8};
use byteorder::{LittleEndian, WriteBytesExt};

use consts;
use img::{Image};

pub struct Printer<W: io::Write> {
    writer: io::BufWriter<W>,
    codec: EncodingRef,
    trap: EncoderTrap
}

impl<W: io::Write> Printer<W> {
    pub fn new(writer: W,
               codec: Option<EncodingRef>,
               trap: Option<EncoderTrap>) -> Printer<W> {
        Printer{
            writer: io::BufWriter::new(writer),
            codec: codec.unwrap_or(UTF_8 as EncodingRef),
            trap: trap.unwrap_or(EncoderTrap::Replace)
        }
    }

    fn encode(&mut self, content: &str) -> Vec<u8> {
        self.codec.encode(content, self.trap).unwrap()
    }

    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.writer.write(buf)
    }

    fn write_u8(&mut self, n: u8) -> io::Result<usize> {
        self.write(vec!(n).as_slice())
    }

    fn write_u16le(&mut self, n: u16) -> io::Result<usize> {
        let mut wtr = vec![];
        wtr.write_u16::<LittleEndian>(n).unwrap();
        self.write(wtr.as_slice())
    }

    pub fn flush(&mut self) -> io::Result<()> {
        self.writer.flush()
    }

    pub fn hwinit(&mut self) -> &mut Printer<W> {
        let _ = self.write(consts::HW_INIT);
        self
    }

    pub fn hwselect(&mut self) -> &mut Printer<W> {
        let _ = self.write(consts::HW_SELECT);
        self
    }

    pub fn hwreset(&mut self) -> &mut Printer<W> {
        let _ = self.write(consts::HW_RESET);
        self
    }

    pub fn print(&mut self, content: &str) -> &mut Printer<W> {
        // let rv = self.encode(content);
        let rv = self.encode(content);
        let _ = self.write(rv.as_slice());
        self
    }

    pub fn println(&mut self, content: &str) -> &mut Printer<W> {
        self.print(format!("{}{}", content, consts::EOL).as_ref());
        self
    }

    pub fn text(&mut self, content: &str) -> &mut Printer<W> {
        self.println(content);
        self
    }

    pub fn line_space(&mut self, n: i32) -> &mut Printer<W> {
        if n >= 0 {
            let _ = self.write(consts::LS_SET);
            let _ = self.write_u8(n as u8);
        } else {
            let _ = self.write(consts::LS_DEFAULT);
        }
        self
    }

    pub fn feed(&mut self, n: usize) -> &mut Printer<W> {
        let n = if n < 1 { 1 } else { n };
        let _ = self.write(iter::repeat(consts::EOL)
                           .take(n)
                           .collect::<String>()
                           .as_ref());
        self
    }

    pub fn control(&mut self, ctrl: &str) -> &mut Printer<W> {
        let ctrl_upper = ctrl.to_uppercase();
        let ctrl_value = match ctrl_upper.as_ref() {
            "LF" => consts::CTL_LF,
            "FF" => consts::CTL_FF,
            "CR" => consts::CTL_CR,
            "HT" => consts::CTL_HT,
            "VT" => consts::CTL_VT,
            _ => panic!("Invalid control action: {}", ctrl)
        };
        let _ = self.write(ctrl_value);
        self
    }

    pub fn align(&mut self, alignment: &str) -> &mut Printer<W> {
        let align_upper = alignment.to_uppercase();
        let align_value = match align_upper.as_ref() {
            "LT" => consts::TXT_ALIGN_LT,
            "CT" => consts::TXT_ALIGN_CT,
            "RT" => consts::TXT_ALIGN_RT,
            _ => panic!("Invalid alignment: {}", alignment)
        };
        let _ = self.write(align_value);
        self
    }

    pub fn font(&mut self, family: &str) -> &mut Printer<W> {
        let family_upper = family.to_uppercase();
        let family_value = match family_upper.as_ref() {
            "A" => consts::TXT_FONT_A,
            "B" => consts::TXT_FONT_B,
            "C" => consts::TXT_FONT_C,
            _ => panic!("Invalid font family: {}", family)
        };
        let _ = self.write(family_value);
        self
    }

    pub fn style(&mut self, kind: &str) -> &mut Printer<W> {
        let kind_upper = kind.to_uppercase();
        match kind_upper.as_ref() {
            "B" => {
                let _ = self.write(consts::TXT_UNDERL_OFF);
                let _ = self.write(consts::TXT_BOLD_ON);
            }
            "U" => {
                let _ = self.write(consts::TXT_BOLD_OFF);
                let _ = self.write(consts::TXT_UNDERL_ON);
            }
            "U2" => {
                let _ = self.write(consts::TXT_BOLD_OFF);
                let _ = self.write(consts::TXT_UNDERL2_ON);
            }
            "BU" => {
                let _ = self.write(consts::TXT_BOLD_ON);
                let _ = self.write(consts::TXT_UNDERL_ON);
            }
            "BU2" => {
                let _ = self.write(consts::TXT_BOLD_ON);
                let _ = self.write(consts::TXT_UNDERL2_ON);
            }
            "NORMAL" | _ => {
                let _ = self.write(consts::TXT_BOLD_OFF);
                let _ = self.write(consts::TXT_UNDERL_OFF);
            }
        }
        self
    }

    pub fn size(&mut self, width: usize, height: usize) -> &mut Printer<W> {
        let _ = self.write(consts::TXT_NORMAL);
        if width == 2 {
            let _ = self.write(consts::TXT_2WIDTH);
        }
        if height == 2 {
            let _ = self.write(consts::TXT_2HEIGHT);
        }
        self
    }

    pub fn hardware(&mut self, hw: &str) -> &mut Printer<W> {
        let value = match hw {
            "INIT" => consts::HW_INIT,
            "SELECT" => consts::HW_SELECT,
            "RESET" => consts::HW_RESET,
            _ => panic!("Invalid hardware command: {}", hw)
        };
        let _ = self.write(value);
        self
    }

    pub fn barcode(&mut self,
                   code: &str,
                   kind: &str,
                   position: &str,
                   font: &str,
                   width: usize, height: usize) -> &mut Printer<W> {
        if width >= 1 || width <= 255 {
            let _ = self.write(consts::BARCODE_WIDTH);
        }
        if height >= 2 || height <= 6 {
            let _ = self.write(consts::BARCODE_HEIGHT);
        }

        let font = font.to_uppercase();
        let position = position.to_uppercase();
        let kind = kind.to_uppercase().replace("-", "_");
        let font_value = match font.as_ref() {
            "B" => consts::BARCODE_FONT_B,
            "A" | _ => consts::BARCODE_FONT_A
        };
        let txt_value = match position.as_ref() {
            "OFF" => consts::BARCODE_TXT_OFF,
            "ABV" => consts::BARCODE_TXT_ABV,
            "BTH" => consts::BARCODE_TXT_BTH,
            "BLW" | _ => consts::BARCODE_TXT_BLW,
        };
        let kind_value = match kind.as_ref() {
            "UPC_A"  => consts::BARCODE_UPC_A,
            "UPC_E"  => consts::BARCODE_UPC_E,
            "EAN8"   => consts::BARCODE_EAN8,
            "CODE39" => consts::BARCODE_CODE39,
            "ITF"    => consts::BARCODE_ITF,
            "NW7"    => consts::BARCODE_NW7,
            "EAN13" | _ => consts::BARCODE_EAN13
        };
        let _ = self.write(font_value);
        let _ = self.write(txt_value);
        let _ = self.write(kind_value);
        let _ = self.write(code.as_bytes());
        self
    }

    pub fn qrimage(&mut self) -> &mut Printer<W> {
        self
    }

    pub fn qrcode(&mut self,
                  code: &str,
                  version: Option<i32>,
                  level: &str,
                  size: Option<i32>) -> &mut Printer<W> {
        let level = level.to_uppercase();
        let level_value = match level.as_ref() {
            "M" => consts::QR_LEVEL_M,
            "Q" => consts::QR_LEVEL_Q,
            "H" => consts::QR_LEVEL_H,
            "L" | _ => consts::QR_LEVEL_L,
        };
        let _ = self.write(consts::TYPE_QR);
        let _ = self.write(consts::CODE2D);
        let _ = self.write_u8(version.unwrap_or(3) as u8);
        let _ = self.write(level_value);
        let _ = self.write_u8(size.unwrap_or(3) as u8);
        let _ = self.write_u16le(code.len() as u16);
        let _ = self.write(code.as_bytes());
        self
    }

    pub fn cashdraw(&mut self, pin: i32) -> &mut Printer<W> {
        let pin_value = if pin == 5 {
            consts::CD_KICK_5
        } else {
            consts::CD_KICK_2
        };
        let _ = self.write(pin_value);
        self
    }

    pub fn cut(&mut self, part: bool) -> &mut Printer<W> {
        self.print(iter::repeat(consts::EOL)
                   .take(3)
                   .collect::<String>()
                   .as_ref());
        let paper_cut_type = if part {
            consts::PAPER_PART_CUT
        } else {
            consts::PAPER_FULL_CUT
        };
        let _ = self.write(paper_cut_type);
        self
    }

    pub fn bit_image(&mut self,
                    image: &Image,
                    density: Option<&str>) -> &mut Printer<W> {
        let density = density.unwrap_or("d24");
        let density_upper = density.to_uppercase();
        let header = match density_upper.as_ref() {
            "S8"  => consts::BITMAP_S8,
            "D8"  => consts::BITMAP_D8,
            "S24" => consts::BITMAP_S24,
            "D24" | _ => consts::BITMAP_D24,
        };
        let n = if density == "s8" || density == "d8" { 1 } else { 3 };
        self.line_space(0);
        for line in image.bitimage_lines(n*8) {
            let _ = self.write(header);
            let _ = self.write_u16le((line.len() / n as usize) as u16);
            let _ = self.write(line.as_ref());
            self.feed(1);
        }
        self
    }

    pub fn raster(&mut self, image: &Image, mode: Option<&str>) -> &mut Printer<W> {
        let mode_upper = mode.unwrap_or("NORMAL").to_uppercase();
        let header = match mode_upper.as_ref() {
            "DH" => consts::GSV0_DH,
            "DWDH" => consts::GSV0_DWDH,
            "DW" | "NORMAL" | _ => consts::GSV0_DW,
        };
        let _ = self.write(header);
        let _ = self.write_u16le(image.width as u16);
        let _ = self.write_u16le(image.height as u16);
        let _ = self.write(image.get_raster().as_ref());
        self
    }
}
<commit_msg>Made write_u8 public<commit_after>
use std::iter;
use std::io::{Write};
use std::io;

use encoding::types::{EncodingRef, EncoderTrap};
use encoding::all::{UTF_8};
use byteorder::{LittleEndian, WriteBytesExt};

use consts;
use img::{Image};

pub struct Printer<W: io::Write> {
    writer: io::BufWriter<W>,
    codec: EncodingRef,
    trap: EncoderTrap
}

impl<W: io::Write> Printer<W> {
    pub fn new(writer: W,
               codec: Option<EncodingRef>,
               trap: Option<EncoderTrap>) -> Printer<W> {
        Printer{
            writer: io::BufWriter::new(writer),
            codec: codec.unwrap_or(UTF_8 as EncodingRef),
            trap: trap.unwrap_or(EncoderTrap::Replace)
        }
    }

    fn encode(&mut self, content: &str) -> Vec<u8> {
        self.codec.encode(content, self.trap).unwrap()
    }

    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.writer.write(buf)
    }

    pub fn write_u8(&mut self, n: u8) -> io::Result<usize> {
        self.write(vec!(n).as_slice())
    }

    fn write_u16le(&mut self, n: u16) -> io::Result<usize> {
        let mut wtr = vec![];
        wtr.write_u16::<LittleEndian>(n).unwrap();
        self.write(wtr.as_slice())
    }

    pub fn flush(&mut self) -> io::Result<()> {
        self.writer.flush()
    }

    pub fn hwinit(&mut self) -> &mut Printer<W> {
        let _ = self.write(consts::HW_INIT);
        self
    }

    pub fn hwselect(&mut self) -> &mut Printer<W> {
        let _ = self.write(consts::HW_SELECT);
        self
    }

    pub fn hwreset(&mut self) -> &mut Printer<W> {
        let _ = self.write(consts::HW_RESET);
        self
    }

    pub fn print(&mut self, content: &str) -> &mut Printer<W> {
        // let rv = self.encode(content);
        let rv = self.encode(content);
        let _ = self.write(rv.as_slice());
        self
    }

    pub fn println(&mut self, content: &str) -> &mut Printer<W> {
        self.print(format!("{}{}", content, consts::EOL).as_ref());
        self
    }

    pub fn text(&mut self, content: &str) -> &mut Printer<W> {
        self.println(content);
        self
    }

    pub fn line_space(&mut self, n: i32) -> &mut Printer<W> {
        if n >= 0 {
            let _ = self.write(consts::LS_SET);
            let _ = self.write_u8(n as u8);
        } else {
            let _ = self.write(consts::LS_DEFAULT);
        }
        self
    }

    pub fn feed(&mut self, n: usize) -> &mut Printer<W> {
        let n = if n < 1 { 1 } else { n };
        let _ = self.write(iter::repeat(consts::EOL)
                           .take(n)
                           .collect::<String>()
                           .as_ref());
        self
    }

    pub fn control(&mut self, ctrl: &str) -> &mut Printer<W> {
        let ctrl_upper = ctrl.to_uppercase();
        let ctrl_value = match ctrl_upper.as_ref() {
            "LF" => consts::CTL_LF,
            "FF" => consts::CTL_FF,
            "CR" => consts::CTL_CR,
            "HT" => consts::CTL_HT,
            "VT" => consts::CTL_VT,
            _ => panic!("Invalid control action: {}", ctrl)
        };
        let _ = self.write(ctrl_value);
        self
    }

    pub fn align(&mut self, alignment: &str) -> &mut Printer<W> {
        let align_upper = alignment.to_uppercase();
        let align_value = match align_upper.as_ref() {
            "LT" => consts::TXT_ALIGN_LT,
            "CT" => consts::TXT_ALIGN_CT,
            "RT" => consts::TXT_ALIGN_RT,
            _ => panic!("Invalid alignment: {}", alignment)
        };
        let _ = self.write(align_value);
        self
    }

    pub fn font(&mut self, family: &str) -> &mut Printer<W> {
        let family_upper = family.to_uppercase();
        let family_value = match family_upper.as_ref() {
            "A" => consts::TXT_FONT_A,
            "B" => consts::TXT_FONT_B,
            "C" => consts::TXT_FONT_C,
            _ => panic!("Invalid font family: {}", family)
        };
        let _ = self.write(family_value);
        self
    }

    pub fn style(&mut self, kind: &str) -> &mut Printer<W> {
        let kind_upper = kind.to_uppercase();
        match kind_upper.as_ref() {
            "B" => {
                let _ = self.write(consts::TXT_UNDERL_OFF);
                let _ = self.write(consts::TXT_BOLD_ON);
            }
            "U" => {
                let _ = self.write(consts::TXT_BOLD_OFF);
                let _ = self.write(consts::TXT_UNDERL_ON);
            }
            "U2" => {
                let _ = self.write(consts::TXT_BOLD_OFF);
                let _ = self.write(consts::TXT_UNDERL2_ON);
            }
            "BU" => {
                let _ = self.write(consts::TXT_BOLD_ON);
                let _ = self.write(consts::TXT_UNDERL_ON);
            }
            "BU2" => {
                let _ = self.write(consts::TXT_BOLD_ON);
                let _ = self.write(consts::TXT_UNDERL2_ON);
            }
            "NORMAL" | _ => {
                let _ = self.write(consts::TXT_BOLD_OFF);
                let _ = self.write(consts::TXT_UNDERL_OFF);
            }
        }
        self
    }

    pub fn size(&mut self, width: usize, height: usize) -> &mut Printer<W> {
        let _ = self.write(consts::TXT_NORMAL);
        if width == 2 {
            let _ = self.write(consts::TXT_2WIDTH);
        }
        if height == 2 {
            let _ = self.write(consts::TXT_2HEIGHT);
        }
        self
    }

    pub fn hardware(&mut self, hw: &str) -> &mut Printer<W> {
        let value = match hw {
            "INIT" => consts::HW_INIT,
            "SELECT" => consts::HW_SELECT,
            "RESET" => consts::HW_RESET,
            _ => panic!("Invalid hardware command: {}", hw)
        };
        let _ = self.write(value);
        self
    }

    pub fn barcode(&mut self,
                   code: &str,
                   kind: &str,
                   position: &str,
                   font: &str,
                   width: usize, height: usize) -> &mut Printer<W> {
        if width >= 1 || width <= 255 {
            let _ = self.write(consts::BARCODE_WIDTH);
        }
        if height >= 2 || height <= 6 {
            let _ = self.write(consts::BARCODE_HEIGHT);
        }

        let font = font.to_uppercase();
        let position = position.to_uppercase();
        let kind = kind.to_uppercase().replace("-", "_");
        let font_value = match font.as_ref() {
            "B" => consts::BARCODE_FONT_B,
            "A" | _ => consts::BARCODE_FONT_A
        };
        let txt_value = match position.as_ref() {
            "OFF" => consts::BARCODE_TXT_OFF,
            "ABV" => consts::BARCODE_TXT_ABV,
            "BTH" => consts::BARCODE_TXT_BTH,
            "BLW" | _ => consts::BARCODE_TXT_BLW,
        };
        let kind_value = match kind.as_ref() {
            "UPC_A"  => consts::BARCODE_UPC_A,
            "UPC_E"  => consts::BARCODE_UPC_E,
            "EAN8"   => consts::BARCODE_EAN8,
            "CODE39" => consts::BARCODE_CODE39,
            "ITF"    => consts::BARCODE_ITF,
            "NW7"    => consts::BARCODE_NW7,
            "EAN13" | _ => consts::BARCODE_EAN13
        };
        let _ = self.write(font_value);
        let _ = self.write(txt_value);
        let _ = self.write(kind_value);
        let _ = self.write(code.as_bytes());
        self
    }

    pub fn qrimage(&mut self) -> &mut Printer<W> {
        self
    }

    pub fn qrcode(&mut self,
                  code: &str,
                  version: Option<i32>,
                  level: &str,
                  size: Option<i32>) -> &mut Printer<W> {
        let level = level.to_uppercase();
        let level_value = match level.as_ref() {
            "M" => consts::QR_LEVEL_M,
            "Q" => consts::QR_LEVEL_Q,
            "H" => consts::QR_LEVEL_H,
            "L" | _ => consts::QR_LEVEL_L,
        };
        let _ = self.write(consts::TYPE_QR);
        let _ = self.write(consts::CODE2D);
        let _ = self.write_u8(version.unwrap_or(3) as u8);
        let _ = self.write(level_value);
        let _ = self.write_u8(size.unwrap_or(3) as u8);
        let _ = self.write_u16le(code.len() as u16);
        let _ = self.write(code.as_bytes());
        self
    }

    pub fn cashdraw(&mut self, pin: i32) -> &mut Printer<W> {
        let pin_value = if pin == 5 {
            consts::CD_KICK_5
        } else {
            consts::CD_KICK_2
        };
        let _ = self.write(pin_value);
        self
    }

    pub fn cut(&mut self, part: bool) -> &mut Printer<W> {
        self.print(iter::repeat(consts::EOL)
                   .take(3)
                   .collect::<String>()
                   .as_ref());
        let paper_cut_type = if part {
            consts::PAPER_PART_CUT
        } else {
            consts::PAPER_FULL_CUT
        };
        let _ = self.write(paper_cut_type);
        self
    }

    pub fn bit_image(&mut self,
                    image: &Image,
                    density: Option<&str>) -> &mut Printer<W> {
        let density = density.unwrap_or("d24");
        let density_upper = density.to_uppercase();
        let header = match density_upper.as_ref() {
            "S8"  => consts::BITMAP_S8,
            "D8"  => consts::BITMAP_D8,
            "S24" => consts::BITMAP_S24,
            "D24" | _ => consts::BITMAP_D24,
        };
        let n = if density == "s8" || density == "d8" { 1 } else { 3 };
        self.line_space(0);
        for line in image.bitimage_lines(n*8) {
            let _ = self.write(header);
            let _ = self.write_u16le((line.len() / n as usize) as u16);
            let _ = self.write(line.as_ref());
            self.feed(1);
        }
        self
    }

    pub fn raster(&mut self, image: &Image, mode: Option<&str>) -> &mut Printer<W> {
        let mode_upper = mode.unwrap_or("NORMAL").to_uppercase();
        let header = match mode_upper.as_ref() {
            "DH" => consts::GSV0_DH,
            "DWDH" => consts::GSV0_DWDH,
            "DW" | "NORMAL" | _ => consts::GSV0_DW,
        };
        let _ = self.write(header);
        let _ = self.write_u16le(image.width as u16);
        let _ = self.write_u16le(image.height as u16);
        let _ = self.write(image.get_raster().as_ref());
        self
    }
}
<|endoftext|>


<commit_before>use command::Command;
use vm::VM;

pub struct Program {
    instructions: Vec<Command>,
    instruction_pointer: Option<usize>,
    current_depth: u64,
    pub status: ProgramStatus,
}

#[derive(Clone, Copy, PartialEq, Debug)]
pub enum ProgramStatus {
    Normal,
    Seeking(u64),
}

impl Program {
    pub fn new() -> Program {
        Program {
            instructions: Vec::new(),
            instruction_pointer: None,
            current_depth: 0,
            status: ProgramStatus::Normal,
        }
    }

    pub fn append(&mut self, instructions: &[Command]) {
        self.instructions.extend(instructions.iter().cloned());
        if self.instruction_pointer.is_none() {
            self.instruction_pointer = Some(0);
        }
    }

    pub fn execute(&mut self, vm: &mut VM) {
        match (self.instruction_pointer, self.status) {
            (Some(index), ProgramStatus::Seeking(_)) => {
                let (new_index, new_depth, new_status) = self.handle_jump_forward(vm, index);
                self.instruction_pointer = Some(new_index);
                self.current_depth = new_depth;
                self.status = new_status;
                if new_index < self.instructions.len() { self.execute(vm); }
            }

            (Some(mut index), ProgramStatus::Normal) => {
                while index < self.instructions.len() {
                    match self.instructions[index] {
                        Command::JumpBackward => self.handle_jump_backward(vm, &mut index),

                        Command::JumpForward => {
                            let (new_index, new_depth, new_status) = self.handle_jump_forward(vm, index);
                            index = new_index;
                            self.current_depth = new_depth;
                            self.status = new_status;
                        }

                        command => {
                            vm.apply(command);
                            index += 1;
                        }
                    }
                }

                self.instruction_pointer = Some(index);
            }

            _ => {}
        }
    }

    fn handle_jump_backward(&mut self, vm: &VM, index_ref: &mut usize) {
        match vm.cells[vm.data_pointer] {
            0 => {
                self.current_depth -= 1;
                *index_ref += 1;
            }

            _ => {
                let goal_depth = self.current_depth;
                for index in (0..*index_ref).rev() {
                    match self.instructions[index] {
                        Command::JumpBackward => self.current_depth += 1,
                        Command::JumpForward => {
                            if self.current_depth == goal_depth {
                                *index_ref = index + 1;
                                return;
                            }
                            self.current_depth -= 1;
                        }
                        _ => {}
                    }
                }
                panic!("No starting brace found!");
            }
        }
    }

    fn seek_forward(&self, starting_index: usize) -> (usize, u64, ProgramStatus) {
        match self.status {
            ProgramStatus::Seeking(goal_depth) => {
                let mut depth = self.current_depth;
                for index in starting_index..self.instructions.len() {
                    match self.instructions[index] {
                        Command::JumpForward => depth += 1,
                        Command::JumpBackward => depth  -= 1,
                        _ => {}
                    }
                    if depth == goal_depth {
                        return (index + 1, self.current_depth, ProgramStatus::Normal);
                    }
                }

                return (self.instructions.len()
                       , self.current_depth
                       , ProgramStatus::Seeking(goal_depth));
            }

            ProgramStatus::Normal => return (starting_index, self.current_depth, self.status)
        }
    }

    fn handle_jump_forward(&self, vm: &VM, index: usize) -> (usize, u64, ProgramStatus){
        match (vm.cells[vm.data_pointer], self.status) {
            (0, ProgramStatus::Normal) => return self.seek_forward(index),
            (_, ProgramStatus::Normal) => return (index + 1, self.current_depth + 1, ProgramStatus::Normal),
            (_, ProgramStatus::Seeking(_)) => self.seek_forward(index),

        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    pub fn test_seek_forward_normal() {
        let program = Program {
            instruction_pointer: None,
            current_depth: 0,
            status: ProgramStatus::Seeking(0),
            instructions: vec![
                Command::JumpForward,
                Command::JumpForward,
                Command::JumpBackward,
                Command::JumpBackward,
            ],
        };
        let (new_index, new_depth, new_status) = program.seek_forward(0);
        assert_eq!(new_depth, 0);
        assert_eq!(new_index, 4);
        assert_eq!(new_status, ProgramStatus::Normal);
    }

    #[test]
    pub fn test_seek_forward_seeking() {
        let program = Program {
            instruction_pointer: None,
            current_depth: 0,
            status: ProgramStatus::Seeking(0),
            instructions: vec![
                Command::JumpForward,
                Command::JumpForward,
                Command::JumpBackward,
            ],
        };
        let (new_index, new_depth, new_status) = program.seek_forward(0);
        assert_eq!(new_depth, 1);
        assert_eq!(new_index, 3);
        assert_eq!(new_status, ProgramStatus::Seeking(0));
    }
}
<commit_msg>Streamline handle_jump_forward definitions<commit_after>use command::Command;
use vm::VM;

pub struct Program {
    instructions: Vec<Command>,
    instruction_pointer: Option<usize>,
    current_depth: u64,
    pub status: ProgramStatus,
}

#[derive(Clone, Copy, PartialEq, Debug)]
pub enum ProgramStatus {
    Normal,
    Seeking(u64),
}

impl Program {
    pub fn new() -> Program {
        Program {
            instructions: Vec::new(),
            instruction_pointer: None,
            current_depth: 0,
            status: ProgramStatus::Normal,
        }
    }

    pub fn append(&mut self, instructions: &[Command]) {
        self.instructions.extend(instructions.iter().cloned());
        if self.instruction_pointer.is_none() {
            self.instruction_pointer = Some(0);
        }
    }

    pub fn execute(&mut self, vm: &mut VM) {
        match (self.instruction_pointer, self.status) {
            (Some(index), ProgramStatus::Seeking(_)) => {
                let (new_index, new_depth, new_status) = self.handle_jump_forward(vm, index);
                self.instruction_pointer = Some(new_index);
                self.current_depth = new_depth;
                self.status = new_status;
                if new_index < self.instructions.len() { self.execute(vm); }
            }

            (Some(mut index), ProgramStatus::Normal) => {
                while index < self.instructions.len() {
                    match self.instructions[index] {
                        Command::JumpBackward => self.handle_jump_backward(vm, &mut index),

                        Command::JumpForward => {
                            let (new_index, new_depth, new_status) = self.handle_jump_forward(vm, index);
                            index = new_index;
                            self.current_depth = new_depth;
                            self.status = new_status;
                        }

                        command => {
                            vm.apply(command);
                            index += 1;
                        }
                    }
                }

                self.instruction_pointer = Some(index);
            }

            _ => {}
        }
    }

    fn handle_jump_backward(&mut self, vm: &VM, index_ref: &mut usize) {
        match vm.cells[vm.data_pointer] {
            0 => {
                self.current_depth -= 1;
                *index_ref += 1;
            }

            _ => {
                let goal_depth = self.current_depth;
                for index in (0..*index_ref).rev() {
                    match self.instructions[index] {
                        Command::JumpBackward => self.current_depth += 1,
                        Command::JumpForward => {
                            if self.current_depth == goal_depth {
                                *index_ref = index + 1;
                                return;
                            }
                            self.current_depth -= 1;
                        }
                        _ => {}
                    }
                }
                panic!("No starting brace found!");
            }
        }
    }

    fn seek_forward(&self, starting_index: usize) -> (usize, u64, ProgramStatus) {
        match self.status {
            ProgramStatus::Seeking(goal_depth) => {
                let mut depth = self.current_depth;
                for index in starting_index..self.instructions.len() {
                    match self.instructions[index] {
                        Command::JumpForward => depth += 1,
                        Command::JumpBackward => depth  -= 1,
                        _ => {}
                    }
                    if depth == goal_depth {
                        return (index + 1, self.current_depth, ProgramStatus::Normal);
                    }
                }

                return (self.instructions.len()
                       , self.current_depth
                       , ProgramStatus::Seeking(goal_depth));
            }

            ProgramStatus::Normal => return (starting_index, self.current_depth, self.status)
        }
    }

    fn handle_jump_forward(&self, vm: &VM, index: usize) -> (usize, u64, ProgramStatus){
        match (vm.cells[vm.data_pointer], self.status) {
            (0, ProgramStatus::Normal) => self.seek_forward(index),
            (_, ProgramStatus::Normal) => (index + 1, self.current_depth + 1, ProgramStatus::Normal),
            (_, ProgramStatus::Seeking(_)) => self.seek_forward(index),

        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    pub fn test_seek_forward_normal() {
        let program = Program {
            instruction_pointer: None,
            current_depth: 0,
            status: ProgramStatus::Seeking(0),
            instructions: vec![
                Command::JumpForward,
                Command::JumpForward,
                Command::JumpBackward,
                Command::JumpBackward,
            ],
        };
        let (new_index, new_depth, new_status) = program.seek_forward(0);
        assert_eq!(new_depth, 0);
        assert_eq!(new_index, 4);
        assert_eq!(new_status, ProgramStatus::Normal);
    }

    #[test]
    pub fn test_seek_forward_seeking() {
        let program = Program {
            instruction_pointer: None,
            current_depth: 0,
            status: ProgramStatus::Seeking(0),
            instructions: vec![
                Command::JumpForward,
                Command::JumpForward,
                Command::JumpBackward,
            ],
        };
        let (new_index, new_depth, new_status) = program.seek_forward(0);
        assert_eq!(new_depth, 1);
        assert_eq!(new_index, 3);
        assert_eq!(new_status, ProgramStatus::Seeking(0));
    }
}
<|endoftext|>


<commit_before>extern crate futures;
extern crate irc;
extern crate tokio_core;

use std::default::Default;
use futures::future;
use irc::error;
use irc::client::prelude::*;
use tokio_core::reactor::Core;

fn main() {
    let cfg1 = Config {
        nickname: Some("pickles1".to_owned()),
        server: Some("irc.fyrechat.net".to_owned()),
        channels: Some(vec!["#irc-crate".to_owned()]),
        ..Default::default()
    };

    let cfg2 = Config {
        nickname: Some("pickles2".to_owned()),
        server: Some("irc.fyrechat.net".to_owned()),
        channels: Some(vec!["#irc-crate".to_owned()]),
        ..Default::default()
    };

    let configs = vec![cfg1, cfg2];

    let (futures, mut reactor) = configs.iter().fold(
        (vec![], Core::new().unwrap()),
        |(mut acc, mut reactor), config| {
            let handle = reactor.handle();
            // First, we run the future representing the connection to the server.
            // After this is complete, we have connected and can send and receive messages.
            let server = reactor.run(IrcServer::new_future(handle, config).unwrap()).unwrap();
            server.identify().unwrap();

            // Add the future for processing messages from the current server to the accumulator.
            acc.push(server.stream().for_each(move |message| {
                process_msg(&server, message)
            }));

            // We then thread through the updated accumulator and the reactor.
            (acc, reactor)
        }
    );

    // Here, we join on all of the futures representing the message handling for each server.
    reactor.run(future::join_all(futures)).unwrap();
}

fn process_msg(server: &IrcServer, message: Message) -> error::Result<()> {
    print!("{}", message);
    match message.command {
        Command::PRIVMSG(ref target, ref msg) => {
            if msg.contains("pickles") {
                server.send_privmsg(target, "Hi!")?;
            }
        }
        _ => (),
    }
    Ok(())
}
<commit_msg>Removed nothreads_alt because that behavior is the default with reactors.<commit_after><|endoftext|>


<commit_before>use std::thread;
use std::sync::mpsc::{self, channel, TryRecvError};
use std::io::{Read, ErrorKind};
use std::collections::HashMap;
use std::time::Duration;

use mio::*;
use mio::tcp::TcpListener;

use ladspa::{PluginDescriptor, Plugin, PortConnection};
use ladspa::{Port, PortDescriptor};
use ladspa::{PROP_NONE, HINT_INTEGER, DefaultValue};

use super::BASE_PORT;
use super::packet::{BYTE_BUFFER_SIZE, Packet};

type ClientPacket = (u64, Packet);

const SERVER: Token = Token(0);

pub struct Receiver {
    sample_rate: u64,
    channel: u16,
    packet_rx: Option<mpsc::Receiver<ClientPacket>>,
    active_packets: Vec<ClientPacket>,
    notify_tx: Option<Sender<<PacketReceiver as Handler>::Message>>,
    client_time_map: HashMap<u64, u64>,
}

impl Receiver {
    pub fn new(_: &PluginDescriptor, sample_rate: u64) -> Box<Plugin + Send> {
        println!("receiver::new");
        Box::new(Receiver {
            sample_rate: sample_rate,
            channel: 0,
            packet_rx: None,
            active_packets: Vec::new(),
            notify_tx: None,
            client_time_map: HashMap::new(),
        })
    }

    pub fn get_descriptor() -> PluginDescriptor {
        PluginDescriptor {
            unique_id: 5878,
            label: "feedback_rx",
            properties: PROP_NONE,
            name: "Feedback Receiver",
            maker: "Noah Weninger",
            copyright: "None",
            ports: vec![Port {
                name: "Left Audio In",
                desc: PortDescriptor::AudioInput,
                ..Default::default()
            },
            Port {
                name: "Right Audio In",
                desc: PortDescriptor::AudioInput,
                ..Default::default()
            },
            Port {
                name: "Left Audio Out",
                desc: PortDescriptor::AudioOutput,
                ..Default::default()
            },
            Port {
                name: "Right Audio Out",
                desc: PortDescriptor::AudioOutput,
                ..Default::default()
            },
            Port {
                name: "Channel",
                desc: PortDescriptor::ControlInput,
                hint: Some(HINT_INTEGER),
                default: Some(DefaultValue::Value0),
                lower_bound: Some(0_f32),
                upper_bound: Some(255_f32),
            },
            Port {
                name: "Dry",
                desc: PortDescriptor::ControlInput,
                hint: None,
                default: Some(DefaultValue::Value1),
                lower_bound: Some(0_f32),
                upper_bound: Some(1_f32),
            },
            Port {
                name: "Recv",
                desc: PortDescriptor::ControlInput,
                hint: None,
                default: Some(DefaultValue::Value1),
                lower_bound: Some(0_f32),
                upper_bound: Some(1_f32),
            }],
            new: Receiver::new,
        }
    }

    fn init_server(&mut self) {
        let (data_tx, data_rx) = channel();
        self.packet_rx = Some(data_rx);

        let channel = self.channel;
        let mut event_loop = EventLoop::new().unwrap();
        self.notify_tx = Some(event_loop.channel());
        thread::spawn(move || {
            let addr = format!("127.0.0.1:{}", BASE_PORT + channel).parse().unwrap();
            let server;
            loop {
                match TcpListener::bind(&addr) {
                    Ok(s) => {
                        server = s;
                        break;
                    }
                    Err(_) => {}
                }
            }
            event_loop.register(&server, SERVER).unwrap();
            event_loop.run(&mut PacketReceiver {
                          server: server,
                          data_tx: data_tx,
                          client_id: 0,
                      })
                      .unwrap();
        });
    }

    fn kill_server(&mut self) {
        self.notify_tx.as_ref().unwrap().send(()).unwrap();
    }
}

impl Plugin for Receiver {
    fn run<'a>(&mut self, sample_count: usize, ports: &[&'a PortConnection<'a>]) {
        let inputl = ports[0].unwrap_audio();
        let inputr = ports[1].unwrap_audio();
        let mut outputl = ports[2].unwrap_audio_mut();
        let mut outputr = ports[3].unwrap_audio_mut();

        let channel = *ports[4].unwrap_control() as u16;
        let dry = ports[5].unwrap_control();
        let wet = ports[6].unwrap_control();

        if channel != self.channel {
            self.channel = channel;
            println!("set channel {}", self.channel);
            self.kill_server();
            self.init_server();
            return;
        }

        loop {
            let packet = match self.packet_rx.as_ref().unwrap().try_recv() {
                Ok(packet) => packet,
                Err(TryRecvError::Disconnected) => {
                    println!("ladspa packet receive failed, dead channel!");
                    self.kill_server();
                    self.init_server();
                    break;
                }
                Err(TryRecvError::Empty) => {
                    break;
                }
            };
            self.active_packets.push(packet);
        }

        for i in 0..sample_count {
            outputl[i] = inputl[i]*(*dry);
            outputr[i] = inputr[i]*(*dry);
        }

        let mut read_clients = Vec::new();
        for &(ref client_id, ref packet) in &self.active_packets {
            let client_time = self.client_time_map.get(client_id).map(|x| *x).unwrap_or(0);
            for i in 0..sample_count {
                let (l, r) = packet.read(client_time + i as u64);
                outputl[i] += l*(*wet);
                outputr[i] += r*(*wet);
            }
            read_clients.push(*client_id);
        }
        for client_id in read_clients {
            let client_time = self.client_time_map.get(&client_id).map(|x| *x).unwrap_or(0);
            self.client_time_map.insert(client_id, client_time + sample_count as u64);
        }

        let mut i = self.active_packets.len();
        while i > 0 {
            i -= 1;
            let complete = {
                let (ref client_id, ref packet) = self.active_packets[i];
                let client_time = self.client_time_map[client_id];
                packet.complete(client_time)
            };
            if complete {
                self.active_packets.remove(i);
            }
        }
    }

    fn activate(&mut self) {
        println!("activate {}", self.channel);
        self.client_time_map.clear();
        self.init_server();
    }

    fn deactivate(&mut self) {
        println!("deactivate {}", self.channel);
        self.kill_server();
    }
}

struct PacketReceiver {
    server: TcpListener,
    data_tx: mpsc::Sender<ClientPacket>,
    client_id: u64,
}

impl Handler for PacketReceiver {
    type Timeout = ();
        type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<Self>, token: Token, events: EventSet) {
        match token {
            SERVER => {
                // Only receive readable events
                assert!(events.is_readable());

                println!("server wait");
                match self.server.accept() {
                    Ok(Some(mut socket)) => {
                        socket.set_nodelay(true).unwrap();
                        let tx = self.data_tx.clone();
                        let mut buf = [0; BYTE_BUFFER_SIZE];
                        let mut buf_pos = 0;
                        let client_id = self.client_id;
                        println!("server accept client {}", client_id);
                        self.client_id += 1;
                        loop {
                            let res = socket.read(&mut buf[buf_pos..]);
                            match res {
                                Ok(num_read) => {
                                    //println!("server read {}", num_read);
                                    // if we got a length zero read, the connection is done.
                                    if num_read == 0 {
                                        println!("read zero bytes");
                                        return;
                                    }

                                    // check if we've filled the buffer
                                    buf_pos += num_read;
                                    if buf_pos != BYTE_BUFFER_SIZE {
                                        continue;
                                    }
                                    buf_pos = 0;
                                }
                                Err(e) => {
                                    if e.kind() == ErrorKind::WouldBlock {
                                        //TODO this is a quick hack to reduce CPU usage
                                        thread::sleep(Duration::from_millis(1));
                                        continue;
                                    }
                                    panic!(e);
                                }
                            }
                            let packet = Packet::parse(&buf[..]);
                            if let Err(_) = tx.send((client_id, packet)) {
                                println!("send packet to ladspa error! channel is dead.");
                                return;
                            }
                        }
                    }
                    Ok(None) => {
                        println!("the server socket wasn't actually ready");
                    }
                    Err(e) => {
                        println!("listener.accept() errored: {}", e);
                        // event_loop.shutdown();
                    }
                }
            }
            _ => panic!("Received unknown token"),
        }
    }
    fn notify(&mut self, event_loop: &mut EventLoop<Self>, msg: Self::Message) {
        event_loop.shutdown();
    }
}
<commit_msg>maybe more latency<commit_after>use std::thread;
use std::sync::mpsc::{self, channel, TryRecvError};
use std::io::{Read, ErrorKind};
use std::collections::HashMap;
use std::time::Duration;

use mio::*;
use mio::tcp::TcpListener;

use ladspa::{PluginDescriptor, Plugin, PortConnection};
use ladspa::{Port, PortDescriptor};
use ladspa::{PROP_NONE, HINT_INTEGER, DefaultValue};

use super::BASE_PORT;
use super::packet::{BYTE_BUFFER_SIZE, Packet};

type ClientPacket = (u64, Packet);

const SERVER: Token = Token(0);

pub struct Receiver {
    sample_rate: u64,
    channel: u16,
    packet_rx: Option<mpsc::Receiver<ClientPacket>>,
    active_packets: Vec<ClientPacket>,
    notify_tx: Option<Sender<<PacketReceiver as Handler>::Message>>,
    client_time_map: HashMap<u64, u64>,
}

impl Receiver {
    pub fn new(_: &PluginDescriptor, sample_rate: u64) -> Box<Plugin + Send> {
        println!("receiver::new");
        Box::new(Receiver {
            sample_rate: sample_rate,
            channel: 0,
            packet_rx: None,
            active_packets: Vec::new(),
            notify_tx: None,
            client_time_map: HashMap::new(),
        })
    }

    pub fn get_descriptor() -> PluginDescriptor {
        PluginDescriptor {
            unique_id: 5878,
            label: "feedback_rx",
            properties: PROP_NONE,
            name: "Feedback Receiver",
            maker: "Noah Weninger",
            copyright: "None",
            ports: vec![Port {
                name: "Left Audio In",
                desc: PortDescriptor::AudioInput,
                ..Default::default()
            },
            Port {
                name: "Right Audio In",
                desc: PortDescriptor::AudioInput,
                ..Default::default()
            },
            Port {
                name: "Left Audio Out",
                desc: PortDescriptor::AudioOutput,
                ..Default::default()
            },
            Port {
                name: "Right Audio Out",
                desc: PortDescriptor::AudioOutput,
                ..Default::default()
            },
            Port {
                name: "Channel",
                desc: PortDescriptor::ControlInput,
                hint: Some(HINT_INTEGER),
                default: Some(DefaultValue::Value0),
                lower_bound: Some(0_f32),
                upper_bound: Some(255_f32),
            },
            Port {
                name: "Dry",
                desc: PortDescriptor::ControlInput,
                hint: None,
                default: Some(DefaultValue::Value1),
                lower_bound: Some(0_f32),
                upper_bound: Some(1_f32),
            },
            Port {
                name: "Recv",
                desc: PortDescriptor::ControlInput,
                hint: None,
                default: Some(DefaultValue::Value1),
                lower_bound: Some(0_f32),
                upper_bound: Some(1_f32),
            }],
            new: Receiver::new,
        }
    }

    fn init_server(&mut self) {
        let (data_tx, data_rx) = channel();
        self.packet_rx = Some(data_rx);

        let channel = self.channel;
        let mut event_loop = EventLoop::new().unwrap();
        self.notify_tx = Some(event_loop.channel());
        thread::spawn(move || {
            let addr = format!("127.0.0.1:{}", BASE_PORT + channel).parse().unwrap();
            let server;
            loop {
                match TcpListener::bind(&addr) {
                    Ok(s) => {
                        server = s;
                        break;
                    }
                    Err(_) => {}
                }
            }
            event_loop.register(&server, SERVER).unwrap();
            event_loop.run(&mut PacketReceiver {
                          server: server,
                          data_tx: data_tx,
                          client_id: 0,
                      })
                      .unwrap();
        });
    }

    fn kill_server(&mut self) {
        self.notify_tx.as_ref().unwrap().send(()).unwrap();
    }
}

impl Plugin for Receiver {
    fn run<'a>(&mut self, sample_count: usize, ports: &[&'a PortConnection<'a>]) {
        let inputl = ports[0].unwrap_audio();
        let inputr = ports[1].unwrap_audio();
        let mut outputl = ports[2].unwrap_audio_mut();
        let mut outputr = ports[3].unwrap_audio_mut();

        let channel = *ports[4].unwrap_control() as u16;
        let dry = ports[5].unwrap_control();
        let wet = ports[6].unwrap_control();

        if channel != self.channel {
            self.channel = channel;
            println!("set channel {}", self.channel);
            self.kill_server();
            self.init_server();
            return;
        }

        loop {
            let packet = match self.packet_rx.as_ref().unwrap().try_recv() {
                Ok(packet) => packet,
                Err(TryRecvError::Disconnected) => {
                    println!("ladspa packet receive failed, dead channel!");
                    self.kill_server();
                    self.init_server();
                    break;
                }
                Err(TryRecvError::Empty) => {
                    break;
                }
            };
            self.active_packets.push(packet);
        }

        for i in 0..sample_count {
            outputl[i] = inputl[i]*(*dry);
            outputr[i] = inputr[i]*(*dry);
        }

        let mut read_clients = Vec::new();
        for &(ref client_id, ref packet) in &self.active_packets {
            let client_time = self.client_time_map.get(client_id).map(|x| *x).unwrap_or(0);
            for i in 0..sample_count {
                let (l, r) = packet.read(client_time + i as u64);
                outputl[i] += l*(*wet);
                outputr[i] += r*(*wet);
            }
            read_clients.push(*client_id);
        }
        for client_id in read_clients {
            let client_time = self.client_time_map.get(&client_id).map(|x| *x).unwrap_or(0);
            self.client_time_map.insert(client_id, client_time + sample_count as u64);
        }

        let mut i = self.active_packets.len();
        while i > 0 {
            i -= 1;
            let complete = {
                let (ref client_id, ref packet) = self.active_packets[i];
                let client_time = self.client_time_map[client_id];
                packet.complete(client_time)
            };
            if complete {
                self.active_packets.remove(i);
            }
        }
    }

    fn activate(&mut self) {
        println!("activate {}", self.channel);
        self.client_time_map.clear();
        self.init_server();
    }

    fn deactivate(&mut self) {
        println!("deactivate {}", self.channel);
        self.kill_server();
    }
}

struct PacketReceiver {
    server: TcpListener,
    data_tx: mpsc::Sender<ClientPacket>,
    client_id: u64,
}

impl Handler for PacketReceiver {
    type Timeout = ();
        type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<Self>, token: Token, events: EventSet) {
        match token {
            SERVER => {
                // Only receive readable events
                assert!(events.is_readable());

                println!("server wait");
                match self.server.accept() {
                    Ok(Some(mut socket)) => {
                        socket.set_nodelay(true).unwrap();
                        let tx = self.data_tx.clone();
                        let mut buf = [0; BYTE_BUFFER_SIZE];
                        let mut buf_pos = 0;
                        let client_id = self.client_id;
                        println!("server accept client {}", client_id);
                        self.client_id += 1;
                        loop {
                            let res = socket.read(&mut buf[buf_pos..]);
                            match res {
                                Ok(num_read) => {
                                    //println!("server read {}", num_read);
                                    // if we got a length zero read, the connection is done.
                                    if num_read == 0 {
                                        println!("read zero bytes");
                                        return;
                                    }

                                    // check if we've filled the buffer
                                    buf_pos += num_read;
                                    if buf_pos != BYTE_BUFFER_SIZE {
                                        continue;
                                    }
                                    buf_pos = 0;
                                }
                                Err(e) => {
                                    if e.kind() == ErrorKind::WouldBlock {
                                        //TODO this is a quick hack to reduce CPU usage
                                        thread::sleep(Duration::from_millis(10));
                                        continue;
                                    }
                                    panic!(e);
                                }
                            }
                            let packet = Packet::parse(&buf[..]);
                            if let Err(_) = tx.send((client_id, packet)) {
                                println!("send packet to ladspa error! channel is dead.");
                                return;
                            }
                        }
                    }
                    Ok(None) => {
                        println!("the server socket wasn't actually ready");
                    }
                    Err(e) => {
                        println!("listener.accept() errored: {}", e);
                        // event_loop.shutdown();
                    }
                }
            }
            _ => panic!("Received unknown token"),
        }
    }
    fn notify(&mut self, event_loop: &mut EventLoop<Self>, msg: Self::Message) {
        event_loop.shutdown();
    }
}
<|endoftext|>


<commit_before>extern crate ropey;

use std::fs::File;
use std::io;

use ropey::{Rope, RopeSlice};

struct TextBuffer {
    text: Rope,
    path: String,
    dirty: bool,
}

impl TextBuffer {
    fn from_path(path: &str) -> io::Result<TextBuffer> {
        let text = Rope::from_reader(&mut io::BufReader::new(File::open(&path)?))?;
        Ok(TextBuffer {
            text: text,
            path: path.to_string(),
            dirty: false,
        })
    }

    fn get_line<'a>(&'a self, idx: usize) -> RopeSlice<'a> {
        self.text.line(idx)
    }

    fn edit(&mut self, start: usize, end: usize, text: &str) {
        if start != end {
            self.text.remove(start..end);
        }
        if text.len() > 0 {
            self.text.insert(start, text);
        }
        self.dirty = true;
    }
}

fn main() {
    // Get filepath from commandline
    let filepath = if std::env::args().count() > 1 {
        std::env::args().nth(1).unwrap()
    } else {
        println!(
            "You must pass a filepath!  Only recieved {} arguments.",
            std::env::args().count()
        );
        panic!()
    };

    let mut buf = TextBuffer::from_path(&filepath).unwrap();

    buf.edit(3, 5, "Hello!");
    println!("{}", buf.get_line(2));
    println!("{}", buf.path);
}
<commit_msg>Fleshed out text buffer example with iterator methods.<commit_after>#![allow(dead_code)]

extern crate ropey;

use std::fs::File;
use std::io;

use ropey::{Rope, RopeSlice};
use ropey::iter::{Bytes, Chars, Chunks, Graphemes, Lines};

struct TextBuffer {
    text: Rope,
    path: String,
    dirty: bool,
}

impl TextBuffer {
    fn from_path(path: &str) -> io::Result<TextBuffer> {
        let text = Rope::from_reader(&mut io::BufReader::new(File::open(&path)?))?;
        Ok(TextBuffer {
            text: text,
            path: path.to_string(),
            dirty: false,
        })
    }

    fn get_line<'a>(&'a self, idx: usize) -> RopeSlice<'a> {
        self.text.line(idx)
    }

    fn bytes<'a>(&'a self) -> Bytes<'a> {
        self.text.bytes()
    }

    fn chars<'a>(&'a self) -> Chars<'a> {
        self.text.chars()
    }

    fn graphemes<'a>(&'a self) -> Graphemes<'a> {
        self.text.graphemes()
    }

    fn lines<'a>(&'a self) -> Lines<'a> {
        self.text.lines()
    }

    fn chunks<'a>(&'a self) -> Chunks<'a> {
        self.text.chunks()
    }

    fn edit(&mut self, start: usize, end: usize, text: &str) {
        if start != end {
            self.text.remove(start..end);
        }
        if text.len() > 0 {
            self.text.insert(start, text);
        }
        self.dirty = true;
    }
}

fn main() {
    // Get filepath from commandline
    let filepath = if std::env::args().count() > 1 {
        std::env::args().nth(1).unwrap()
    } else {
        println!(
            "You must pass a filepath!  Only recieved {} arguments.",
            std::env::args().count()
        );
        panic!()
    };

    let mut buf = TextBuffer::from_path(&filepath).unwrap();

    buf.edit(3, 5, "Hello!");
    println!("{}", buf.get_line(2));
}
<|endoftext|>