<commit_before>// xfail-pretty

// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod std;

use std::bitv;
use core::io::{ReaderUtil, WriterUtil};
use core::io;

// Computes a single solution to a given 9x9 sudoku
//
// Call with "-" to read input sudoku from stdin
//
// The expected line-based format is:
//
// 9,9
// <row>,<column>,<color>
// ...
//
// Row and column are 0-based (i.e. <= 8) and color is 1-based (>=1,<=9).
// A color of 0 indicates an empty field.
//
// If called without arguments, sudoku solves a built-in example sudoku
//

// internal type of sudoku grids
type grid = ~[~[u8]];

// exported type of sudoku grids
pub enum grid_t { grid_ctor(grid), }

// read a sudoku problem from file f
pub fn read_grid(f: @io::Reader) -> grid_t {
    fail_unless!(f.read_line() == ~"9,9"); /* assert first line is exactly "9,9" */

    let mut g = vec::from_fn(10u, {|_i|
        vec::from_elem(10u, 0 as u8)
    });
    while !f.eof() {
        let comps = str::split_char(str::trim(f.read_line()), ',');
        if vec::len(comps) >= 3u {
            let row     = uint::from_str(comps[0]).get() as u8;
            let col     = uint::from_str(comps[1]).get() as u8;
            g[row][col] = uint::from_str(comps[2]).get() as u8;
        }
    }
    return grid_ctor(g);
}

// solve sudoku grid
pub fn solve_grid(g: grid_t) {
    fn next_color(mut g: grid, row: u8, col: u8, start_color: u8) -> bool {
        if start_color < 10u8 {
            // colors not yet used
            let mut avail = bitv::Bitv::new(10u, false);
            for u8::range(start_color, 10u8) |color| {
                avail.set(color as uint, true);
            }

            // drop colors already in use in neighbourhood
            drop_colors(copy g, copy avail, row, col);

            // find first remaining color that is available
            for uint::range(1u, 10u) |i| {
                if avail.get(i) {
                    g[row][col] = i as u8;
                    return true;
                }
            };
        }
        g[row][col] = 0u8;
        return false;
    }

    // find colors available in neighbourhood of (row, col)
    fn drop_colors(g: grid, avail: bitv::Bitv, row: u8, col: u8) {
        fn drop_color(g: grid, mut colors: bitv::Bitv, row: u8, col: u8) {
            let color = g[row][col];
            if color != 0u8 { colors.set(color as uint, false); }
        }

        let it = |a,b| drop_color(copy g, copy avail, a, b);

        for u8::range(0u8, 9u8) |idx| {
            it(idx, col); /* check same column fields */
            it(row, idx); /* check same row fields */
        }

        // check same block fields
        let row0 = (row / 3u8) * 3u8;
        let col0 = (col / 3u8) * 3u8;
        for u8::range(row0, row0 + 3u8) |alt_row| {
            for u8::range(col0, col0 + 3u8) |alt_col| { it(alt_row, alt_col); }
        }
    }

    let mut work: ~[(u8, u8)] = ~[]; /* queue of uncolored fields */
    for u8::range(0u8, 9u8) |row| {
        for u8::range(0u8, 9u8) |col| {
            let color = (*g)[row][col];
            if color == 0u8 { work += ~[(row, col)]; }
        }
    }

    let mut ptr = 0u;
    let end = vec::len(work);
    while (ptr < end) {
        let (row, col) = work[ptr];
        // is there another color to try?
        if next_color(copy *g, row, col, (*g)[row][col] + (1 as u8)) {
            //  yes: advance work list
            ptr = ptr + 1u;
        } else {
            // no: redo this field aft recoloring pred; unless there is none
            if ptr == 0u { fail!(~"No solution found for this sudoku"); }
            ptr = ptr - 1u;
        }
    }
}

pub fn write_grid(f: @io::Writer, g: grid_t) {
    for u8::range(0u8, 9u8) |row| {
        f.write_str(fmt!("%u", (*g)[row][0] as uint));
        for u8::range(1u8, 9u8) |col| {
            f.write_str(fmt!(" %u", (*g)[row][col] as uint));
        }
        f.write_char('\n');
     }
}

fn main() {
    let args = os::args();
    let grid = if vec::len(args) == 1u {
        // FIXME create sudoku inline since nested vec consts dont work yet
        // (#3733)
        let mut g = vec::from_fn(10u, |_i| {
            vec::from_elem(10u, 0 as u8)
        });
        g[0][1] = 4u8;
        g[0][3] = 6u8;
        g[0][7] = 3u8;
        g[0][8] = 2u8;
        g[1][2] = 8u8;
        g[1][4] = 2u8;
        g[2][0] = 7u8;
        g[2][3] = 8u8;
        g[3][3] = 5u8;
        g[4][1] = 5u8;
        g[4][5] = 3u8;
        g[4][6] = 6u8;
        g[5][0] = 6u8;
        g[5][1] = 8u8;
        g[5][7] = 9u8;
        g[6][1] = 9u8;
        g[6][2] = 5u8;
        g[6][5] = 6u8;
        g[6][7] = 7u8;
        g[7][4] = 4u8;
        g[7][7] = 6u8;
        g[8][0] = 4u8;
        g[8][5] = 7u8;
        g[8][6] = 2u8;
        g[8][8] = 3u8;
        grid_ctor(g)
    } else {
        read_grid(io::stdin())
    };
    solve_grid(copy grid);
    write_grid(io::stdout(), grid);
}

<commit_msg>auto merge of #5420 : boggle/rust/sudoku-with-traits, r=graydon<commit_after>// xfail-pretty

// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod std;

use core::io::{ReaderUtil, WriterUtil};
use core::io;
use core::unstable::intrinsics::cttz16;

// Computes a single solution to a given 9x9 sudoku
//
// Call with "-" to read input sudoku from stdin
//
// The expected line-based format is:
//
// 9,9
// <row>,<column>,<color>
// ...
//
// Row and column are 0-based (i.e. <= 8) and color is 1-based (>=1,<=9).
// A color of 0 indicates an empty field.
//
// If called without arguments, sudoku solves a built-in example sudoku
//

// internal type of sudoku grids
type grid = ~[~[u8]];

struct Sudoku {
    grid: grid
}

pub impl Sudoku {
    static pub fn new(g: grid) -> Sudoku {
        return Sudoku { grid: g }
    }

    static pub fn from_vec(vec: &[[u8 * 9] * 9]) -> Sudoku {
        let mut g = do vec::from_fn(9u) |i| {
            do vec::from_fn(9u) |j| { vec[i][j] }
        };
        return Sudoku::new(g)
    }

    pub fn equal(&self, other: &Sudoku) -> bool {
        for u8::range(0u8, 9u8) |row| {
            for u8::range(0u8, 9u8) |col| {
                if self.grid[row][col] != other.grid[row][col] {
                    return false;
                }
            }
        }
        return true;
    }

    static pub fn read(reader: @io::Reader) -> Sudoku {
        fail_unless!(reader.read_line() == ~"9,9"); /* assert first line is exactly "9,9" */

        let mut g = vec::from_fn(10u, { |_i| ~[0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8] });
        while !reader.eof() {
            let comps = str::split_char(str::trim(reader.read_line()), ',');
            if vec::len(comps) == 3u {
                let row     = uint::from_str(comps[0]).get() as u8;
                let col     = uint::from_str(comps[1]).get() as u8;
                g[row][col] = uint::from_str(comps[2]).get() as u8;
            }
            else {
                fail!(~"Invalid sudoku file");
            }
        }
        return Sudoku::new(g)
    }

    pub fn write(&self, writer: @io::Writer) {
        for u8::range(0u8, 9u8) |row| {
            writer.write_str(fmt!("%u", self.grid[row][0] as uint));
            for u8::range(1u8, 9u8) |col| {
                writer.write_str(fmt!(" %u", self.grid[row][col] as uint));
            }
            writer.write_char('\n');
         }
    }

    // solve sudoku grid
    pub fn solve(&mut self) {
        let mut work: ~[(u8, u8)] = ~[]; /* queue of uncolored fields */
        for u8::range(0u8, 9u8) |row| {
            for u8::range(0u8, 9u8) |col| {
                let color = self.grid[row][col];
                if color == 0u8 { work += ~[(row, col)]; }
            }
        }

        let mut ptr = 0u;
        let end = vec::len(work);
        while (ptr < end) {
            let (row, col) = work[ptr];
            // is there another color to try?
            if self.next_color(row, col, self.grid[row][col] + (1 as u8)) {
                //  yes: advance work list
                ptr = ptr + 1u;
            } else {
                // no: redo this field aft recoloring pred; unless there is none
                if ptr == 0u { fail!(~"No solution found for this sudoku"); }
                ptr = ptr - 1u;
            }
        }
    }

    fn next_color(&mut self, row: u8, col: u8, start_color: u8) -> bool {
        if start_color < 10u8 {
            // colors not yet used
            let mut avail = ~Colors::new(start_color);

            // drop colors already in use in neighbourhood
            self.drop_colors(avail, row, col);

            // find first remaining color that is available
            let next = avail.next();
            self.grid[row][col] = next;
            return 0u8 != next;
        }
        self.grid[row][col] = 0u8;
        return false;
    }

    // find colors available in neighbourhood of (row, col)
    fn drop_colors(&mut self, avail: &mut Colors, row: u8, col: u8) {
        for u8::range(0u8, 9u8) |idx| {
            avail.remove(self.grid[idx][col]); /* check same column fields */
            avail.remove(self.grid[row][idx]); /* check same row fields */
        }

        // check same block fields
        let row0 = (row / 3u8) * 3u8;
        let col0 = (col / 3u8) * 3u8;
        for u8::range(row0, row0 + 3u8) |alt_row| {
            for u8::range(col0, col0 + 3u8) |alt_col| { avail.remove(self.grid[alt_row][alt_col]); }
        }
    }
}

// Stores available colors as simple bitfield, bit 0 is always unset
struct Colors(u16);

const heads: u16 = (1u16 << 10) - 1; /* bits 9..0 */

impl Colors {
    static fn new(start_color: u8) -> Colors {
        // Sets bits 9..start_color
        let tails = !0u16 << start_color;
        return Colors(heads & tails);
    }

    fn next(&self) -> u8 {
        let val = **self & heads;
        if (0u16 == val) {
            return 0u8;
        }
        else
        {
            return cttz16(val as i16) as u8;
        }
    }

    fn remove(&mut self, color: u8) {
        if color != 0u8 {
            let val  = **self;
            let mask = !(1u16 << color);
            *self    = Colors(val & mask);
        }
    }
}

const default_sudoku: [[u8 * 9] * 9] = [
         /* 0    1    2    3    4    5    6    7    8    */
  /* 0 */  [0u8, 4u8, 0u8, 6u8, 0u8, 0u8, 0u8, 3u8, 2u8],
  /* 1 */  [0u8, 0u8, 8u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8],
  /* 2 */  [7u8, 0u8, 0u8, 8u8, 0u8, 0u8, 0u8, 0u8, 0u8],
  /* 3 */  [0u8, 0u8, 0u8, 5u8, 0u8, 0u8, 0u8, 0u8, 0u8],
  /* 4 */  [0u8, 5u8, 0u8, 0u8, 0u8, 3u8, 6u8, 0u8, 0u8],
  /* 5 */  [6u8, 8u8, 0u8, 0u8, 0u8, 0u8, 0u8, 9u8, 0u8],
  /* 6 */  [0u8, 9u8, 5u8, 0u8, 0u8, 6u8, 0u8, 7u8, 0u8],
  /* 7 */  [0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 6u8, 0u8],
  /* 8 */  [4u8, 0u8, 0u8, 0u8, 0u8, 7u8, 2u8, 0u8, 3u8]
];

#[cfg(test)]
const default_solution: [[u8 * 9] * 9] = [
         /* 0    1    2    3    4    5    6    7    8    */
  /* 0 */  [1u8, 4u8, 9u8, 6u8, 7u8, 5u8, 8u8, 3u8, 2u8],
  /* 1 */  [5u8, 3u8, 8u8, 1u8, 2u8, 9u8, 7u8, 4u8, 6u8],
  /* 2 */  [7u8, 2u8, 6u8, 8u8, 3u8, 4u8, 1u8, 5u8, 9u8],
  /* 3 */  [9u8, 1u8, 4u8, 5u8, 6u8, 8u8, 3u8, 2u8, 7u8],
  /* 4 */  [2u8, 5u8, 7u8, 4u8, 9u8, 3u8, 6u8, 1u8, 8u8],
  /* 5 */  [6u8, 8u8, 3u8, 7u8, 1u8, 2u8, 5u8, 9u8, 4u8],
  /* 6 */  [3u8, 9u8, 5u8, 2u8, 8u8, 6u8, 4u8, 7u8, 1u8],
  /* 7 */  [8u8, 7u8, 2u8, 3u8, 4u8, 1u8, 9u8, 6u8, 5u8],
  /* 8 */  [4u8, 6u8, 1u8, 9u8, 5u8, 7u8, 2u8, 8u8, 3u8]
];

#[test]
fn colors_new_works() {
    fail_unless!(*Colors::new(1) == 1022u16);
    fail_unless!(*Colors::new(2) == 1020u16);
    fail_unless!(*Colors::new(3) == 1016u16);
    fail_unless!(*Colors::new(4) == 1008u16);
    fail_unless!(*Colors::new(5) == 992u16);
    fail_unless!(*Colors::new(6) == 960u16);
    fail_unless!(*Colors::new(7) == 896u16);
    fail_unless!(*Colors::new(8) == 768u16);
    fail_unless!(*Colors::new(9) == 512u16);
}

#[test]
fn colors_next_works() {
    fail_unless!(Colors(0).next() == 0u8);
    fail_unless!(Colors(2).next() == 1u8);
    fail_unless!(Colors(4).next() == 2u8);
    fail_unless!(Colors(8).next() == 3u8);
    fail_unless!(Colors(16).next() == 4u8);
    fail_unless!(Colors(32).next() == 5u8);
    fail_unless!(Colors(64).next() == 6u8);
    fail_unless!(Colors(128).next() == 7u8);
    fail_unless!(Colors(256).next() == 8u8);
    fail_unless!(Colors(512).next() == 9u8);
    fail_unless!(Colors(1024).next() == 0u8);
}

#[test]
fn colors_remove_works() {
    // GIVEN
    let mut colors = Colors::new(1);

    // WHEN
    colors.remove(1);

    // THEN
    fail_unless!(colors.next() == 2u8);
}

#[test]
fn check_default_sudoku_solution() {
    // GIVEN
    let mut sudoku = Sudoku::from_vec(&default_sudoku);
    let solution   = Sudoku::from_vec(&default_solution);

    // WHEN
    sudoku.solve();

    // THEN
    fail_unless!(sudoku.equal(&solution));
}

fn main() {
    let args        = os::args();
    let use_default = vec::len(args) == 1u;
    let mut sudoku = if use_default {
        Sudoku::from_vec(&default_sudoku)
    } else {
        Sudoku::read(io::stdin())
    };
    sudoku.solve();
    sudoku.write(io::stdout());
}

<|endoftext|>


<commit_before>#![crate_id(name="base64", vers="1.0.0", author="Jordy Dickinson")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordy Dickinson <jordy.dickinson@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE file
 * that was distributed with this source code.
 */

#![feature(phase)]
#![feature(macro_rules)]

extern crate serialize;
extern crate getopts;
extern crate libc;
#[phase(syntax, link)] extern crate log;

use std::char;
use std::io::{println, File, stdin, stdout};
use std::os;
use std::str;

use getopts::{
    getopts,
    optflag,
    optopt,
    usage
};
use serialize::base64;
use serialize::base64::{FromBase64, ToBase64};

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "base64";

fn main() {
    let args = box os::args();
    let opts = ~[
        optflag("d", "decode", "decode data"),
        optflag("i", "ignore-garbage", "when decoding, ignore non-alphabetic characters"),
        optopt("w", "wrap",
            "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", "COLS"
        ),
        optflag("h", "help", "display this help text and exit"),
        optflag("V", "version", "output version information and exit")
    ];
    let matches = match getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(e) => {
            error!("error: {:s}", e.to_err_msg());
            fail!()
        }
    };

    let progname = args.get(0).clone();
    let usage = usage("Base64 encode or decode FILE, or standard input, to standard output.", opts);
    let mode = if matches.opt_present("help") {
        Help
    } else if matches.opt_present("version") {
        Version
    } else if matches.opt_present("decode") {
        Decode
    } else {
        Encode
    };
    let ignore_garbage = matches.opt_present("ignore-garbage");
    let line_wrap = match matches.opt_str("wrap") {
        Some(s) => match from_str(s) {
            Some(s) => s,
            None => {
                error!("error: {:s}", "Argument to option 'wrap' improperly formatted.");
                fail!()
            }
        },
        None => 76
    };
    let mut input = if matches.free.is_empty() || matches.free.get(0).as_slice() == "-" {
        box stdin() as Box<Reader>
    } else {
        let path = Path::new(matches.free.get(0).clone());
        box File::open(&path) as Box<Reader>
    };

    match mode {
        Decode  => decode(input, ignore_garbage),
        Encode  => encode(input, line_wrap),
        Help    => help(progname, usage),
        Version => version()
    }
}

fn decode(input: &mut Reader, ignore_garbage: bool) {
    let mut to_decode = match input.read_to_str() {
        Ok(m) => m,
        Err(f) => fail!(f.to_str())
    };

    to_decode = str::replace(to_decode, "\n", "");

    if ignore_garbage {
        let standard_chars: ~[char] =
            bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ",
            "abcdefghijklmnopqrstuvwxyz",
            "0123456789+/").iter().map(|b| char::from_u32(*b as u32).unwrap()).collect();

        to_decode = to_decode
            .trim_chars(|c| !standard_chars.contains(&c))
            .to_owned();
    }

    match to_decode.from_base64() {
        Ok(bytes) => {
            let mut out = stdout();

            match out.write(bytes) {
                Ok(_) => {}
                Err(f) => { crash!(1, "{}", f.to_str()); }
            }
            match out.flush() {
                Ok(_) => {}
                Err(f) => { crash!(1, "{}", f.to_str()); }
            }
        }
        Err(s) => {
            error!("error: {}", s.to_str());
            fail!()
        }
    }
}

fn encode(input: &mut Reader, line_wrap: uint) {
    let b64_conf = base64::Config {
        char_set: base64::Standard,
        pad: true,
        line_length: match line_wrap {
            0 => None,
            _ => Some(line_wrap)
        }
    };
    let to_encode = match input.read_to_end() {
        Ok(m) => m,
        Err(f) => fail!(f.to_str())
    };
    let mut encoded = to_encode.as_slice().to_base64(b64_conf);

    // To my knowledge, RFC 3548 does not specify which line endings to use. It
    // seems that rust's base64 algorithm uses CRLF as prescribed by RFC 2045.
    // However, since GNU base64 outputs only LF (presumably because that is
    // the standard UNIX line ending), we strip CRs from the output to maintain
    // compatibility.
    encoded = encoded.replace("\r", "");

    println(encoded);
}

fn help(progname: &str, usage: &str) {
    println!("Usage: {:s} [OPTION]... [FILE]", progname);
    println!("");
    println(usage);

    let msg = "With no FILE, or when FILE is -, read standard input.\n\n\
        The data are encoded as described for the base64 alphabet in RFC \
        3548. When\ndecoding, the input may contain newlines in addition \
        to the bytes of the formal\nbase64 alphabet. Use --ignore-garbage \
        to attempt to recover from any other\nnon-alphabet bytes in the \
        encoded stream.";

    println(msg);
}

fn version() {
    println!("base64 1.0.0");
}

enum Mode {
    Decode,
    Encode,
    Help,
    Version
}

<commit_msg>from_base64 returns Vec<u8> now<commit_after>#![crate_id(name="base64", vers="1.0.0", author="Jordy Dickinson")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordy Dickinson <jordy.dickinson@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE file
 * that was distributed with this source code.
 */

#![feature(phase)]
#![feature(macro_rules)]

extern crate serialize;
extern crate getopts;
extern crate libc;
#[phase(syntax, link)] extern crate log;

use std::char;
use std::io::{println, File, stdin, stdout};
use std::os;
use std::str;

use getopts::{
    getopts,
    optflag,
    optopt,
    usage
};
use serialize::base64;
use serialize::base64::{FromBase64, ToBase64};

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "base64";

fn main() {
    let args = box os::args();
    let opts = ~[
        optflag("d", "decode", "decode data"),
        optflag("i", "ignore-garbage", "when decoding, ignore non-alphabetic characters"),
        optopt("w", "wrap",
            "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", "COLS"
        ),
        optflag("h", "help", "display this help text and exit"),
        optflag("V", "version", "output version information and exit")
    ];
    let matches = match getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(e) => {
            error!("error: {:s}", e.to_err_msg());
            fail!()
        }
    };

    let progname = args.get(0).clone();
    let usage = usage("Base64 encode or decode FILE, or standard input, to standard output.", opts);
    let mode = if matches.opt_present("help") {
        Help
    } else if matches.opt_present("version") {
        Version
    } else if matches.opt_present("decode") {
        Decode
    } else {
        Encode
    };
    let ignore_garbage = matches.opt_present("ignore-garbage");
    let line_wrap = match matches.opt_str("wrap") {
        Some(s) => match from_str(s) {
            Some(s) => s,
            None => {
                error!("error: {:s}", "Argument to option 'wrap' improperly formatted.");
                fail!()
            }
        },
        None => 76
    };
    let mut input = if matches.free.is_empty() || matches.free.get(0).as_slice() == "-" {
        box stdin() as Box<Reader>
    } else {
        let path = Path::new(matches.free.get(0).clone());
        box File::open(&path) as Box<Reader>
    };

    match mode {
        Decode  => decode(input, ignore_garbage),
        Encode  => encode(input, line_wrap),
        Help    => help(progname, usage),
        Version => version()
    }
}

fn decode(input: &mut Reader, ignore_garbage: bool) {
    let mut to_decode = match input.read_to_str() {
        Ok(m) => m,
        Err(f) => fail!(f.to_str())
    };

    to_decode = str::replace(to_decode, "\n", "");

    if ignore_garbage {
        let standard_chars: ~[char] =
            bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ",
            "abcdefghijklmnopqrstuvwxyz",
            "0123456789+/").iter().map(|b| char::from_u32(*b as u32).unwrap()).collect();

        to_decode = to_decode
            .trim_chars(|c| !standard_chars.contains(&c))
            .to_owned();
    }

    match to_decode.from_base64() {
        Ok(bytes) => {
            let mut out = stdout();

            match out.write(bytes.as_slice()) {
                Ok(_) => {}
                Err(f) => { crash!(1, "{}", f.to_str()); }
            }
            match out.flush() {
                Ok(_) => {}
                Err(f) => { crash!(1, "{}", f.to_str()); }
            }
        }
        Err(s) => {
            error!("error: {}", s.to_str());
            fail!()
        }
    }
}

fn encode(input: &mut Reader, line_wrap: uint) {
    let b64_conf = base64::Config {
        char_set: base64::Standard,
        pad: true,
        line_length: match line_wrap {
            0 => None,
            _ => Some(line_wrap)
        }
    };
    let to_encode = match input.read_to_end() {
        Ok(m) => m,
        Err(f) => fail!(f.to_str())
    };
    let mut encoded = to_encode.as_slice().to_base64(b64_conf);

    // To my knowledge, RFC 3548 does not specify which line endings to use. It
    // seems that rust's base64 algorithm uses CRLF as prescribed by RFC 2045.
    // However, since GNU base64 outputs only LF (presumably because that is
    // the standard UNIX line ending), we strip CRs from the output to maintain
    // compatibility.
    encoded = encoded.replace("\r", "");

    println(encoded);
}

fn help(progname: &str, usage: &str) {
    println!("Usage: {:s} [OPTION]... [FILE]", progname);
    println!("");
    println(usage);

    let msg = "With no FILE, or when FILE is -, read standard input.\n\n\
        The data are encoded as described for the base64 alphabet in RFC \
        3548. When\ndecoding, the input may contain newlines in addition \
        to the bytes of the formal\nbase64 alphabet. Use --ignore-garbage \
        to attempt to recover from any other\nnon-alphabet bytes in the \
        encoded stream.";

    println(msg);
}

fn version() {
    println!("base64 1.0.0");
}

enum Mode {
    Decode,
    Encode,
    Help,
    Version
}

<|endoftext|>


<commit_before>use ra_db::FileId;
use ra_syntax::{
    SyntaxNode, SyntaxNodePtr, AstNode, SmolStr, TextRange, ast,
    SyntaxKind::{self, NAME},
};
use hir::{ModuleSource, FieldSource, Name, ImplItem};

use crate::{FileSymbol, db::RootDatabase};

/// `NavigationTarget` represents and element in the editor's UI which you can
/// click on to navigate to a particular piece of code.
///
/// Typically, a `NavigationTarget` corresponds to some element in the source
/// code, like a function or a struct, but this is not strictly required.
#[derive(Debug, Clone)]
pub struct NavigationTarget {
    file_id: FileId,
    name: SmolStr,
    kind: SyntaxKind,
    full_range: TextRange,
    focus_range: Option<TextRange>,
    container_name: Option<SmolStr>,
}

impl NavigationTarget {
    /// When `focus_range` is specified, returns it. otherwise
    /// returns `full_range`
    pub fn range(&self) -> TextRange {
        self.focus_range.unwrap_or(self.full_range)
    }

    pub fn name(&self) -> &SmolStr {
        &self.name
    }

    pub fn container_name(&self) -> Option<&SmolStr> {
        self.container_name.as_ref()
    }

    pub fn kind(&self) -> SyntaxKind {
        self.kind
    }

    pub fn file_id(&self) -> FileId {
        self.file_id
    }

    pub fn full_range(&self) -> TextRange {
        self.full_range
    }

    /// A "most interesting" range withing the `full_range`.
    ///
    /// Typically, `full_range` is the whole syntax node,
    /// including doc comments, and `focus_range` is the range of the identifier.
    pub fn focus_range(&self) -> Option<TextRange> {
        self.focus_range
    }

    pub(crate) fn from_bind_pat(file_id: FileId, pat: &ast::BindPat) -> NavigationTarget {
        NavigationTarget::from_named(file_id, pat)
    }

    pub(crate) fn from_symbol(symbol: FileSymbol) -> NavigationTarget {
        NavigationTarget {
            file_id: symbol.file_id,
            name: symbol.name.clone(),
            kind: symbol.ptr.kind(),
            full_range: symbol.ptr.range(),
            focus_range: symbol.name_range,
            container_name: symbol.container_name.clone(),
        }
    }

    pub(crate) fn from_scope_entry(
        file_id: FileId,
        name: Name,
        ptr: SyntaxNodePtr,
    ) -> NavigationTarget {
        NavigationTarget {
            file_id,
            name: name.to_string().into(),
            full_range: ptr.range(),
            focus_range: None,
            kind: NAME,
            container_name: None,
        }
    }

    pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
        let (file_id, source) = module.definition_source(db);
        let file_id = file_id.as_original_file();
        let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
        match source {
            ModuleSource::SourceFile(node) => {
                NavigationTarget::from_syntax(file_id, name, None, node.syntax())
            }
            ModuleSource::Module(node) => {
                NavigationTarget::from_syntax(file_id, name, None, node.syntax())
            }
        }
    }

    pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
        let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
        if let Some((file_id, source)) = module.declaration_source(db) {
            let file_id = file_id.as_original_file();
            return NavigationTarget::from_syntax(file_id, name, None, source.syntax());
        }
        NavigationTarget::from_module(db, module)
    }

    pub(crate) fn from_function(db: &RootDatabase, func: hir::Function) -> NavigationTarget {
        let (file_id, fn_def) = func.source(db);
        NavigationTarget::from_named(file_id.original_file(db), &*fn_def)
    }

    pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget {
        let (file_id, field) = field.source(db);
        let file_id = file_id.original_file(db);
        match field {
            FieldSource::Named(it) => NavigationTarget::from_named(file_id, &*it),
            FieldSource::Pos(it) => {
                NavigationTarget::from_syntax(file_id, "".into(), None, it.syntax())
            }
        }
    }

    pub(crate) fn from_def(db: &RootDatabase, module_def: hir::ModuleDef) -> NavigationTarget {
        match module_def {
            hir::ModuleDef::Module(module) => NavigationTarget::from_module(db, module),
            hir::ModuleDef::Function(func) => NavigationTarget::from_function(db, func),
            hir::ModuleDef::Struct(s) => {
                let (file_id, node) = s.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            hir::ModuleDef::Const(s) => {
                let (file_id, node) = s.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            hir::ModuleDef::Static(s) => {
                let (file_id, node) = s.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            hir::ModuleDef::Enum(e) => {
                let (file_id, node) = e.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            hir::ModuleDef::EnumVariant(var) => {
                let (file_id, node) = var.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            hir::ModuleDef::Trait(e) => {
                let (file_id, node) = e.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            hir::ModuleDef::TypeAlias(e) => {
                let (file_id, node) = e.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
        }
    }

    pub(crate) fn from_impl_block(
        db: &RootDatabase,
        impl_block: hir::ImplBlock,
    ) -> NavigationTarget {
        let (file_id, node) = impl_block.source(db);
        NavigationTarget::from_syntax(
            file_id.as_original_file(),
            "impl".into(),
            None,
            node.syntax(),
        )
    }

    pub(crate) fn from_impl_item(
        db: &RootDatabase,
        impl_item: hir::ImplItem,
    ) -> NavigationTarget {
        match impl_item {
            ImplItem::Method(f) => {
                NavigationTarget::from_function(db, f)
            }
            ImplItem::Const(c) => {
                let (file_id, node) = c.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            ImplItem::TypeAlias(a) => {
                let (file_id, node) = a.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
        }
    }

    #[cfg(test)]
    pub(crate) fn assert_match(&self, expected: &str) {
        let actual = self.debug_render();
        test_utils::assert_eq_text!(expected.trim(), actual.trim(),);
    }

    #[cfg(test)]
    pub(crate) fn debug_render(&self) -> String {
        let mut buf = format!(
            "{} {:?} {:?} {:?}",
            self.name(),
            self.kind(),
            self.file_id(),
            self.full_range()
        );
        if let Some(focus_range) = self.focus_range() {
            buf.push_str(&format!(" {:?}", focus_range))
        }
        if let Some(container_name) = self.container_name() {
            buf.push_str(&format!(" {}", container_name))
        }
        buf
    }

    /// Allows `NavigationTarget` to be created from a `NameOwner`
    pub(crate) fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget {
        let name = node.name().map(|it| it.text().clone()).unwrap_or_default();
        let focus_range = node.name().map(|it| it.syntax().range());
        NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax())
    }

    fn from_syntax(
        file_id: FileId,
        name: SmolStr,
        focus_range: Option<TextRange>,
        node: &SyntaxNode,
    ) -> NavigationTarget {
        NavigationTarget {
            file_id,
            name,
            kind: node.kind(),
            full_range: node.range(),
            focus_range,
            // ptr: Some(LocalSyntaxPtr::new(node)),
            container_name: None,
        }
    }
}
<commit_msg>Format<commit_after>use ra_db::FileId;
use ra_syntax::{
    SyntaxNode, SyntaxNodePtr, AstNode, SmolStr, TextRange, ast,
    SyntaxKind::{self, NAME},
};
use hir::{ModuleSource, FieldSource, Name, ImplItem};

use crate::{FileSymbol, db::RootDatabase};

/// `NavigationTarget` represents and element in the editor's UI which you can
/// click on to navigate to a particular piece of code.
///
/// Typically, a `NavigationTarget` corresponds to some element in the source
/// code, like a function or a struct, but this is not strictly required.
#[derive(Debug, Clone)]
pub struct NavigationTarget {
    file_id: FileId,
    name: SmolStr,
    kind: SyntaxKind,
    full_range: TextRange,
    focus_range: Option<TextRange>,
    container_name: Option<SmolStr>,
}

impl NavigationTarget {
    /// When `focus_range` is specified, returns it. otherwise
    /// returns `full_range`
    pub fn range(&self) -> TextRange {
        self.focus_range.unwrap_or(self.full_range)
    }

    pub fn name(&self) -> &SmolStr {
        &self.name
    }

    pub fn container_name(&self) -> Option<&SmolStr> {
        self.container_name.as_ref()
    }

    pub fn kind(&self) -> SyntaxKind {
        self.kind
    }

    pub fn file_id(&self) -> FileId {
        self.file_id
    }

    pub fn full_range(&self) -> TextRange {
        self.full_range
    }

    /// A "most interesting" range withing the `full_range`.
    ///
    /// Typically, `full_range` is the whole syntax node,
    /// including doc comments, and `focus_range` is the range of the identifier.
    pub fn focus_range(&self) -> Option<TextRange> {
        self.focus_range
    }

    pub(crate) fn from_bind_pat(file_id: FileId, pat: &ast::BindPat) -> NavigationTarget {
        NavigationTarget::from_named(file_id, pat)
    }

    pub(crate) fn from_symbol(symbol: FileSymbol) -> NavigationTarget {
        NavigationTarget {
            file_id: symbol.file_id,
            name: symbol.name.clone(),
            kind: symbol.ptr.kind(),
            full_range: symbol.ptr.range(),
            focus_range: symbol.name_range,
            container_name: symbol.container_name.clone(),
        }
    }

    pub(crate) fn from_scope_entry(
        file_id: FileId,
        name: Name,
        ptr: SyntaxNodePtr,
    ) -> NavigationTarget {
        NavigationTarget {
            file_id,
            name: name.to_string().into(),
            full_range: ptr.range(),
            focus_range: None,
            kind: NAME,
            container_name: None,
        }
    }

    pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
        let (file_id, source) = module.definition_source(db);
        let file_id = file_id.as_original_file();
        let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
        match source {
            ModuleSource::SourceFile(node) => {
                NavigationTarget::from_syntax(file_id, name, None, node.syntax())
            }
            ModuleSource::Module(node) => {
                NavigationTarget::from_syntax(file_id, name, None, node.syntax())
            }
        }
    }

    pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
        let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
        if let Some((file_id, source)) = module.declaration_source(db) {
            let file_id = file_id.as_original_file();
            return NavigationTarget::from_syntax(file_id, name, None, source.syntax());
        }
        NavigationTarget::from_module(db, module)
    }

    pub(crate) fn from_function(db: &RootDatabase, func: hir::Function) -> NavigationTarget {
        let (file_id, fn_def) = func.source(db);
        NavigationTarget::from_named(file_id.original_file(db), &*fn_def)
    }

    pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget {
        let (file_id, field) = field.source(db);
        let file_id = file_id.original_file(db);
        match field {
            FieldSource::Named(it) => NavigationTarget::from_named(file_id, &*it),
            FieldSource::Pos(it) => {
                NavigationTarget::from_syntax(file_id, "".into(), None, it.syntax())
            }
        }
    }

    pub(crate) fn from_def(db: &RootDatabase, module_def: hir::ModuleDef) -> NavigationTarget {
        match module_def {
            hir::ModuleDef::Module(module) => NavigationTarget::from_module(db, module),
            hir::ModuleDef::Function(func) => NavigationTarget::from_function(db, func),
            hir::ModuleDef::Struct(s) => {
                let (file_id, node) = s.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            hir::ModuleDef::Const(s) => {
                let (file_id, node) = s.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            hir::ModuleDef::Static(s) => {
                let (file_id, node) = s.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            hir::ModuleDef::Enum(e) => {
                let (file_id, node) = e.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            hir::ModuleDef::EnumVariant(var) => {
                let (file_id, node) = var.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            hir::ModuleDef::Trait(e) => {
                let (file_id, node) = e.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            hir::ModuleDef::TypeAlias(e) => {
                let (file_id, node) = e.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
        }
    }

    pub(crate) fn from_impl_block(
        db: &RootDatabase,
        impl_block: hir::ImplBlock,
    ) -> NavigationTarget {
        let (file_id, node) = impl_block.source(db);
        NavigationTarget::from_syntax(
            file_id.as_original_file(),
            "impl".into(),
            None,
            node.syntax(),
        )
    }

    pub(crate) fn from_impl_item(db: &RootDatabase, impl_item: hir::ImplItem) -> NavigationTarget {
        match impl_item {
            ImplItem::Method(f) => NavigationTarget::from_function(db, f),
            ImplItem::Const(c) => {
                let (file_id, node) = c.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
            ImplItem::TypeAlias(a) => {
                let (file_id, node) = a.source(db);
                NavigationTarget::from_named(file_id.original_file(db), &*node)
            }
        }
    }

    #[cfg(test)]
    pub(crate) fn assert_match(&self, expected: &str) {
        let actual = self.debug_render();
        test_utils::assert_eq_text!(expected.trim(), actual.trim(),);
    }

    #[cfg(test)]
    pub(crate) fn debug_render(&self) -> String {
        let mut buf = format!(
            "{} {:?} {:?} {:?}",
            self.name(),
            self.kind(),
            self.file_id(),
            self.full_range()
        );
        if let Some(focus_range) = self.focus_range() {
            buf.push_str(&format!(" {:?}", focus_range))
        }
        if let Some(container_name) = self.container_name() {
            buf.push_str(&format!(" {}", container_name))
        }
        buf
    }

    /// Allows `NavigationTarget` to be created from a `NameOwner`
    pub(crate) fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget {
        let name = node.name().map(|it| it.text().clone()).unwrap_or_default();
        let focus_range = node.name().map(|it| it.syntax().range());
        NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax())
    }

    fn from_syntax(
        file_id: FileId,
        name: SmolStr,
        focus_range: Option<TextRange>,
        node: &SyntaxNode,
    ) -> NavigationTarget {
        NavigationTarget {
            file_id,
            name,
            kind: node.kind(),
            full_range: node.range(),
            focus_range,
            // ptr: Some(LocalSyntaxPtr::new(node)),
            container_name: None,
        }
    }
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate test;
use test::Bencher;

use resize::Pixel::{Gray16, Gray8};
use resize::Type::Triangle;
use resize::Type::Lanczos3;
use std::fs::File;
use std::path::PathBuf;

fn get_image() -> (png::OutputInfo, Vec<u8>) {
    let root: PathBuf = env!("CARGO_MANIFEST_DIR").into();
    let decoder = png::Decoder::new(File::open(root.join("examples/tiger.png")).unwrap());
    let (info, mut reader) = decoder.read_info().unwrap();
    let mut src = vec![110; info.buffer_size()];
    reader.next_frame(&mut src).unwrap();
    (info, src)
}

#[bench]
fn precomputed_large(b: &mut Bencher) {
    let (info, src) = get_image();
    let (w1, h1) = (info.width as usize, info.height as usize);
    let (w2, h2) = (1600, 1200);
    let mut dst = vec![120; w2 * h2];

    let mut r = resize::new(w1, h1, w2, h2, Gray8, Triangle);

    b.iter(|| r.resize(&src, &mut dst));
}

#[bench]
fn tiny(b: &mut Bencher) {
    let (info, src0) = get_image();
    let (w0, h0) = (info.width as usize, info.height as usize);
    let (w1, h1) = (3200, 2400);
    let mut src1 = vec![0; w1 * h1];

    resize::new(w0, h0, w1, h1, Gray8, Triangle).resize(&src0, &mut src1);
    let (w2, h2) = (16, 12);
    let mut dst = vec![0; w2 * h2];

    let mut r = resize::new(w1, h1, w2, h2, Gray8, Lanczos3);
    b.iter(|| r.resize(&src1, &mut dst));
}

#[bench]
fn huge_stretch(b: &mut Bencher) {
    let (info, src0) = get_image();
    let (w0, h0) = (info.width as usize, info.height as usize);
    let (w1, h1) = (12, 12);
    let mut src1 = vec![0; w1 * h1];

    resize::new(w0, h0, w1, h1, Gray8, Lanczos3).resize(&src0, &mut src1);
    let (w2, h2) = (1200, 1200);
    let mut dst = vec![0; w2 * h2];

    let mut r = resize::new(w1, h1, w2, h2, Gray8, Triangle);
    b.iter(|| r.resize(&src1, &mut dst));
}

#[bench]
fn precomputed_small(b: &mut Bencher) {
    let (info, src) = get_image();
    let (w1, h1) = (info.width as usize, info.height as usize);
    let (w2, h2) = (100, 100);
    let mut dst = vec![240; w2 * h2];

    let mut r = resize::new(w1, h1, w2, h2, Gray8, Triangle);

    b.iter(|| r.resize(&src, &mut dst));
}

#[bench]
fn precomputed_small_16bit(b: &mut Bencher) {
    let (info, src) = get_image();
    let (w1, h1) = (info.width as usize, info.height as usize);
    let (w2, h2) = (100,100);
    let mut dst = vec![33; w2*h2];
    let src: Vec<_> = src.into_iter().map(|px|{
        let px = px as u16;
        (px << 8) | px
    }).collect();

    let mut r = resize::new(w1, h1, w2, h2, Gray16, Triangle);

    b.iter(|| r.resize(&src, &mut dst));
}

#[bench]
#[allow(deprecated)]
fn recomputed_small(b: &mut Bencher) {
    let (info, src) = get_image();
    let (w1, h1) = (info.width as usize, info.height as usize);
    let (w2, h2) = (100, 100);
    let mut dst = vec![99; w2 * h2];

    b.iter(|| resize::resize(w1, h1, w2, h2, Gray8, Triangle, &src, &mut dst));
}
<commit_msg>Bench new()<commit_after>#![feature(test)]

extern crate test;
use test::Bencher;

use resize::Pixel::{Gray16, Gray8, RGB24};
use resize::Type::Triangle;
use resize::Type::Lanczos3;
use resize::Type::Point;
use std::fs::File;
use std::path::PathBuf;

fn get_image() -> (png::OutputInfo, Vec<u8>) {
    let root: PathBuf = env!("CARGO_MANIFEST_DIR").into();
    let decoder = png::Decoder::new(File::open(root.join("examples/tiger.png")).unwrap());
    let (info, mut reader) = decoder.read_info().unwrap();
    let mut src = vec![110; info.buffer_size()];
    reader.next_frame(&mut src).unwrap();
    (info, src)
}

#[bench]
fn precomputed_large(b: &mut Bencher) {
    let (info, src) = get_image();
    let (w1, h1) = (info.width as usize, info.height as usize);
    let (w2, h2) = (1600, 1200);
    let mut dst = vec![120; w2 * h2];

    let mut r = resize::new(w1, h1, w2, h2, Gray8, Triangle);

    b.iter(|| r.resize(&src, &mut dst));
}

#[bench]
fn tiny(b: &mut Bencher) {
    let (info, src0) = get_image();
    let (w0, h0) = (info.width as usize, info.height as usize);
    let (w1, h1) = (3200, 2400);
    let mut src1 = vec![0; w1 * h1];

    resize::new(w0, h0, w1, h1, Gray8, Triangle).resize(&src0, &mut src1);
    let (w2, h2) = (16, 12);
    let mut dst = vec![0; w2 * h2];

    let mut r = resize::new(w1, h1, w2, h2, Gray8, Lanczos3);
    b.iter(|| r.resize(&src1, &mut dst));
}

#[bench]
fn huge_stretch(b: &mut Bencher) {
    let (info, src0) = get_image();
    let (w0, h0) = (info.width as usize, info.height as usize);
    let (w1, h1) = (12, 12);
    let mut src1 = vec![0; w1 * h1];

    resize::new(w0, h0, w1, h1, Gray8, Lanczos3).resize(&src0, &mut src1);
    let (w2, h2) = (1200, 1200);
    let mut dst = vec![0; w2 * h2];

    let mut r = resize::new(w1, h1, w2, h2, Gray8, Triangle);
    b.iter(|| r.resize(&src1, &mut dst));
}

#[bench]
fn precomputed_small(b: &mut Bencher) {
    let (info, src) = get_image();
    let (w1, h1) = (info.width as usize, info.height as usize);
    let (w2, h2) = (100, 100);
    let mut dst = vec![240; w2 * h2];

    let mut r = resize::new(w1, h1, w2, h2, Gray8, Triangle);

    b.iter(|| r.resize(&src, &mut dst));
}

#[bench]
fn precomputed_small_16bit(b: &mut Bencher) {
    let (info, src) = get_image();
    let (w1, h1) = (info.width as usize, info.height as usize);
    let (w2, h2) = (100,100);
    let mut dst = vec![33; w2*h2];
    let src: Vec<_> = src.into_iter().map(|px|{
        let px = px as u16;
        (px << 8) | px
    }).collect();

    let mut r = resize::new(w1, h1, w2, h2, Gray16, Triangle);

    b.iter(|| r.resize(&src, &mut dst));
}

#[bench]
#[allow(deprecated)]
fn recomputed_small(b: &mut Bencher) {
    let (info, src) = get_image();
    let (w1, h1) = (info.width as usize, info.height as usize);
    let (w2, h2) = (100, 100);
    let mut dst = vec![99; w2 * h2];

    b.iter(|| resize::resize(w1, h1, w2, h2, Gray8, Triangle, &src, &mut dst));
}

#[bench]
#[allow(deprecated)]
fn init_lanczos(b: &mut Bencher) {
    b.iter(|| resize::new(test::black_box(100), 200, test::black_box(300), 400, RGB24, Lanczos3));
}

#[bench]
#[allow(deprecated)]
fn init_point(b: &mut Bencher) {
    b.iter(|| resize::new(test::black_box(100), 200, test::black_box(300), 400, RGB24, Point));
}
<|endoftext|>


<commit_before>use gl;
use std::default::Default;
use std::os::raw::c_void;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;

pub use glfw::{self, Action, Context, CursorMode, Key, MouseButton, Window};

#[derive(Clone, Copy, Debug)]
pub enum LuminanceBackend {
  GL33
}

impl Default for LuminanceBackend {
  fn default() -> Self {
    LuminanceBackend::GL33
  }
}

#[derive(Clone, Copy, Debug)]
pub enum WindowDim {
  Windowed(u32, u32),
  FullScreen,
  FullScreenRestricted(u32, u32)
}

pub type Keyboard = mpsc::Receiver<(Key, Action)>;
pub type Mouse = mpsc::Receiver<(MouseButton, Action)>;
pub type MouseMove = mpsc::Receiver<[f64; 2]>;
pub type Scroll = mpsc::Receiver<[f64; 2]>;

pub fn bootstrap<App: FnOnce(u32, u32, Keyboard, Mouse, MouseMove, Scroll, Window)>(dim: WindowDim, title: &'static str, backend: LuminanceBackend, app: App) {
  let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

  match backend {
    LuminanceBackend::GL33 => {
      // OpenGL hints; implements luminance-gl’s core contexts creation
      glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));
      glfw.window_hint(glfw::WindowHint::ContextVersionMajor(3));
      glfw.window_hint(glfw::WindowHint::ContextVersionMinor(3));
    }
  }

  // open a window in windowed or fullscreen mode
  let (mut window, events, w, h) = match dim {
    WindowDim::Windowed(w, h) => {
      let (window, events) = glfw.create_window(w, h, title, glfw::WindowMode::Windowed).expect("Failed to create GLFW window.");
      (window, events, w, h)
    },
    WindowDim::FullScreen => {
      glfw.with_primary_monitor(|glfw, monitor| {
        let monitor = monitor.unwrap();
        let vmode = monitor.get_video_mode().expect("primary monitor’s video mode");
        let (w, h) = (vmode.width, vmode.height);

        let (window, events) = glfw.create_window(w, h, title, glfw::WindowMode::FullScreen(monitor)).expect("Failed to create GLFW window.");
        (window, events, w, h)
      })
    },
    WindowDim::FullScreenRestricted(w, h) => {
      glfw.with_primary_monitor(|glfw, monitor| {
        let monitor = monitor.unwrap();

        let (window, events) = glfw.create_window(w, h, title, glfw::WindowMode::FullScreen(monitor)).expect("Failed to create GLFW window.");
        (window, events, w, h)
      })
    }
  };

  window.make_current();

  if cfg!(feature = "release") {
    window.set_cursor_mode(CursorMode::Disabled);
  }

  window.set_key_polling(true);
  window.set_cursor_pos_polling(true);
  window.set_mouse_button_polling(true);
  window.set_scroll_polling(true);

  // init OpenGL
  gl::load_with(|s| window.get_proc_address(s) as *const c_void);

  info!("using resolution {}x{}", w, h);

  // create channels to stream keyboard and mouse events
  let (kbd_snd, kbd_rcv) = mpsc::channel();
  let (mouse_snd, mouse_rcv) = mpsc::channel();
  let (mouse_move_snd, mouse_move_rcv) = mpsc::channel();
  let (scroll_snd, scroll_rcv) = mpsc::channel();

  // start the event threads
  let _ = thread::spawn(move || {
    loop {
      glfw.poll_events();

      for (_, event) in glfw::flush_messages(&events) {
        match event {
            glfw::WindowEvent::Key(key, _, action, _) => {
              let _ = kbd_snd.send((key, action));
            },
            glfw::WindowEvent::MouseButton(button, action, _) => {
              let _ = mouse_snd.send((button, action));
            },
            glfw::WindowEvent::CursorPos(x, y) => {
              let _ = mouse_move_snd.send([x, y]);
            },
            glfw::WindowEvent::Scroll(x, y) => {
              let _ = scroll_snd.send([x, y]);
            },
            _ => {},
        }

        thread::sleep(Duration::from_millis(10));
      }
    }
  });

  app(w, h, kbd_rcv, mouse_rcv, mouse_move_rcv, scroll_rcv, window);
}
<commit_msg>Fixed CPU overload in the event loop. No fucking idea what was wrong.<commit_after>use gl;
use std::default::Default;
use std::os::raw::c_void;
use std::sync::mpsc;
use std::thread;

pub use glfw::{self, Action, Context, CursorMode, Key, MouseButton, Window};

#[derive(Clone, Copy, Debug)]
pub enum LuminanceBackend {
  GL33
}

impl Default for LuminanceBackend {
  fn default() -> Self {
    LuminanceBackend::GL33
  }
}

#[derive(Clone, Copy, Debug)]
pub enum WindowDim {
  Windowed(u32, u32),
  FullScreen,
  FullScreenRestricted(u32, u32)
}

pub type Keyboard = mpsc::Receiver<(Key, Action)>;
pub type Mouse = mpsc::Receiver<(MouseButton, Action)>;
pub type MouseMove = mpsc::Receiver<[f64; 2]>;
pub type Scroll = mpsc::Receiver<[f64; 2]>;

pub fn bootstrap<App: FnOnce(u32, u32, Keyboard, Mouse, MouseMove, Scroll, Window)>(dim: WindowDim, title: &'static str, backend: LuminanceBackend, app: App) {
  let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

  match backend {
    LuminanceBackend::GL33 => {
      // OpenGL hints; implements luminance-gl’s core contexts creation
      glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));
      glfw.window_hint(glfw::WindowHint::ContextVersionMajor(3));
      glfw.window_hint(glfw::WindowHint::ContextVersionMinor(3));
    }
  }

  // open a window in windowed or fullscreen mode
  let (mut window, events, w, h) = match dim {
    WindowDim::Windowed(w, h) => {
      let (window, events) = glfw.create_window(w, h, title, glfw::WindowMode::Windowed).expect("Failed to create GLFW window.");
      (window, events, w, h)
    },
    WindowDim::FullScreen => {
      glfw.with_primary_monitor(|glfw, monitor| {
        let monitor = monitor.unwrap();
        let vmode = monitor.get_video_mode().expect("primary monitor’s video mode");
        let (w, h) = (vmode.width, vmode.height);

        let (window, events) = glfw.create_window(w, h, title, glfw::WindowMode::FullScreen(monitor)).expect("Failed to create GLFW window.");
        (window, events, w, h)
      })
    },
    WindowDim::FullScreenRestricted(w, h) => {
      glfw.with_primary_monitor(|glfw, monitor| {
        let monitor = monitor.unwrap();

        let (window, events) = glfw.create_window(w, h, title, glfw::WindowMode::FullScreen(monitor)).expect("Failed to create GLFW window.");
        (window, events, w, h)
      })
    }
  };

  window.make_current();

  if cfg!(feature = "release") {
    window.set_cursor_mode(CursorMode::Disabled);
  }

  window.set_key_polling(true);
  window.set_cursor_pos_polling(true);
  window.set_mouse_button_polling(true);
  window.set_scroll_polling(true);

  // init OpenGL
  gl::load_with(|s| window.get_proc_address(s) as *const c_void);

  info!("using resolution {}x{}", w, h);

  // create channels to stream keyboard and mouse events
  let (kbd_snd, kbd_rcv) = mpsc::channel();
  let (mouse_snd, mouse_rcv) = mpsc::channel();
  let (mouse_move_snd, mouse_move_rcv) = mpsc::channel();
  let (scroll_snd, scroll_rcv) = mpsc::channel();

  // start the event threads
  let _ = thread::spawn(move || {
    loop {
      glfw.wait_events();

      for (_, event) in glfw::flush_messages(&events) {
        match event {
            glfw::WindowEvent::Key(key, _, action, _) => {
              let _ = kbd_snd.send((key, action));
            },
            glfw::WindowEvent::MouseButton(button, action, _) => {
              let _ = mouse_snd.send((button, action));
            },
            glfw::WindowEvent::CursorPos(x, y) => {
              let _ = mouse_move_snd.send([x, y]);
            },
            glfw::WindowEvent::Scroll(x, y) => {
              let _ = scroll_snd.send([x, y]);
            },
            _ => {},
        }
      }
    }
  });

  app(w, h, kbd_rcv, mouse_rcv, mouse_move_rcv, scroll_rcv, window);
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use devicemapper::{DM, DevId, DeviceInfo, DmFlags};
use engine::EngineResult;

use std::path::Path;

use super::blockdev::BlockDev;

use types::DataBlocks;
use types::Sectors;

pub struct ThinPoolDev {
    pub name: String,
    dev_info: Option<DeviceInfo>,
    data_block_size: Option<Sectors>,
    pub low_water_mark: Option<DataBlocks>, // How close to full before we are worried?
    pub meta_dev: Option<BlockDev>,
    pub data_dev: Option<BlockDev>,
}

/// support use of DM to create pools for thin provisioned devices
impl ThinPoolDev {
    pub fn new(name: &str) -> ThinPoolDev {
        ThinPoolDev {
            name: name.to_owned(),
            dev_info: None,
            data_block_size: None,
            low_water_mark: None,
            meta_dev: None,
            data_dev: None,
        }
    }
    /// Generate a Vec<> to be passed to DM.  The format of the Vec entries is:
    /// <start sec> <length> "thin-pool" /dev/meta /dev/data <block size> <low water mark>
    fn dm_table(&self,
                length: Sectors,
                data_block_size: Sectors,
                low_water_mark: DataBlocks,
                meta_dev: &Path,
                data_dev: &Path)
                -> Vec<(u64, u64, String, String)> {
        let mut table = Vec::new();
        let params = format!("{} {} {} {} 1 skip_block_zeroing",
                             meta_dev.to_string_lossy(),
                             data_dev.to_string_lossy(),
                             *data_block_size,
                             *low_water_mark);
        table.push((0u64, length.0, "thin-pool".to_owned(), params));
        debug!("dmtable line : {:?}", table);
        table
    }

    /// Use DM to create a "thin-pool".  A "thin-pool" is shared space for
    /// other thin provisioned devices to use.
    ///
    /// See section "Setting up a fresh pool device":
    /// https://www.kernel.org/doc/Documentation/device-mapper/thin-provisioning.txt
    pub fn setup(&mut self,
                 dm: &DM,
                 length: Sectors,
                 data_block_size: Sectors,
                 low_water_mark: DataBlocks,
                 meta_dev: &Path,
                 data_dev: &Path)
                 -> EngineResult<()> {

        debug!("setup : {}", self.name);
        try!(dm.device_create(&self.name, None, DmFlags::empty()));

        let table = self.dm_table(length, data_block_size, low_water_mark, meta_dev, data_dev);
        self.data_block_size = Some(data_block_size);
        self.low_water_mark = Some(low_water_mark);
        let id = &DevId::Name(&self.name);
        self.dev_info = Some(try!(dm.table_load(id, &table)));
        try!(dm.device_suspend(id, DmFlags::empty()));

        Ok(())
    }

    pub fn teardown(&mut self, dm: &DM) -> EngineResult<()> {
        try!(dm.device_remove(&DevId::Name(&self.name), DmFlags::empty()));

        Ok(())
    }
}
<commit_msg>Adde "message()" function to allow message passing to DM.<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use devicemapper::{DM, DevId, DeviceInfo, DmFlags};
use engine::EngineResult;

use std::path::Path;

use super::blockdev::BlockDev;

use types::DataBlocks;
use types::Sectors;

pub struct ThinPoolDev {
    pub name: String,
    dev_info: Option<DeviceInfo>,
    data_block_size: Option<Sectors>,
    pub low_water_mark: Option<DataBlocks>, // How close to full before we are worried?
    pub meta_dev: Option<BlockDev>,
    pub data_dev: Option<BlockDev>,
}

/// support use of DM to create pools for thin provisioned devices
impl ThinPoolDev {
    pub fn new(name: &str) -> ThinPoolDev {
        ThinPoolDev {
            name: name.to_owned(),
            dev_info: None,
            data_block_size: None,
            low_water_mark: None,
            meta_dev: None,
            data_dev: None,
        }
    }
    /// Generate a Vec<> to be passed to DM.  The format of the Vec entries is:
    /// <start sec> <length> "thin-pool" /dev/meta /dev/data <block size> <low water mark>
    fn dm_table(&self,
                length: Sectors,
                data_block_size: Sectors,
                low_water_mark: DataBlocks,
                meta_dev: &Path,
                data_dev: &Path)
                -> Vec<(u64, u64, String, String)> {
        let mut table = Vec::new();
        let params = format!("{} {} {} {} 1 skip_block_zeroing",
                             meta_dev.to_string_lossy(),
                             data_dev.to_string_lossy(),
                             *data_block_size,
                             *low_water_mark);
        table.push((0u64, length.0, "thin-pool".to_owned(), params));
        debug!("dmtable line : {:?}", table);
        table
    }

    /// Use DM to create a "thin-pool".  A "thin-pool" is shared space for
    /// other thin provisioned devices to use.
    ///
    /// See section "Setting up a fresh pool device":
    /// https://www.kernel.org/doc/Documentation/device-mapper/thin-provisioning.txt
    pub fn setup(&mut self,
                 dm: &DM,
                 length: Sectors,
                 data_block_size: Sectors,
                 low_water_mark: DataBlocks,
                 meta_dev: &Path,
                 data_dev: &Path)
                 -> EngineResult<()> {

        debug!("setup : {}", self.name);
        try!(dm.device_create(&self.name, None, DmFlags::empty()));

        let table = self.dm_table(length, data_block_size, low_water_mark, meta_dev, data_dev);
        self.data_block_size = Some(data_block_size);
        self.low_water_mark = Some(low_water_mark);
        let id = &DevId::Name(&self.name);
        self.dev_info = Some(try!(dm.table_load(id, &table)));
        try!(dm.device_suspend(id, DmFlags::empty()));

        Ok(())
    }

    pub fn message(&self, dm: &DM, message: &str) -> EngineResult<()> {
        try!(dm.target_msg(&DevId::Name(&self.name), 0, message));

        Ok(())
    }

    pub fn teardown(&mut self, dm: &DM) -> EngineResult<()> {
        try!(dm.device_remove(&DevId::Name(&self.name), DmFlags::empty()));

        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::fs;
use std::fs::{DirBuilder, File};
use std::path::Path;
use super::generation::PageGenerator;
use super::config::Config;

pub fn new_project(parent_dir: &str) -> Result<(), io::Error> {
    try!(DirBuilder::new().recursive(true).create(parent_dir));

    try!(DirBuilder::new().recursive(false).create(format!("{}/pages", parent_dir)));

    try!(File::create(format!("{}/_config.yml", parent_dir)));

    Ok(())
}

pub fn build_project(config: Config) -> Result<(), io::Error> {
    let pages_path = &config.source_dir;
    let output_dir = &config.output_dir;
    let mut page_generator = PageGenerator::new();

    let directory_iterator = try!(Path::new(pages_path).read_dir());

    if !Path::new(output_dir).exists() {
        try!(DirBuilder::new().create(output_dir));
    }

    for entry in directory_iterator {
        let file = try!(entry);
        let file_type = file.file_type().unwrap();
        let source_file = format!("{}/{}", pages_path, file.file_name().to_str().unwrap());
        let file_stem = String::from(file.path().file_stem().unwrap().to_str().unwrap());
        let destination_file = format!("{}/{}.html", output_dir, file_stem);

        if file_type.is_file() && file.file_name().to_str().unwrap().contains(".md") {
            try!(page_generator.set_input_file(source_file.as_ref())
                     .set_output_file(destination_file.as_ref())
                     .set_wrap(true)
                     .generate());
        }
    }

    Ok(())
}

pub fn clean_project(config: Config) -> Result<(), io::Error> {
    try!(fs::remove_dir_all(config.output_dir));

    Ok(())
}
<commit_msg>chore: fix error handling in build command<commit_after>use std::io;
use std::fs;
use std::fs::{DirBuilder, File};
use std::path::Path;
use super::generation::PageGenerator;
use super::config::Config;

pub fn new_project(parent_dir: &str) -> Result<(), io::Error> {
    try!(DirBuilder::new().recursive(true).create(parent_dir));

    try!(DirBuilder::new().recursive(false).create(format!("{}/pages", parent_dir)));

    try!(File::create(format!("{}/_config.yml", parent_dir)));

    Ok(())
}

pub fn build_project(config: Config) -> Result<(), io::Error> {
    let pages_path = &config.source_dir;
    let output_dir = &config.output_dir;
    let mut page_generator = PageGenerator::new();

    let directory_iterator = try!(Path::new(pages_path).read_dir());

    if !Path::new(output_dir).exists() {
        try!(DirBuilder::new().create(output_dir));
    }

    for entry in directory_iterator {
        let file = try!(entry);
        let file_type = try!(file.file_type());

        let file_name = match file.file_name().to_str() {
            Some(file_name) => file_name.to_string(),
            None => continue
        };

        let source_file = format!("{}/{}", pages_path, file_name);

        let file_stem = match file.path().file_stem() {
            Some(file_stem) => file_stem.to_string_lossy().into_owned(),
            None => continue
        };

        let destination_file = format!("{}/{}.html", output_dir, file_stem);

        let file_ext = match file.file_name().to_str() {
            Some(file_ext) => file_ext.to_string(),
            None => continue
        };

        if file_type.is_file() && file_ext.contains(".md") {
            try!(page_generator.set_input_file(source_file.as_ref())
                     .set_output_file(destination_file.as_ref())
                     .set_wrap(true)
                     .generate());
        }
    }

    Ok(())
}

pub fn clean_project(config: Config) -> Result<(), io::Error> {
    try!(fs::remove_dir_all(config.output_dir));

    Ok(())
}
<|endoftext|>


<commit_before>use std::vec::Vec;
use std::string::String;

struct Compiler {
    pub lines: Vec<String>,
}

impl Compiler {
    pub fn new() -> Self {
        Compiler { lines: Vec::new() }
    }

    pub fn parse(&mut self, assembly: &str) {
        let mut line = String::new();
        let mut chars = assembly.chars();

        while let Some(c) = chars.next() {
            match c {
                // Line Feed | Vertical Tab | Form Feed | Next Line | Line/Paragraph Separator
                '\u{000A}' | '\u{000B}' | '\u{000C}' | '\u{0085}' | '\u{2028}' | '\u{2029}' => {
                    self.lines.push(line);
                    line = String::new();
                }

                // Carriage Return
                '\u{000D}' => {
                    self.lines.push(line);
                    line = String::new();

                    // Carriage Return + Line Feed
                    match chars.next() {
                        Some(n) => {
                            if n != '\u{000A}' {
                                line.push(n);
                            }
                        }
                        None => {}
                    }
                }

                _ => {
                    line.push(c);
                }
            }
        }

        if !line.is_empty() {
            self.lines.push(line);
        }
    }
}

#[cfg(test)]
mod tests {
    use super::Compiler;

    #[test]
    fn it_splits_lines_by_line_feed() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\n0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_vertical_tab() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\x0B0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_form_feed() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\x0C0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_carriage_return() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\r0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_carriage_return_line_feed() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\r\n0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_next_line() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\u{0085}0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_line_separator() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\u{2028}0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_paragraph_separator() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\u{2029}0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_ignors_trailing_separators() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\r\n0 0 0 0\r\n");

        assert_eq!(compiler.lines.len(), 2);
    }
}
<commit_msg>Move split lines code into its own function.<commit_after>use std::vec::Vec;
use std::string::String;

struct Compiler {
    pub lines: Vec<String>,
}

impl Compiler {
    pub fn new() -> Self {
        Compiler { lines: Vec::new() }
    }

    pub fn parse(&mut self, assembly: &str) {
        self.split_lines(assembly);
    }

    fn split_lines(&mut self, assembly: &str) {
        let mut line = String::new();
        let mut chars = assembly.chars();

        while let Some(c) = chars.next() {
            match c {
                // Line Feed | Vertical Tab | Form Feed | Next Line | Line/Paragraph Separator
                '\u{000A}' | '\u{000B}' | '\u{000C}' | '\u{0085}' | '\u{2028}' | '\u{2029}' => {
                    self.lines.push(line);
                    line = String::new();
                }

                // Carriage Return
                '\u{000D}' => {
                    self.lines.push(line);
                    line = String::new();

                    // Carriage Return + Line Feed
                    match chars.next() {
                        Some(n) => {
                            if n != '\u{000A}' {
                                line.push(n);
                            }
                        }
                        None => {}
                    }
                }

                _ => {
                    line.push(c);
                }
            }
        }

        if !line.is_empty() {
            self.lines.push(line);
        }
    }
}

#[cfg(test)]
mod tests {
    use super::Compiler;

    #[test]
    fn it_splits_lines_by_line_feed() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\n0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_vertical_tab() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\x0B0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_form_feed() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\x0C0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_carriage_return() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\r0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_carriage_return_line_feed() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\r\n0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_next_line() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\u{0085}0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_line_separator() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\u{2028}0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_splits_lines_by_paragraph_separator() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\u{2029}0 0 0 0");

        assert_eq!(compiler.lines.len(), 2);
    }

    #[test]
    fn it_ignors_trailing_separators() {
        let mut compiler = Compiler::new();
        compiler.parse("0 0 0 0\r\n0 0 0 0\r\n");

        assert_eq!(compiler.lines.len(), 2);
    }
}
<|endoftext|>


<commit_before>use std::io::{Listener, Acceptor};
use std::io::net::tcp::{TcpListener, TcpStream};

static EXT_PORT: u16 = 8443;
static SSH_PORT: u16 = 22;
static SSL_PORT: u16 = 9443;

fn keep_copying(mut a: TcpStream, mut b: TcpStream) {
	let mut buf = [0u8,..1024];
	loop {
		let read = match a.read(buf) {
			Err(..) => { drop(a); return; },
			Ok(r) => r
		};
		match b.write(buf.slice_to(read)) {
			Err(..) => { drop(a); return; },
			Ok(r) => r
		};
	}
}

fn start_pipe(front: TcpStream, port: u16, header: u8) {
	let mut back = match TcpStream::connect("127.0.0.1", port) {
		Err(e) => { println!("Error connecting: {}", e); return; },
		Ok(b) => b
	};
	match back.write_u8(header) {
		Err(e) => { println!("Error writing first byte: {}", e); return }
		Ok(..) => ()
	}
	let front_copy = front.clone();
	let back_copy = back.clone();

	spawn(proc() {
		keep_copying(front, back);
	});
	spawn(proc() {
		keep_copying(back_copy, front_copy);
	});
}

fn handle_new_connection(mut stream: TcpStream) {
	//stream.set_read_timeout(2000);
	let header = match stream.read_byte() {
		Err(..) => -1,
		Ok(b) => b
	};
	if header == 22 || header == 128 {
		start_pipe(stream, SSL_PORT, header);
	}
	else {
		start_pipe(stream, SSH_PORT, header);
	}
}

fn main() {
    let mut acceptor = TcpListener::bind("127.0.0.1", EXT_PORT).listen().unwrap();
    println!("listening started, ready to accept");
    for stream in acceptor.incoming() {
		match stream {
			Err(e) => { /* connection failed */ }
			Ok(stream) => spawn(proc() {
					// connection succeeded
					handle_new_connection(stream);
					})
		}
    }
	drop(acceptor);
}
<commit_msg>Improved the cases<commit_after>use std::io::{Listener, Acceptor};
use std::io::net::tcp::{TcpListener, TcpStream};

static EXT_PORT: u16 = 8443;
static SSH_PORT: u16 = 22;
static SSL_PORT: u16 = 9443;

fn keep_copying(mut a: TcpStream, mut b: TcpStream) {
	let mut buf = [0u8,..1024];
	loop {
		let read = match a.read(buf) {
			Err(..) => { drop(a); return; },
			Ok(r) => r
		};
		match b.write(buf.slice_to(read)) {
			Err(..) => { drop(a); return; },
			Ok(..) => ()
		};
	}
}

fn start_pipe(front: TcpStream, port: u16, header: u8) {
	let mut back = match TcpStream::connect("127.0.0.1", port) {
		Err(e) => { println!("Error connecting: {}", e); return; },
		Ok(b) => b
	};
	match back.write_u8(header) {
		Err(e) => { println!("Error writing first byte: {}", e); return }
		Ok(..) => ()
	}
	let front_copy = front.clone();
	let back_copy = back.clone();

	spawn(proc() {
		keep_copying(front, back);
	});
	spawn(proc() {
		keep_copying(back_copy, front_copy);
	});
}

fn handle_new_connection(mut stream: TcpStream) {
	//stream.set_read_timeout(2000);
	let header = match stream.read_byte() {
		Err(..) => -1,
		Ok(b) => b
	};
	if header == 22 || header == 128 {
		start_pipe(stream, SSL_PORT, header);
	}
	else {
		start_pipe(stream, SSH_PORT, header);
	}
}

fn main() {
    let mut acceptor = TcpListener::bind("127.0.0.1", EXT_PORT).listen().unwrap();
    println!("listening started, ready to accept");
    for stream in acceptor.incoming() {
		match stream {
			Err(e) => println!("Strange connection broken: {}", e),
			Ok(stream) => spawn(proc() {
					// connection succeeded
					handle_new_connection(stream);
					})
		}
    }
	drop(acceptor);
}
<|endoftext|>


<commit_before>//! I/O operations for Rust
//!
//! To be completed

pub mod reader;

pub mod writer;
<commit_msg>Test reading and writing signed and unsigned bytes on a Cursor<Vec<u8>><commit_after>//! I/O operations for Rust
//!
//! To be completed

pub mod reader;

pub mod writer;

#[cfg(test)]
mod test {

    use super::reader::Reader;
    use super::writer::Writer;

    use std::io::Cursor;

    impl Writer for Cursor<Vec<u8>> {

    }

    impl Reader for Cursor<Vec<u8>> {

    }

    #[test]
    fn test_read_write_u8() {

        let mut vector = Cursor::new(vec![0u8; 0]);

        assert!(vector.write_unsigned_byte(15).is_ok());
        assert!(vector.write_unsigned_byte(62).is_ok());

        vector.set_position(0);

        assert_eq!(15, vector.read_unsigned_byte().unwrap());
        assert_eq!(62, vector.read_unsigned_byte().unwrap());

    }

    #[test]
    fn test_read_write_i8() {

        let mut vector = Cursor::new(vec![0u8; 0]);

        assert!(vector.write_signed_byte(-43).is_ok());
        assert!(vector.write_signed_byte(33).is_ok());

        vector.set_position(0);

        assert_eq!(-43, vector.read_signed_byte().unwrap());
        assert_eq!(33, vector.read_signed_byte().unwrap());

    }

}
<|endoftext|>