<commit_before>#[deny(missing_docs)]

extern crate input;
extern crate piston_window;
extern crate rustc_serialize;
extern crate viewport;

mod builder;

use input::{Input, Button, Motion};
use piston_window::Size;
use std::collections::HashMap;
use std::default::Default;
use viewport::Viewport;

pub use builder::InputMapBuilder;

/// Represents a logical action to be bound to a particular button press, e.g.
/// jump, attack, or move forward
pub trait Action: Copy + PartialEq + Eq { }

/// A translated action.
#[derive(Debug, Copy, Clone)]
pub enum Translated<A: Action> {
    /// A keypress event which was bound to an action
    Press(A),

    /// A key release event which was bound to an action
    Release(A),

    /// A translated mouse motion. The logical origin of a translated MouseCursor event
    /// is in the top left corner of the window, and the logical scroll is non-natural.
    /// Relative events are unchanged for now.
    Move(Motion)
}

/// An object which translates piston::input::Input events into input_map::Translated<A> events
#[derive(Clone)]
pub struct InputMap<A: Action> {
    keymap: KeyMap<A>,
    mouse_translator: MouseTranslator
}

impl<A: Action> InputMap<A> {

    /// Creates an empty InputMap.
    pub fn new(size: Size) -> Self {
        InputMap {
            keymap: KeyMap::new(),
            mouse_translator: MouseTranslator::new(size)
        }
    }

    /// Translate an Input into a Translated<A> event
    pub fn translate(&self, input: &Input) -> Option<Translated<A>> {
        macro_rules! translate_button(($but_state:ident, $but_var:ident) => (
            match self.keymap.translate($but_var) {
                Some(act) => Some(Translated::$but_state(act)),
                None => None
            });
        );

        match input {
            &Input::Press(button) => translate_button!(Press, button),
            &Input::Release(button) => translate_button!(Release, button),
            &Input::Move(motion) =>
                Some(Translated::Move(self.mouse_translator.translate(motion))),
            _ => None
        }
    }

    pub fn rebind_button(&mut self, _but: Button, _act: A) {
        // TODO implement
    }

    pub fn add_binding(&mut self, but: Button, act: A) {
        self.keymap.add_mapping(but, act);
    }

    /// Get all the bindings for an action
    pub fn get_bindings_for_action(&self, _act: A) -> ButtonTuple {
        ButtonTuple(None, None, None) // TODO implement
    }

    /// Re-set the mouse bounds size used for calculating mouse events
    pub fn set_size(&mut self, size: Size) {
        self.mouse_translator.viewport_size = size
    }

    /// Re-set the mouse bounds size from a viewport
    pub fn set_size_from_viewport(&mut self, vp: Viewport) {
        self.set_size(Size::from(vp.draw_size));
    }
}

#[derive(Clone)]
struct MouseTranslator {
    pub x_axis_motion_inverted: bool,
    pub y_axis_motion_inverted: bool,
    pub x_axis_scroll_inverted: bool,
    pub y_axis_scroll_inverted: bool,
    pub viewport_size: Size
}

impl MouseTranslator {
    fn new(size: Size) -> Self {
        MouseTranslator {
            x_axis_motion_inverted: false,
            y_axis_motion_inverted: false,
            x_axis_scroll_inverted: false,
            y_axis_scroll_inverted: false,
            viewport_size: size
        }
    }

    fn translate(&self, motion: Motion) -> Motion {
        match motion {
            Motion::MouseCursor(x, y) => {
                let (sw, sh) = {
                    let Size {width, height} = self.viewport_size;
                    (width as f64, height as f64)
                };

                let cx = if self.x_axis_motion_inverted { sw - x } else { x };
                let cy = if self.y_axis_motion_inverted { sh - y } else { y };

                Motion::MouseCursor(cx, cy)
            },
            Motion::MouseScroll(x, y) => {
                let mx = if self.x_axis_scroll_inverted { -1.0f64 } else { 1.0 };
                let my = if self.y_axis_scroll_inverted { -1.0f64 } else { 1.0 };
                Motion::MouseScroll(x * mx, y * my)
            },
            relative => relative
        }
    }
}

#[derive(Clone, Debug)]
struct KeyMap<A: Action> {
    btn_map: HashMap<ButtonTuple, A>
}

impl<A: Action> KeyMap<A> {
    fn new() -> Self {
        KeyMap {
            btn_map: HashMap::new()
        }
    }

    fn add_mapping(&mut self, button: Button, action: A) {
        let mut bt = self.get_bindings_for_action(action).unwrap_or(ButtonTuple::new());
        let bt = if bt.insert_inplace(button) {bt} else {ButtonTuple::new()};
        self.btn_map.insert(bt, action);
    }

    fn _with_mapping(mut self, button: Button, action: A) -> Self {
        self.add_mapping(button, action);
        self
    }

    fn get_bindings_for_action(&self, action: A) -> Option<ButtonTuple> {
        self.btn_map.iter().find(|&(_, &a)| a == action).map(|(&bt, _)| bt)
    }

    fn _get_ref_bindings_for_action(&self, action: A) -> Option<&ButtonTuple> {
        self.btn_map.iter().find(|&(_, &a)| a == action).map(|(bt, _)| bt)
    }

    #[cfg(_false)] // This gives a compile error
    fn _get_ref_bindings_for_action_mut(&mut self, action: A) -> Option<&mut ButtonTuple> {
        self.btn_map.iter_mut().find(|&(_, &mut a)| a == action).as_mut().map(|&mut (bt, _)| bt)
    }

    fn translate(&self, button: Button) -> Option<A> {
        self.btn_map.iter().find(|&(&bt, _)| bt.contains(button)).map(|(_, &a)| a)
    }
}

/// A three-element tuple of Option<Button>. Used as the key of an InputMap
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct ButtonTuple(pub Option<Button>, pub Option<Button>, pub Option<Button>);

impl ButtonTuple {
    fn new() -> Self { Default::default() }

    fn contains(&self, btn: Button) -> bool {
        let sbtn = Some(btn);
        self.0 == sbtn || self.1 == sbtn || self.2 == sbtn
    }

    fn _remove_inplace(&mut self, btn: Button) {
        let sbtn = Some(btn);
        if self.0 == sbtn {self.0 = None}
        if self.1 == sbtn {self.1 = None}
        if self.2 == sbtn {self.2 = None}
    }

    fn _replace_inplace(&mut self, btn_idx: u32, btn: Button) -> bool {
        match btn_idx {
            0 => {self.0 = Some(btn); true},
            1 => {self.1 = Some(btn); true},
            2 => {self.2 = Some(btn); true},
            _ => false
        }
    }

    fn insert_inplace(&mut self, btn: Button) -> bool {
        let &mut ButtonTuple(a, b, c) = self;
        if a.is_none() {
            *self = ButtonTuple(Some(btn), b, c)
        } else if b.is_none() {
            *self = ButtonTuple(a, Some(btn), c)
        } else if c.is_none() {
            *self = ButtonTuple(a, b, Some(btn))
        } else {
            return false;
        }
        true
    }
}

impl Default for ButtonTuple {
    fn default() -> Self { ButtonTuple(None, None, None) }
}
<commit_msg>Refactor ButtonTuple::insert_inplace to use a match statement (45.5% line reduction)<commit_after>#[deny(missing_docs)]

extern crate input;
extern crate piston_window;
extern crate rustc_serialize;
extern crate viewport;

mod builder;

use input::{Input, Button, Motion};
use piston_window::Size;
use std::collections::HashMap;
use std::default::Default;
use viewport::Viewport;

pub use builder::InputMapBuilder;

/// Represents a logical action to be bound to a particular button press, e.g.
/// jump, attack, or move forward
pub trait Action: Copy + PartialEq + Eq { }

/// A translated action.
#[derive(Debug, Copy, Clone)]
pub enum Translated<A: Action> {
    /// A keypress event which was bound to an action
    Press(A),

    /// A key release event which was bound to an action
    Release(A),

    /// A translated mouse motion. The logical origin of a translated MouseCursor event
    /// is in the top left corner of the window, and the logical scroll is non-natural.
    /// Relative events are unchanged for now.
    Move(Motion)
}

/// An object which translates piston::input::Input events into input_map::Translated<A> events
#[derive(Clone)]
pub struct InputMap<A: Action> {
    keymap: KeyMap<A>,
    mouse_translator: MouseTranslator
}

impl<A: Action> InputMap<A> {

    /// Creates an empty InputMap.
    pub fn new(size: Size) -> Self {
        InputMap {
            keymap: KeyMap::new(),
            mouse_translator: MouseTranslator::new(size)
        }
    }

    /// Translate an Input into a Translated<A> event
    pub fn translate(&self, input: &Input) -> Option<Translated<A>> {
        macro_rules! translate_button(($but_state:ident, $but_var:ident) => (
            match self.keymap.translate($but_var) {
                Some(act) => Some(Translated::$but_state(act)),
                None => None
            });
        );

        match input {
            &Input::Press(button) => translate_button!(Press, button),
            &Input::Release(button) => translate_button!(Release, button),
            &Input::Move(motion) =>
                Some(Translated::Move(self.mouse_translator.translate(motion))),
            _ => None
        }
    }

    pub fn rebind_button(&mut self, _but: Button, _act: A) {
        // TODO implement
    }

    pub fn add_binding(&mut self, but: Button, act: A) {
        self.keymap.add_mapping(but, act);
    }

    /// Get all the bindings for an action
    pub fn get_bindings_for_action(&self, _act: A) -> ButtonTuple {
        ButtonTuple(None, None, None) // TODO implement
    }

    /// Re-set the mouse bounds size used for calculating mouse events
    pub fn set_size(&mut self, size: Size) {
        self.mouse_translator.viewport_size = size
    }

    /// Re-set the mouse bounds size from a viewport
    pub fn set_size_from_viewport(&mut self, vp: Viewport) {
        self.set_size(Size::from(vp.draw_size));
    }
}

#[derive(Clone)]
struct MouseTranslator {
    pub x_axis_motion_inverted: bool,
    pub y_axis_motion_inverted: bool,
    pub x_axis_scroll_inverted: bool,
    pub y_axis_scroll_inverted: bool,
    pub viewport_size: Size
}

impl MouseTranslator {
    fn new(size: Size) -> Self {
        MouseTranslator {
            x_axis_motion_inverted: false,
            y_axis_motion_inverted: false,
            x_axis_scroll_inverted: false,
            y_axis_scroll_inverted: false,
            viewport_size: size
        }
    }

    fn translate(&self, motion: Motion) -> Motion {
        match motion {
            Motion::MouseCursor(x, y) => {
                let (sw, sh) = {
                    let Size {width, height} = self.viewport_size;
                    (width as f64, height as f64)
                };

                let cx = if self.x_axis_motion_inverted { sw - x } else { x };
                let cy = if self.y_axis_motion_inverted { sh - y } else { y };

                Motion::MouseCursor(cx, cy)
            },
            Motion::MouseScroll(x, y) => {
                let mx = if self.x_axis_scroll_inverted { -1.0f64 } else { 1.0 };
                let my = if self.y_axis_scroll_inverted { -1.0f64 } else { 1.0 };
                Motion::MouseScroll(x * mx, y * my)
            },
            relative => relative
        }
    }
}

#[derive(Clone, Debug)]
struct KeyMap<A: Action> {
    btn_map: HashMap<ButtonTuple, A>
}

impl<A: Action> KeyMap<A> {
    fn new() -> Self {
        KeyMap {
            btn_map: HashMap::new()
        }
    }

    fn add_mapping(&mut self, button: Button, action: A) {
        let mut bt = self.get_bindings_for_action(action).unwrap_or(ButtonTuple::new());
        let bt = if bt.insert_inplace(button) {bt} else {ButtonTuple::new()};
        self.btn_map.insert(bt, action);
    }

    fn _with_mapping(mut self, button: Button, action: A) -> Self {
        self.add_mapping(button, action);
        self
    }

    fn get_bindings_for_action(&self, action: A) -> Option<ButtonTuple> {
        self.btn_map.iter().find(|&(_, &a)| a == action).map(|(&bt, _)| bt)
    }

    fn _get_ref_bindings_for_action(&self, action: A) -> Option<&ButtonTuple> {
        self.btn_map.iter().find(|&(_, &a)| a == action).map(|(bt, _)| bt)
    }

    #[cfg(_false)] // This gives a compile error
    fn _get_ref_bindings_for_action_mut(&mut self, action: A) -> Option<&mut ButtonTuple> {
        self.btn_map.iter_mut().find(|&(_, &mut a)| a == action).as_mut().map(|&mut (bt, _)| bt)
    }

    fn translate(&self, button: Button) -> Option<A> {
        self.btn_map.iter().find(|&(&bt, _)| bt.contains(button)).map(|(_, &a)| a)
    }
}

/// A three-element tuple of Option<Button>. Used as the key of an InputMap
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct ButtonTuple(pub Option<Button>, pub Option<Button>, pub Option<Button>);

impl ButtonTuple {
    fn new() -> Self { Default::default() }

    fn contains(&self, btn: Button) -> bool {
        let sbtn = Some(btn);
        self.0 == sbtn || self.1 == sbtn || self.2 == sbtn
    }

    fn _remove_inplace(&mut self, btn: Button) {
        let sbtn = Some(btn);
        if self.0 == sbtn {self.0 = None}
        if self.1 == sbtn {self.1 = None}
        if self.2 == sbtn {self.2 = None}
    }

    fn _replace_inplace(&mut self, btn_idx: u32, btn: Button) -> bool {
        match btn_idx {
            0 => {self.0 = Some(btn); true},
            1 => {self.1 = Some(btn); true},
            2 => {self.2 = Some(btn); true},
            _ => false
        }
    }

    fn insert_inplace(&mut self, btn: Button) -> bool {
        match self {
            &mut ButtonTuple(a, b, c) if a.is_none() => {*self = ButtonTuple(Some(btn), b, c); true},
            &mut ButtonTuple(a, b, c) if b.is_none() => {*self = ButtonTuple(a, Some(btn), c); true},
            &mut ButtonTuple(a, b, c) if c.is_none() => {*self = ButtonTuple(a, b, Some(btn)); true}
            _ => false
        }
    }
}

impl Default for ButtonTuple {
    fn default() -> Self { ButtonTuple(None, None, None) }
}
<|endoftext|>


<commit_before>//! Fancy pure Rust crypto and hash library.
//!
//! The main reason this exists is so I can learn about cryptography.
//!
//! If you're asking "We have rust-crypto, why the hell do we need a new
//! library?"), `rust-crypto` was (at the time of Octavio's creation) big pile of… mess. To be honest
//! I doesn't hate `rust-crypto` but I wanted something that will be organized in fancy way, not
//! another OpenSSL (but written in Rust, so probably less buggy).
//!
//! Anther reason is that I want Octavo to became highly configurable via Cargo features. Each
//! cipher, hash family, MAC, etc. should be behind a feature.
//!
//! Oh… one more thing. I want to create C wrapper for Octavo (maybe even OpenSSL compatible), so
//! that you could use this beautiful peace of crap.
//!
//! Happy coding!
//!
//! ## Examples
//!
//!

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(not(feature = "lints"), allow(unknown_lints))]

#![deny(trivial_casts, unreachable_code, while_true)]
#![warn(unused_qualifications)]

extern crate byteorder;
#[cfg(feature = "num")] extern crate num;
#[cfg(feature = "rand")] extern crate rand;

pub mod crypto;
pub mod digest;
pub mod mac;

mod utils;
<commit_msg>fix(): fix typos<commit_after>//! Fancy pure Rust crypto and hash library.
//!
//! The main reason this exists is so I can learn about cryptography.
//!
//! If you're asking "We have rust-crypto, why the hell do we need a new
//! library?"), `rust-crypto` was (at the time of Octavo's creation) big pile of… mess. To be honest
//! I doesn't hate `rust-crypto` but I wanted something that will be organized in fancy way, not
//! another OpenSSL (but written in Rust, so probably less buggy).
//!
//! Anther reason is that I want Octavo to became highly configurable via Cargo features. Each
//! cipher, hash family, MAC, etc. should be behind a feature.
//!
//! Oh… one more thing. I want to create C wrapper for Octavo (maybe even OpenSSL compatible), so
//! that you could use this beautiful peace of crap.
//!
//! Happy coding!
//!
//! ## Examples
//!
//!

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(not(feature = "lints"), allow(unknown_lints))]

#![deny(trivial_casts, unreachable_code, while_true)]
#![warn(unused_qualifications)]

extern crate byteorder;
#[cfg(feature = "num")] extern crate num;
#[cfg(feature = "rand")] extern crate rand;

pub mod crypto;
pub mod digest;
pub mod mac;

mod utils;
<|endoftext|>


<commit_before>#![crate_type= "lib"]

#![feature(collections, core, libc)]

//! A simply library for parsing command line arguments when writing
//! command line and console applications.
//!
//!
//! You can use `clap` to lay out a list of possible valid command line arguments and let `clap` parse the string given by the user at runtime.
//! When using `clap` you define a set of parameters and rules for your arguments and at runtime `clap` will determine their validity.
//! Also, `clap` provides the traditional version and help switches 'for free' by parsing the list of possible valid arguments lazily at runtime.
//! i.e. only when it's been determined that the user wants or needs to see the help and version information.
//!
//! After defining a list of possible valid arguments you get a list of matches that the user supplied at runtime. You can then use this list to
//! determine the functioning of your program.
//!
//! Example:
//!
//! ```no_run
//! use clap::{Arg, App};
//!
//! // ...
//!
//! let matches = App::new("MyApp")
//!						.version("1.0")
//!						.author("Kevin K. <kbknapp@gmail.com>")
//!						.about("Does awesome things")
//!						.arg(Arg::new("config")
//!									.short("c")
//!									.long("config")
//!									.help("Sets a custom config file")
//!									.takes_value(true))
//!						.arg(Arg::new("output")
//!									.help("Sets an optional output file")
//!									.index(1))
//!						.arg(Arg::new("debug")
//!									.short("d")
//! 								.multiple(true)
//!									.help("Turn debugging information on"))
//!						.get_matches();
//!
//!	if let Some(o) = matches.value_of("output") {
//!		println!("Value for output: {}", o);
//!	}
//!
//!	if let Some(c) = matches.value_of("config") {
//!		println!("Value for config: {}", c);
//!	}
//!
//! match matches.occurrences_of("debug") {
//! 	0 => println!("Debug mode is off"),
//!		1 => println!("Debug mode is kind of on"),
//!		2 => println!("Debug mode is on"),
//!		3 | _ => println!("Don't be crazy"),
//! }
//!
//! // more porgram logic goes here...
//! ```
//!
//! If you were to compile the above program and run it with the flag `--help` or `-h` the following output woud be presented
//!
//! ```sh
//! $ myprog --help
//! MyApp 1.0
//! Kevin K. <kbknapp@gmail.com>
//! Does awesome things
//!
//! USAGE:
//! 	MyApp [FLAGS] [OPTIONS] [POSITIONAL]
//!
//! FLAGS:
//! 	d--help   			Turn debugging information on
//! 	h--version,--help		Prints this message
//! 	vd--help,--version	Prints version information
//!
//! OPTIONS:
//! 	ch--version,--config <config>		Sets a custom config file
//!
//! POSITIONAL ARGUMENTS:
//! 	output			Sets an optional output file
//! ```

pub use argmatches::ArgMatches;
pub use arg::Arg;
pub use app::App;

mod app;
mod argmatches;
mod arg;
mod args;
<commit_msg>Added initial testing<commit_after>#![crate_type= "lib"]

#![feature(collections, core, libc)]

//! A simply library for parsing command line arguments when writing
//! command line and console applications.
//!
//!
//! You can use `clap` to lay out a list of possible valid command line arguments and let `clap` parse the string given by the user at runtime.
//! When using `clap` you define a set of parameters and rules for your arguments and at runtime `clap` will determine their validity.
//! Also, `clap` provides the traditional version and help switches 'for free' by parsing the list of possible valid arguments lazily at runtime.
//! i.e. only when it's been determined that the user wants or needs to see the help and version information.
//!
//! After defining a list of possible valid arguments you get a list of matches that the user supplied at runtime. You can then use this list to
//! determine the functioning of your program.
//!
//! Example:
//!
//! ```no_run
//! use clap::{Arg, App};
//!
//! // ...
//!
//! let matches = App::new("MyApp")
//!						.version("1.0")
//!						.author("Kevin K. <kbknapp@gmail.com>")
//!						.about("Does awesome things")
//!						.arg(Arg::new("config")
//!									.short("c")
//!									.long("config")
//!									.help("Sets a custom config file")
//!									.takes_value(true))
//!						.arg(Arg::new("output")
//!									.help("Sets an optional output file")
//!									.index(1))
//!						.arg(Arg::new("debug")
//!									.short("d")
//! 								.multiple(true)
//!									.help("Turn debugging information on"))
//!						.get_matches();
//!
//!	if let Some(o) = matches.value_of("output") {
//!		println!("Value for output: {}", o);
//!	}
//!
//!	if let Some(c) = matches.value_of("config") {
//!		println!("Value for config: {}", c);
//!	}
//!
//! match matches.occurrences_of("debug") {
//! 	0 => println!("Debug mode is off"),
//!		1 => println!("Debug mode is kind of on"),
//!		2 => println!("Debug mode is on"),
//!		3 | _ => println!("Don't be crazy"),
//! }
//!
//! // more porgram logic goes here...
//! ```
//!
//! If you were to compile the above program and run it with the flag `--help` or `-h` the following output woud be presented
//!
//! ```sh
//! $ myprog --help
//! MyApp 1.0
//! Kevin K. <kbknapp@gmail.com>
//! Does awesome things
//!
//! USAGE:
//! 	MyApp [FLAGS] [OPTIONS] [POSITIONAL]
//!
//! FLAGS:
//! 	d--help   			Turn debugging information on
//! 	h--version,--help		Prints this message
//! 	vd--help,--version	Prints version information
//!
//! OPTIONS:
//! 	ch--version,--config <config>		Sets a custom config file
//!
//! POSITIONAL ARGUMENTS:
//! 	output			Sets an optional output file
//! ```

pub use argmatches::ArgMatches;
pub use arg::Arg;
pub use app::App;

mod app;
mod argmatches;
mod arg;
mod args;

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

	#[test]
	#[should_fail]
	fn unique_arg_names(){
		App::new("some").args(vec![
			Arg::new("arg").short("a"),
			Arg::new("arg").short("b")
		]);
	}
	#[test]
	#[should_fail]
	fn unique_arg_shorts(){
		App::new("some").args(vec![
			Arg::new("arg1").short("a"),
			Arg::new("arg2").short("a")
		]);
	}
	#[test]
	#[should_fail]
	fn unique_arg_longs(){
		App::new("some").args(vec![
			Arg::new("arg1").long("long"),
			Arg::new("arg2").long("long")
		]);
	}
	#[test]
	fn create_app(){
		App::new("some").about("about").author("author").version("1.0");
	}
	#[test]
	fn create_arg_flag(){
		Arg::new("some").short("a").long("long").help("help with some arg").multiple(true);
	}
	#[test]
	fn create_arg_pos(){
		Arg::new("some").index(1).help("help with some arg").required(true);
	}
	#[test]
	fn create_arg_opt(){
		Arg::new("some").short("s").long("some").takes_value(true).help("help with some arg").required(true);
	}
}<|endoftext|>


<commit_before>#![crate_name = "graphics"]
#![deny(missing_docs)]
#![feature(default_type_params)]
#![feature(globs)]
#![feature(if_let)]

//! A library for 2D graphics that works with multiple back-ends.

extern crate "vecmath" as vecmath_lib;
extern crate texture;
extern crate read_color;
extern crate current;

pub use texture::ImageSize;

pub use back_end::BackEnd;
pub use draw::Draw;
pub use relative::{
    RelativeColor,
    RelativeRectangle,
    RelativeSourceRectangle,
    RelativeTransform,
    RelativeViewTransform,
};
pub use rectangle::Rectangle;
pub use line::Line;
pub use ellipse::Ellipse;
pub use image::Image;

pub use context::Context as Context;

use current::{ Get, Set };

/// Any triangulation method called on the back-end
/// never exceeds this number of vertices.
/// This can be used to initialize buffers that fit the chunk size.
pub static BACK_END_MAX_VERTEX_COUNT: uint = 1024;

mod back_end;
mod draw;
mod relative;

pub mod context;
pub mod color;
pub mod polygon;
pub mod line;
pub mod ellipse;
pub mod rectangle;
pub mod image;
pub mod internal;
pub mod interpolation;
pub mod modular_index;
pub mod triangulation;
pub mod vecmath;
pub mod deform;
pub mod grid;
pub mod radians;

/// A color property
pub struct Color(pub internal::Color);

/// Wrapper trait for `Get<Color>`
pub trait GetColor: Get<Color> {
    /// Get color
    #[inline(always)]
    fn get_color(&self) -> Color {
        self.get()
    }
}

impl<T: Get<Color>> GetColor for T {}

/// Wrapper trait for `Set<Color>`
pub trait SetColor: Set<Color> {
    /// Set color
    #[inline(always)]
    fn set_color(&mut self, val: Color) {
        self.set_mut(val);
    }
}

impl<T: Set<Color>> SetColor for T {}

/// A rectangle property
pub struct Rect(pub internal::Rectangle);

/// Wrapper trait for `Get<Rect>`
pub trait GetRect: Get<Rect> {
    /// Get rectangle
    #[inline(always)]
    fn get_rect(&self) -> Rect {
        self.get()
    }
}

impl<T: Get<Rect>> GetRect for T {}

/// Wrapper trait for `Set<Rect>`
pub trait SetRect: Set<Rect> {
    /// Set rectangle
    #[inline(always)]
    fn set_rect(&mut self, val: Rect) {
        self.set_mut(val);
    }
}

impl<T: Set<Rect>> SetRect for T {}

/// A source rectangle property
pub struct SrcRect(pub internal::SourceRectangle);

/// Wrapper trait for `Get<SrcRect>`
pub trait GetSrcRect: Get<SrcRect> {
    /// Get source rectangle
    #[inline(always)]
    fn get_src_rect(&self) -> SrcRect {
        self.get()
    }
}

impl<T: Get<SrcRect>> GetSrcRect for T {}

/// Wrapper trait for `Set<SrcRect>`
pub trait SetSrcRect: Set<SrcRect> {
    /// Set source rectangle
    #[inline(always)]
    fn set_src_rect(&mut self, val: SrcRect) {
        self.set_mut(val);
    }
}

impl<T: Set<SrcRect>> SetSrcRect for T {}

<commit_msg>Reexported Polygon<commit_after>#![crate_name = "graphics"]
#![deny(missing_docs)]
#![feature(default_type_params)]
#![feature(globs)]
#![feature(if_let)]

//! A library for 2D graphics that works with multiple back-ends.

extern crate "vecmath" as vecmath_lib;
extern crate texture;
extern crate read_color;
extern crate current;

pub use texture::ImageSize;

pub use back_end::BackEnd;
pub use draw::Draw;
pub use relative::{
    RelativeColor,
    RelativeRectangle,
    RelativeSourceRectangle,
    RelativeTransform,
    RelativeViewTransform,
};
pub use rectangle::Rectangle;
pub use line::Line;
pub use ellipse::Ellipse;
pub use image::Image;
pub use polygon::Polygon;

pub use context::Context as Context;

use current::{ Get, Set };

/// Any triangulation method called on the back-end
/// never exceeds this number of vertices.
/// This can be used to initialize buffers that fit the chunk size.
pub static BACK_END_MAX_VERTEX_COUNT: uint = 1024;

mod back_end;
mod draw;
mod relative;

pub mod context;
pub mod color;
pub mod polygon;
pub mod line;
pub mod ellipse;
pub mod rectangle;
pub mod image;
pub mod internal;
pub mod interpolation;
pub mod modular_index;
pub mod triangulation;
pub mod vecmath;
pub mod deform;
pub mod grid;
pub mod radians;

/// A color property
pub struct Color(pub internal::Color);

/// Wrapper trait for `Get<Color>`
pub trait GetColor: Get<Color> {
    /// Get color
    #[inline(always)]
    fn get_color(&self) -> Color {
        self.get()
    }
}

impl<T: Get<Color>> GetColor for T {}

/// Wrapper trait for `Set<Color>`
pub trait SetColor: Set<Color> {
    /// Set color
    #[inline(always)]
    fn set_color(&mut self, val: Color) {
        self.set_mut(val);
    }
}

impl<T: Set<Color>> SetColor for T {}

/// A rectangle property
pub struct Rect(pub internal::Rectangle);

/// Wrapper trait for `Get<Rect>`
pub trait GetRect: Get<Rect> {
    /// Get rectangle
    #[inline(always)]
    fn get_rect(&self) -> Rect {
        self.get()
    }
}

impl<T: Get<Rect>> GetRect for T {}

/// Wrapper trait for `Set<Rect>`
pub trait SetRect: Set<Rect> {
    /// Set rectangle
    #[inline(always)]
    fn set_rect(&mut self, val: Rect) {
        self.set_mut(val);
    }
}

impl<T: Set<Rect>> SetRect for T {}

/// A source rectangle property
pub struct SrcRect(pub internal::SourceRectangle);

/// Wrapper trait for `Get<SrcRect>`
pub trait GetSrcRect: Get<SrcRect> {
    /// Get source rectangle
    #[inline(always)]
    fn get_src_rect(&self) -> SrcRect {
        self.get()
    }
}

impl<T: Get<SrcRect>> GetSrcRect for T {}

/// Wrapper trait for `Set<SrcRect>`
pub trait SetSrcRect: Set<SrcRect> {
    /// Set source rectangle
    #[inline(always)]
    fn set_src_rect(&mut self, val: SrcRect) {
        self.set_mut(val);
    }
}

impl<T: Set<SrcRect>> SetSrcRect for T {}

<|endoftext|>


<commit_before>#![crate_name = "tar"]
#![crate_type = "lib"]
#![license = "MIT"]

use std::io::fs::File;
use std::collections::hashmap::HashMap;

pub struct Tar {
    filepath: &'static str,
    pub fields: HashMap<&'static str, uint>,
    pub field_size: HashMap<uint, uint>
}

pub fn new(filepath: &'static str) -> Tar {
    let mut fields = HashMap::<&str, uint>::new();
    let mut field_size = HashMap::<uint, uint>::new();

    fields.insert("path", 1);
    fields.insert("mode", 2);
    fields.insert("uid", 3);
    fields.insert("gid", 4);
    fields.insert("size", 5);
    fields.insert("mtime", 6);
    fields.insert("cksum", 7);
    fields.insert("type", 8);
    fields.insert("linkpath", 9);

    // path
    field_size.insert(*fields.get(&"path"), 100);
    // mode
    field_size.insert(*fields.get(&"mode"), 8);
    // uid
    field_size.insert(3, 8);
    // gid
    field_size.insert(4, 8);
    // size
    field_size.insert(5, 12);
    // mtime
    field_size.insert(6, 12);
    // cksum
    field_size.insert(7, 8);
    // type
    field_size.insert(8, 1);
    // linkpath
    field_size.insert(9, 100);

    Tar {
        filepath: filepath,
        fields: fields,
        field_size: field_size
    }
}

impl Tar {

    pub fn read(&self) -> Vec<Vec<u8>> {
        static BLOCK_SIZE: uint = 512;

        let mut split_data = vec!();
        let mut cur_block = 0;
        let mut handle = File::open(&Path::new(self.filepath));
        let data = handle.read_to_end().unwrap();

        while cur_block < data.len() {
            split_data.push(Vec::from_slice(data.slice(cur_block, cur_block + BLOCK_SIZE)));
            cur_block += BLOCK_SIZE;
        }

        split_data
    }

    pub fn extract(&self) {
        fail!();
    }
}

struct TarHeader;

impl TarHeader {
    fn decode() {
        fail!();
    }

    fn encode() {
        fail!();
    }

    fn calc_sum() {
        fail!();
    }

    fn check_sum() {
        fail!();
    }
}
<commit_msg>changing field_size to use fields for reals this time<commit_after>#![crate_name = "tar"]
#![crate_type = "lib"]
#![license = "MIT"]

use std::io::fs::File;
use std::collections::hashmap::HashMap;

pub struct Tar {
    filepath: &'static str,
    pub fields: HashMap<&'static str, uint>,
    pub field_size: HashMap<uint, uint>
}

pub fn new(filepath: &'static str) -> Tar {
    let mut fields = HashMap::<&str, uint>::new();
    let mut field_size = HashMap::<uint, uint>::new();

    fields.insert("path", 1);
    fields.insert("mode", 2);
    fields.insert("uid", 3);
    fields.insert("gid", 4);
    fields.insert("size", 5);
    fields.insert("mtime", 6);
    fields.insert("cksum", 7);
    fields.insert("type", 8);
    fields.insert("linkpath", 9);

    field_size.insert(*fields.get(&"path"), 100);
    field_size.insert(*fields.get(&"mode"), 8);
    field_size.insert(*fields.get(&"uid"), 8);
    field_size.insert(*fields.get(&"gid"), 8);
    field_size.insert(*fields.get(&"size"), 12);
    field_size.insert(*fields.get(&"mtime"), 12);
    field_size.insert(*fields.get(&"cksum"), 8);
    field_size.insert(*fields.get(&"type"), 1);
    field_size.insert(*fields.get(&"linkpath"), 100);

    Tar {
        filepath: filepath,
        fields: fields,
        field_size: field_size
    }
}

impl Tar {

    pub fn read(&self) -> Vec<Vec<u8>> {
        static BLOCK_SIZE: uint = 512;

        let mut split_data = vec!();
        let mut cur_block = 0;
        let mut handle = File::open(&Path::new(self.filepath));
        let data = handle.read_to_end().unwrap();

        while cur_block < data.len() {
            split_data.push(Vec::from_slice(data.slice(cur_block, cur_block + BLOCK_SIZE)));
            cur_block += BLOCK_SIZE;
        }

        split_data
    }

    pub fn extract(&self) {
        fail!();
    }
}

struct TarHeader;

impl TarHeader {
    fn decode() {
        fail!();
    }

    fn encode() {
        fail!();
    }

    fn calc_sum() {
        fail!();
    }

    fn check_sum() {
        fail!();
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
#![allow(unused_parens)]
#![allow(unstable)]
#![feature(box_syntax)]

extern crate syntax;

pub mod lexer;
pub mod token;

#[derive(Copy)]
pub struct Span {
    pub start: u32,
    pub end: u32,
}<commit_msg>Update mod docs with my findings about lexer grammar<commit_after>#![allow(dead_code)]
#![allow(unused_parens)]
#![allow(unstable)]
#![feature(box_syntax)]

extern crate syntax;

/*
 * Rust's lexical grammar is not unambiguous.
 * 'a'b can parse either as <Lifetime><Lifetime
 * or <CharLiteral><Ident>. Libsyntax lexer panic!()s on that.
 * I've took stats from servo and rust sources.
 * Rate of <Lifetime><Token>?<Lifetime> to <CharLiteral><Token>?<Ident>
 * is 378 to 485 in rust and 3 to 49 in servo.
 * That's why we go with the second choice (and raise an error).
 */
pub mod lexer;
pub mod token;

#[derive(Copy)]
pub struct Span {
    pub start: u32,
    pub end: u32,
}<|endoftext|>


<commit_before>extern crate hyper;
extern crate url;

#[macro_use]
extern crate lazy_static;

use hyper::Client;
use std::collections::HashMap;
use std::env::var;
use std::io::Read;
use std::sync::Mutex;
use url::form_urlencoded;

lazy_static! {
    static ref MAP: Mutex<HashMap<u16, u16>> = Mutex::new(HashMap::new());
}

static OK: i8 = 0;
static ERR_INVALID: i8 = -1;

macro_rules! post_query {
    ($path:expr) => (post_query($path, Vec::new()));
    ($path:expr, $query:expr) => (post_query($path, $query));
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern fn CT_init(ctn: u16, pn: u16) -> i8 {
    // Do we know this CTN?
    if MAP.lock().unwrap().contains_key(&ctn) {
        return ERR_INVALID
    }

    // Build the request URL
    let endpoint = "ct_init".to_string();
    let path = endpoint + "/" + &ctn.to_string() + "/" + &pn.to_string();

    // Perform the request
    let response = post_query!(&path);

    match response {
        Ok(v) => {
            // Cast server response
            let response = v.parse::<i8>().unwrap();
            if response == OK {
                // Store CTN
                MAP.lock().unwrap().insert(ctn, pn);
            }

            response
        },
        Err(_) => ERR_INVALID
    }
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern fn CT_data(ctn: u16, dad: u8, sad: u8, lenc: u16, command: u8, lenr: u16, response: u8) -> i8 {

    1
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern fn CT_close(ctn: u16) -> i8 {
    if !MAP.lock().unwrap().contains_key(&ctn) {
        return ERR_INVALID
    }

    let pn = MAP.lock().unwrap().remove(&ctn).unwrap();

    let ctn_string = ctn.to_string();
    let path = "ct_close/".to_string() + &ctn_string + "/" + &pn.to_string();

    let response = post_query!(&path);

    match response {
        Ok(v) => v.parse::<i8>().unwrap(),
        Err(_) => ERR_INVALID
    }
}

fn env_or_default(var_name: &str, default: &str) -> String {
    match var(var_name) {
        Ok(s) => s,
        Err(_) => default.into(),
    }
}

type Query<'a> = Vec<(&'a str, &'a str)>;

fn post_query(path: &str, query: Query) -> hyper::Result<String> {
    // untested
    let base_url = env_or_default("K2_BASE_URL", "http://localhost:8080/k2/ctapi/");
    let url = base_url + path;

    let client = Client::new();
    let body = form_urlencoded::Serializer::new(String::new())
        .extend_pairs(query.iter())
        .finish();
    let mut response = client.post(&url)
        .body(&body[..])
        .send()?;
    let mut buf = String::new();
    response.read_to_string(&mut buf)?;

    Ok(buf)
}
<commit_msg>move type def to head<commit_after>extern crate hyper;
extern crate url;

#[macro_use]
extern crate lazy_static;

use hyper::Client;
use std::collections::HashMap;
use std::env::var;
use std::io::Read;
use std::sync::Mutex;
use url::form_urlencoded;

lazy_static! {
    static ref MAP: Mutex<HashMap<u16, u16>> = Mutex::new(HashMap::new());
}

static OK: i8 = 0;
static ERR_INVALID: i8 = -1;

macro_rules! post_query {
    ($path:expr) => (post_query($path, Vec::new()));
    ($path:expr, $query:expr) => (post_query($path, $query));
}

type Query<'a> = Vec<(&'a str, &'a str)>;

#[no_mangle]
#[allow(non_snake_case)]
pub extern fn CT_init(ctn: u16, pn: u16) -> i8 {
    // Do we know this CTN?
    if MAP.lock().unwrap().contains_key(&ctn) {
        return ERR_INVALID
    }

    // Build the request URL
    let endpoint = "ct_init".to_string();
    let path = endpoint + "/" + &ctn.to_string() + "/" + &pn.to_string();

    // Perform the request
    let response = post_query!(&path);

    match response {
        Ok(v) => {
            // Cast server response
            let response = v.parse::<i8>().unwrap();
            if response == OK {
                // Store CTN
                MAP.lock().unwrap().insert(ctn, pn);
            }

            response
        },
        Err(_) => ERR_INVALID
    }
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern fn CT_data(ctn: u16, dad: u8, sad: u8, lenc: u16, command: u8, lenr: u16, response: u8) -> i8 {

    1
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern fn CT_close(ctn: u16) -> i8 {
    if !MAP.lock().unwrap().contains_key(&ctn) {
        return ERR_INVALID
    }

    let pn = MAP.lock().unwrap().remove(&ctn).unwrap();

    let ctn_string = ctn.to_string();
    let path = "ct_close/".to_string() + &ctn_string + "/" + &pn.to_string();

    let response = post_query!(&path);

    match response {
        Ok(v) => v.parse::<i8>().unwrap(),
        Err(_) => ERR_INVALID
    }
}

fn env_or_default(var_name: &str, default: &str) -> String {
    match var(var_name) {
        Ok(s) => s,
        Err(_) => default.into(),
    }
}

fn post_query(path: &str, query: Query) -> hyper::Result<String> {
    // untested
    let base_url = env_or_default("K2_BASE_URL", "http://localhost:8080/k2/ctapi/");
    let url = base_url + path;

    let client = Client::new();
    let body = form_urlencoded::Serializer::new(String::new())
        .extend_pairs(query.iter())
        .finish();
    let mut response = client.post(&url)
        .body(&body[..])
        .send()?;
    let mut buf = String::new();
    response.read_to_string(&mut buf)?;

    Ok(buf)
}
<|endoftext|>


<commit_before>// Claxon -- A FLAC decoding library in Rust
// Copyright 2014 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

//! Claxon, a FLAC decoding library.
//!
//! Examples
//! ========
//!
//! The following example computes the root mean square (RMS) of a FLAC file.
//!
//! ```
//! # use claxon;
//! let mut reader = claxon::FlacReader::open("testsamples/pop.flac").unwrap();
//! let mut sqr_sum = 0.0;
//! let mut count = 0;
//! for sample in reader.samples() {
//!     let s = sample.unwrap() as f64;
//!     sqr_sum += s * s;
//!     count += 1;
//! }
//! println!("RMS is {}", (sqr_sum / count as f64).sqrt());
//! ```
//!
//! A simple way to decode a file to wav with Claxon and
//! [Hound](https://github.com/ruuda/hound):
//!
//! ```
//! # extern crate hound;
//! # extern crate claxon;
//! # use std::path::Path;
//! # fn decode_file(fname: &Path) {
//! let mut reader = claxon::FlacReader::open(fname).expect("failed to open FLAC stream");
//!
//! let spec = hound::WavSpec {
//!     channels: reader.streaminfo().channels as u16,
//!     sample_rate: reader.streaminfo().sample_rate,
//!     bits_per_sample: reader.streaminfo().bits_per_sample as u16,
//!     sample_format: hound::SampleFormat::Int,
//! };
//!
//! let fname_wav = fname.with_extension("wav");
//! let opt_wav_writer = hound::WavWriter::create(fname_wav, spec);
//! let mut wav_writer = opt_wav_writer.expect("failed to create wav file");
//!
//! for opt_sample in reader.samples() {
//!     let sample = opt_sample.expect("failed to decode FLAC stream");
//!     wav_writer.write_sample(sample).expect("failed to write wav file");
//! }
//! # }
//! ```
//!
//! For more examples, see the [examples](https://github.com/ruuda/claxon/tree/master/examples)
//! directory in the crate.

#![warn(missing_docs)]

use std::fs;
use std::io;
use std::mem;
use std::path;
use error::fmt_err;
use frame::FrameReader;
use input::{BufferedReader, ReadBytes};
use metadata::{MetadataBlock, MetadataBlockReader, StreamInfo};

mod crc;
mod input;
mod error;
pub mod frame;
pub mod subframe;
pub mod metadata;

pub use error::{Error, Result};
pub use frame::Block;

/// A FLAC decoder that can decode the stream from the underlying reader.
///
/// TODO: Add an example.
pub struct FlacReader<R: io::Read> {
    streaminfo: StreamInfo,
    #[allow(dead_code)] // TODO: Expose metadata nicely.
    metadata_blocks: Vec<MetadataBlock>,
    input: BufferedReader<R>,
}

/// An iterator that yields samples read from a `FlacReader`.
pub struct FlacSamples<R: ReadBytes> {
    frame_reader: FrameReader<R>,
    block: Block,
    sample: u32,
    channel: u32,

    /// If reading ever failed, this flag is set, so that the iterator knows not
    /// to return any new values.
    has_failed: bool,
}

// TODO: Add a `FlacIntoSamples`.

fn read_stream_header<R: ReadBytes>(input: &mut R) -> Result<()> {
    // A FLAC stream starts with a 32-bit header 'fLaC' (big endian).
    const HEADER: u32 = 0x66_4c_61_43;
    let header = try!(input.read_be_u32());
    if header != HEADER {
        fmt_err("invalid stream header")
    } else {
        Ok(())
    }
}

impl<R: io::Read> FlacReader<R> {
    /// Attempts to create a reader that reads the FLAC format.
    ///
    /// The header and metadata blocks are read immediately. Audio frames will
    /// be read on demand.
    pub fn new(reader: R) -> Result<FlacReader<R>> {
        let mut buf_reader = BufferedReader::new(reader);

        // A flac stream first of all starts with a stream header.
        try!(read_stream_header(&mut buf_reader));

        // Start a new scope, because the input reader must be available again
        // for the frame reader next.
        let (streaminfo, metadata_blocks) = {
            // Next are one or more metadata blocks. The flac specification
            // dictates that the streaminfo block is the first block. The metadata
            // block reader will yield at least one element, so the unwrap is safe.
            let mut metadata_iter = MetadataBlockReader::new(&mut buf_reader);
            let streaminfo_block = try!(metadata_iter.next().unwrap());
            let streaminfo = match streaminfo_block {
                MetadataBlock::StreamInfo(info) => info,
                _ => return fmt_err("streaminfo block missing"),
            };

            // There might be more metadata blocks, read and store them.
            let mut metadata_blocks = Vec::new();
            for block_result in metadata_iter {
                match block_result {
                    Err(error) => return Err(error),
                    Ok(block) => metadata_blocks.push(block),
                }
            }

            (streaminfo, metadata_blocks)
        };

        // The flac reader will contain the reader that will read frames.
        let flac_reader = FlacReader {
            streaminfo: streaminfo,
            metadata_blocks: metadata_blocks,
            input: buf_reader,
        };

        Ok(flac_reader)
    }

    /// Returns the streaminfo metadata.
    ///
    /// This contains information like the sample rate and number of channels.
    pub fn streaminfo(&self) -> StreamInfo {
        self.streaminfo
    }

    /// Returns an iterator that decodes a single frame on every iteration.
    /// TODO: It is not an iterator.
    ///
    /// This is a low-level primitive that gives you control over when decoding
    /// happens. The representation of the decoded audio is somewhat specific to
    /// the FLAC format. For a higher-level interface, see `samples()`.
    pub fn blocks<'r>(&'r mut self) -> FrameReader<&'r mut BufferedReader<R>> {
        FrameReader::new(&mut self.input)
    }

    /// Returns an iterator over all samples.
    ///
    /// This is a user-friendly interface that trades performance for ease of
    /// use. If performance is an issue, consider using `blocks()` instead.
    ///
    /// This is a high-level interface to the decoder. The cost of retrieving
    /// the next sample can vary significantly, as sometimes a new block has to
    /// be decoded. Additionally, there is a cost to every iteration returning a
    /// `Result`. When a block has been decoded, iterating the samples in that
    /// block can never fail, but a match on every sample is required
    /// nonetheless. For more control over when decoding happens, and less error
    /// handling overhead, use `blocks()`.
    ///
    /// The channel data is is interleaved. The iterator is streaming. That is,
    /// if you call this method once, read a few samples, and call this method
    /// again, the second iterator will not start again from the beginning of
    /// the file. It will continue somewhere after where the first iterator
    /// stopped, and it might skip some samples. (This is because FLAC divides
    /// a stream into blocks, which have to be decoded entirely. If you drop the
    /// iterator, you lose the unread samples in that block.)
    pub fn samples<'r>(&'r mut self) -> FlacSamples<&'r mut BufferedReader<R>> {
        FlacSamples {
            frame_reader: frame::FrameReader::new(&mut self.input),
            block: Block::empty(),
            sample: 0,
            channel: 0,
            has_failed: false,
        }
    }

    /// Destroys the FLAC reader and returns the underlying reader.
    ///
    /// Because the reader employs buffering internally, anything in the buffer
    /// will be lost.
    pub fn into_inner(self) -> R {
        self.input.into_inner()
    }
}

impl FlacReader<fs::File> {
    /// Attempts to create a reader that reads from the specified file.
    ///
    /// This is a convenience constructor that opens a `File`, and constructs a
    /// `FlacReader` from it. There is no need to wrap the file in a
    /// `BufReader`, as the `FlacReader` employs buffering already.
    pub fn open<P: AsRef<path::Path>>(filename: P) -> Result<FlacReader<fs::File>> {
        let file = try!(fs::File::open(filename));
        FlacReader::new(file)
    }
}

impl<R: ReadBytes> Iterator for FlacSamples<R> {
    type Item = Result<i32>;

    fn next(&mut self) -> Option<Result<i32>> {
        // If the previous read failed, end iteration.
        if self.has_failed {
            return None;
        }

        // Iterate the samples channel interleaved, so first increment the
        // channel.
        self.channel += 1;

        // If that was the last channel, increment the sample number.
        if self.channel >= self.block.channels() {
            self.channel = 0;
            self.sample += 1;

            // If that was the last sample in the block, decode the next block.
            if self.sample >= self.block.duration() {
                self.sample = 0;

                // Replace the current block with an empty one so that we may
                // reuse the current buffer to decode again.
                let current_block = mem::replace(&mut self.block, Block::empty());

                match self.frame_reader.read_next_or_eof(current_block.into_buffer()) {
                    Ok(Some(next_block)) => {
                        self.block = next_block;
                    }
                    Ok(None) => {
                        // The stream ended with EOF.
                        // TODO: If a number of samples was specified in the
                        // streaminfo metadata block, verify that we did not
                        // read more or less samples.
                        return None;
                    }
                    Err(error) => {
                        self.has_failed = true;
                        return Some(Err(error));
                    }
                }
            }
        }

        Some(Ok(self.block.sample(self.channel, self.sample)))
    }
}
<commit_msg>Add helpful error message for ID3 headers<commit_after>// Claxon -- A FLAC decoding library in Rust
// Copyright 2014 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

//! Claxon, a FLAC decoding library.
//!
//! Examples
//! ========
//!
//! The following example computes the root mean square (RMS) of a FLAC file.
//!
//! ```
//! # use claxon;
//! let mut reader = claxon::FlacReader::open("testsamples/pop.flac").unwrap();
//! let mut sqr_sum = 0.0;
//! let mut count = 0;
//! for sample in reader.samples() {
//!     let s = sample.unwrap() as f64;
//!     sqr_sum += s * s;
//!     count += 1;
//! }
//! println!("RMS is {}", (sqr_sum / count as f64).sqrt());
//! ```
//!
//! A simple way to decode a file to wav with Claxon and
//! [Hound](https://github.com/ruuda/hound):
//!
//! ```
//! # extern crate hound;
//! # extern crate claxon;
//! # use std::path::Path;
//! # fn decode_file(fname: &Path) {
//! let mut reader = claxon::FlacReader::open(fname).expect("failed to open FLAC stream");
//!
//! let spec = hound::WavSpec {
//!     channels: reader.streaminfo().channels as u16,
//!     sample_rate: reader.streaminfo().sample_rate,
//!     bits_per_sample: reader.streaminfo().bits_per_sample as u16,
//!     sample_format: hound::SampleFormat::Int,
//! };
//!
//! let fname_wav = fname.with_extension("wav");
//! let opt_wav_writer = hound::WavWriter::create(fname_wav, spec);
//! let mut wav_writer = opt_wav_writer.expect("failed to create wav file");
//!
//! for opt_sample in reader.samples() {
//!     let sample = opt_sample.expect("failed to decode FLAC stream");
//!     wav_writer.write_sample(sample).expect("failed to write wav file");
//! }
//! # }
//! ```
//!
//! For more examples, see the [examples](https://github.com/ruuda/claxon/tree/master/examples)
//! directory in the crate.

#![warn(missing_docs)]

use std::fs;
use std::io;
use std::mem;
use std::path;
use error::fmt_err;
use frame::FrameReader;
use input::{BufferedReader, ReadBytes};
use metadata::{MetadataBlock, MetadataBlockReader, StreamInfo};

mod crc;
mod input;
mod error;
pub mod frame;
pub mod subframe;
pub mod metadata;

pub use error::{Error, Result};
pub use frame::Block;

/// A FLAC decoder that can decode the stream from the underlying reader.
///
/// TODO: Add an example.
pub struct FlacReader<R: io::Read> {
    streaminfo: StreamInfo,
    #[allow(dead_code)] // TODO: Expose metadata nicely.
    metadata_blocks: Vec<MetadataBlock>,
    input: BufferedReader<R>,
}

/// An iterator that yields samples read from a `FlacReader`.
pub struct FlacSamples<R: ReadBytes> {
    frame_reader: FrameReader<R>,
    block: Block,
    sample: u32,
    channel: u32,

    /// If reading ever failed, this flag is set, so that the iterator knows not
    /// to return any new values.
    has_failed: bool,
}

// TODO: Add a `FlacIntoSamples`.

fn read_stream_header<R: ReadBytes>(input: &mut R) -> Result<()> {
    // A FLAC stream starts with a 32-bit header 'fLaC' (big endian).
    const FLAC_HEADER: u32 = 0x66_4c_61_43;

    // Some files start with ID3 tag data. The reference decoder supports this
    // for convenience. Claxon does not, but we can at least generate a helpful
    // error message if a file starts like this.
    const ID3_HEADER: u32 = 0x49_44_33_00;

    let header = try!(input.read_be_u32());
    if header != FLAC_HEADER {
        if (header & 0xff_ff_ff_00) == ID3_HEADER {
            fmt_err("stream starts with ID3 header rather than FLAC header")
        } else {
            fmt_err("invalid stream header")
        }
    } else {
        Ok(())
    }
}

impl<R: io::Read> FlacReader<R> {
    /// Attempts to create a reader that reads the FLAC format.
    ///
    /// The header and metadata blocks are read immediately. Audio frames will
    /// be read on demand.
    pub fn new(reader: R) -> Result<FlacReader<R>> {
        let mut buf_reader = BufferedReader::new(reader);

        // A flac stream first of all starts with a stream header.
        try!(read_stream_header(&mut buf_reader));

        // Start a new scope, because the input reader must be available again
        // for the frame reader next.
        let (streaminfo, metadata_blocks) = {
            // Next are one or more metadata blocks. The flac specification
            // dictates that the streaminfo block is the first block. The metadata
            // block reader will yield at least one element, so the unwrap is safe.
            let mut metadata_iter = MetadataBlockReader::new(&mut buf_reader);
            let streaminfo_block = try!(metadata_iter.next().unwrap());
            let streaminfo = match streaminfo_block {
                MetadataBlock::StreamInfo(info) => info,
                _ => return fmt_err("streaminfo block missing"),
            };

            // There might be more metadata blocks, read and store them.
            let mut metadata_blocks = Vec::new();
            for block_result in metadata_iter {
                match block_result {
                    Err(error) => return Err(error),
                    Ok(block) => metadata_blocks.push(block),
                }
            }

            (streaminfo, metadata_blocks)
        };

        // The flac reader will contain the reader that will read frames.
        let flac_reader = FlacReader {
            streaminfo: streaminfo,
            metadata_blocks: metadata_blocks,
            input: buf_reader,
        };

        Ok(flac_reader)
    }

    /// Returns the streaminfo metadata.
    ///
    /// This contains information like the sample rate and number of channels.
    pub fn streaminfo(&self) -> StreamInfo {
        self.streaminfo
    }

    /// Returns an iterator that decodes a single frame on every iteration.
    /// TODO: It is not an iterator.
    ///
    /// This is a low-level primitive that gives you control over when decoding
    /// happens. The representation of the decoded audio is somewhat specific to
    /// the FLAC format. For a higher-level interface, see `samples()`.
    pub fn blocks<'r>(&'r mut self) -> FrameReader<&'r mut BufferedReader<R>> {
        FrameReader::new(&mut self.input)
    }

    /// Returns an iterator over all samples.
    ///
    /// This is a user-friendly interface that trades performance for ease of
    /// use. If performance is an issue, consider using `blocks()` instead.
    ///
    /// This is a high-level interface to the decoder. The cost of retrieving
    /// the next sample can vary significantly, as sometimes a new block has to
    /// be decoded. Additionally, there is a cost to every iteration returning a
    /// `Result`. When a block has been decoded, iterating the samples in that
    /// block can never fail, but a match on every sample is required
    /// nonetheless. For more control over when decoding happens, and less error
    /// handling overhead, use `blocks()`.
    ///
    /// The channel data is is interleaved. The iterator is streaming. That is,
    /// if you call this method once, read a few samples, and call this method
    /// again, the second iterator will not start again from the beginning of
    /// the file. It will continue somewhere after where the first iterator
    /// stopped, and it might skip some samples. (This is because FLAC divides
    /// a stream into blocks, which have to be decoded entirely. If you drop the
    /// iterator, you lose the unread samples in that block.)
    pub fn samples<'r>(&'r mut self) -> FlacSamples<&'r mut BufferedReader<R>> {
        FlacSamples {
            frame_reader: frame::FrameReader::new(&mut self.input),
            block: Block::empty(),
            sample: 0,
            channel: 0,
            has_failed: false,
        }
    }

    /// Destroys the FLAC reader and returns the underlying reader.
    ///
    /// Because the reader employs buffering internally, anything in the buffer
    /// will be lost.
    pub fn into_inner(self) -> R {
        self.input.into_inner()
    }
}

impl FlacReader<fs::File> {
    /// Attempts to create a reader that reads from the specified file.
    ///
    /// This is a convenience constructor that opens a `File`, and constructs a
    /// `FlacReader` from it. There is no need to wrap the file in a
    /// `BufReader`, as the `FlacReader` employs buffering already.
    pub fn open<P: AsRef<path::Path>>(filename: P) -> Result<FlacReader<fs::File>> {
        let file = try!(fs::File::open(filename));
        FlacReader::new(file)
    }
}

impl<R: ReadBytes> Iterator for FlacSamples<R> {
    type Item = Result<i32>;

    fn next(&mut self) -> Option<Result<i32>> {
        // If the previous read failed, end iteration.
        if self.has_failed {
            return None;
        }

        // Iterate the samples channel interleaved, so first increment the
        // channel.
        self.channel += 1;

        // If that was the last channel, increment the sample number.
        if self.channel >= self.block.channels() {
            self.channel = 0;
            self.sample += 1;

            // If that was the last sample in the block, decode the next block.
            if self.sample >= self.block.duration() {
                self.sample = 0;

                // Replace the current block with an empty one so that we may
                // reuse the current buffer to decode again.
                let current_block = mem::replace(&mut self.block, Block::empty());

                match self.frame_reader.read_next_or_eof(current_block.into_buffer()) {
                    Ok(Some(next_block)) => {
                        self.block = next_block;
                    }
                    Ok(None) => {
                        // The stream ended with EOF.
                        // TODO: If a number of samples was specified in the
                        // streaminfo metadata block, verify that we did not
                        // read more or less samples.
                        return None;
                    }
                    Err(error) => {
                        self.has_failed = true;
                        return Some(Err(error));
                    }
                }
            }
        }

        Some(Ok(self.block.sample(self.channel, self.sample)))
    }
}
<|endoftext|>


<commit_before>//! Slow and basic handling of primes.

use std::{iter, option, cmp};
use std::collections::{Bitv, bitv};

/// Stores information about primes.
pub struct Primes {
    // This only stores odd numbers, since even numbers are mostly
    // non-prime.
    v: Bitv
}

pub type PrimeIterator<'a> = iter::Chain<
    option::Item<uint>,
    iter::FilterMap<'static, (uint, bool), uint,
       iter::Enumerate<bitv::Bits<'a>>>>;

pub type Factorisation = Vec<(uint, u32)>;

impl Primes {
    /// Construct a `Primes` via a sieve, stopping at `upto`.
    pub fn sieve(upto: uint) -> Primes {
        // bad stuff happens for very small bounds.
        let upto = cmp::max(10, upto);

        let mut is_prime = Bitv::with_capacity((upto + 1) / 2, true);
        // 1 isn't prime
        is_prime.set(0, false);

        // multiples of 3 aren't prime (3 is handled separately, so
        // the ticking works properly)
        for i in iter::range_step(4, upto / 2, 3) {
            is_prime.set(i, false);
        }

        let mut check = 2; // 5
        let mut tick = 1; // step by 2 to get 7
        let bound = (upto as f64).sqrt() as uint + 1;
        while check <= bound {
            if is_prime[check] {
                let p = 2 * check + 1;
                for zero in iter::range_step(2 * check * (check + 1), upto / 2, p) {
                    is_prime.set(zero, false);
                }
            }

            check += tick;
            tick = 3 - tick;
        }

        Primes { v: is_prime }
    }

    /// The largest number stored.
    pub fn upper_bound(&self) -> uint {
        self.v.len() * 2 + 1
    }

    /// Check if `n` is prime, failing if `n` is larger than the upper
    /// bound of this Primes instance.
    pub fn is_prime(&self, n: uint) -> bool {
        assert!(n <= self.upper_bound());
        if n % 2 == 0 {
            // 2 is the evenest prime.
            n == 2
        } else {
            self.v[n / 2]
        }
    }

    /// Iterator over the primes stored in this map.
    pub fn primes<'a>(&'a self) -> PrimeIterator<'a> {
        Some(2).move_iter()
            .chain(self.v.iter().enumerate().filter_map(|(i, is_prime)| {
                if is_prime {
                    Some(2 * i + 1)
                } else {
                    None
                }
            }))
    }

    /// Factorise `n` into (prime, exponent pairs).
    ///
    /// Will fail if n has any factors large than the upper bound of
    /// this `Primes` instance.
    pub fn factor(&self, mut n: uint) -> Vec<(uint, u32)> {
        assert!(n > 0);
        let mut ret = Vec::new();

        for p in self.primes() {
            if n == 1 { break }

            let mut count = 0;
            while n % p == 0 {
                n /= p;
                count += 1;
            }
            if count > 0 {
                ret.push((p,count));
            }
        }
        // FIXME handle errors properly
        assert!(n == 1);
        ret
    }
}

#[cfg(test)]
mod tests {
    extern crate test;

    use super::Primes;
    use self::test::Bencher;

    #[test]
    fn is_prime() {
        let primes = Primes::sieve(1000);
        let tests = [
            (0, false),
            (1, false),
            (2, true),
            (3, true),
            (4, false),
            (5, true),
            (6, false),
            (7, true),
            (8, false),
            (9, false),
            (10, false),
            (11, true)
                ];

        for &(n, expected) in tests.iter() {
            assert_eq!(primes.is_prime(n), expected);
        }
    }

    #[test]
    fn primes_iterator() {
        let primes = Primes::sieve(1000);
        let expected = &[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];

        assert_eq!(primes.primes().take(expected.len()).collect::<Vec<uint>>().as_slice(),
                   expected);
    }

    #[test]
    fn factor() {
        let primes = Primes::sieve(1000);

        let tests = [
            (1, &[]),
            (2, &[(2u, 1u32)]),
            (3, &[(3, 1)]),
            (4, &[(2, 2)]),
            (5, &[(5, 1)]),
            (6, &[(2, 1), (3, 1)]),
            (7, &[(7, 1)]),
            (8, &[(2, 3)]),
            (9, &[(3, 2)]),
            (10, &[(2, 1), (5, 1)]),
            ];
        for &(n, expected) in tests.iter() {
            assert_eq!(primes.factor(n), expected.to_vec());
        }
    }

    #[bench]
    fn sieve_small(b: &mut Bencher) {
        b.iter(|| Primes::sieve(100))
    }
    #[bench]
    fn sieve_medium(b: &mut Bencher) {
        b.iter(|| Primes::sieve(10_000))
    }
    #[bench]
    fn sieve_large(b: &mut Bencher) {
        b.iter(|| Primes::sieve(100_000))
    }
}
<commit_msg>Update to 5419b2ca2 2014-08-29 22:16:20 +0000.<commit_after>//! Slow and basic handling of primes.

use std::{iter, option, cmp};
use std::collections::{Bitv, bitv};

/// Stores information about primes.
pub struct Primes {
    // This only stores odd numbers, since even numbers are mostly
    // non-prime.
    v: Bitv
}

pub type PrimeIterator<'a> = iter::Chain<
    option::Item<uint>,
    iter::FilterMap<'static, (uint, bool), uint,
       iter::Enumerate<bitv::Bits<'a>>>>;

pub type Factorisation = Vec<(uint, u32)>;

impl Primes {
    /// Construct a `Primes` via a sieve, stopping at `upto`.
    pub fn sieve(upto: uint) -> Primes {
        // bad stuff happens for very small bounds.
        let upto = cmp::max(10, upto);

        let mut is_prime = Bitv::with_capacity((upto + 1) / 2, true);
        // 1 isn't prime
        is_prime.set(0, false);

        // multiples of 3 aren't prime (3 is handled separately, so
        // the ticking works properly)
        for i in iter::range_step(4, upto / 2, 3) {
            is_prime.set(i, false);
        }

        let mut check = 2; // 5
        let mut tick = 1; // step by 2 to get 7
        let bound = (upto as f64).sqrt() as uint + 1;
        while check <= bound {
            if is_prime[check] {
                let p = 2 * check + 1;
                for zero in iter::range_step(2 * check * (check + 1), upto / 2, p) {
                    is_prime.set(zero, false);
                }
            }

            check += tick;
            tick = 3 - tick;
        }

        Primes { v: is_prime }
    }

    /// The largest number stored.
    pub fn upper_bound(&self) -> uint {
        self.v.len() * 2 + 1
    }

    /// Check if `n` is prime, failing if `n` is larger than the upper
    /// bound of this Primes instance.
    pub fn is_prime(&self, n: uint) -> bool {
        assert!(n <= self.upper_bound());
        if n % 2 == 0 {
            // 2 is the evenest prime.
            n == 2
        } else {
            self.v[n / 2]
        }
    }

    /// Iterator over the primes stored in this map.
    pub fn primes<'a>(&'a self) -> PrimeIterator<'a> {
        Some(2).move_iter()
            .chain(self.v.iter().enumerate().filter_map(|(i, is_prime)| {
                if is_prime {
                    Some(2 * i + 1)
                } else {
                    None
                }
            }))
    }

    /// Factorise `n` into (prime, exponent pairs).
    ///
    /// Will fail if n has any factors large than the upper bound of
    /// this `Primes` instance.
    pub fn factor(&self, mut n: uint) -> Vec<(uint, u32)> {
        assert!(n > 0);
        let mut ret = Vec::new();

        for p in self.primes() {
            if n == 1 { break }

            let mut count = 0;
            while n % p == 0 {
                n /= p;
                count += 1;
            }
            if count > 0 {
                ret.push((p,count));
            }
        }
        // FIXME handle errors properly
        assert!(n == 1);
        ret
    }
}

#[cfg(test)]
mod tests {
    extern crate test;

    use super::Primes;
    use self::test::Bencher;

    #[test]
    fn is_prime() {
        let primes = Primes::sieve(1000);
        let tests = [
            (0, false),
            (1, false),
            (2, true),
            (3, true),
            (4, false),
            (5, true),
            (6, false),
            (7, true),
            (8, false),
            (9, false),
            (10, false),
            (11, true)
                ];

        for &(n, expected) in tests.iter() {
            assert_eq!(primes.is_prime(n), expected);
        }
    }

    #[test]
    fn primes_iterator() {
        let primes = Primes::sieve(1000);
        let expected = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];

        assert_eq!(primes.primes().take(expected.len()).collect::<Vec<uint>>().as_slice(),
                   expected.as_slice());
    }

    #[test]
    fn factor() {
        let primes = Primes::sieve(1000);

        let tests: &[(uint, &[(uint, u32)])] = &[
            (1, &[]),
            (2, &[(2u, 1u32)]),
            (3, &[(3, 1)]),
            (4, &[(2, 2)]),
            (5, &[(5, 1)]),
            (6, &[(2, 1), (3, 1)]),
            (7, &[(7, 1)]),
            (8, &[(2, 3)]),
            (9, &[(3, 2)]),
            (10, &[(2, 1), (5, 1)]),
            ];
        for &(n, expected) in tests.iter() {
            assert_eq!(primes.factor(n), expected.to_vec());
        }
    }

    #[bench]
    fn sieve_small(b: &mut Bencher) {
        b.iter(|| Primes::sieve(100))
    }
    #[bench]
    fn sieve_medium(b: &mut Bencher) {
        b.iter(|| Primes::sieve(10_000))
    }
    #[bench]
    fn sieve_large(b: &mut Bencher) {
        b.iter(|| Primes::sieve(100_000))
    }
}
<|endoftext|>


<commit_before>//! SputnikVM implementation, traits and structs
//!
//! ### Lifecycle
//!
//! A VM can be started given a `Context` and a `BlockHeader`. The
//! user can then `fire` or `step` to run it. Those functions would
//! only fail if it needs some information (accounts in the current
//! block, or block hashes of previous blocks). If this happens, one
//! can use the function `commit_account` and `commit_blockhash` to
//! commit those information to the VM, and `fire` or `step` again
//! until it succeeds. The current VM status can always be obtained
//! using the `status` function.

#![deny(unused_import_braces, unused_imports,
        unused_comparisons, unused_must_use,
        unused_variables, non_shorthand_field_patterns,
        unreachable_code, missing_docs)]

#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]

#[cfg(not(feature = "std"))]
extern crate alloc;

extern crate rlp;
extern crate bigint;
extern crate block_core;
extern crate sha3;
extern crate ripemd160;
extern crate sha2;
extern crate digest;

#[cfg(feature = "c-secp256k1")]
extern crate secp256k1;

#[cfg(feature = "rust-secp256k1")]
extern crate secp256k1;

#[cfg(feature = "std")]
extern crate block;

#[cfg(test)]
extern crate hexutil;

mod util;
mod memory;
mod stack;
mod pc;
mod params;
mod eval;
mod commit;
mod patch;
mod transaction;
pub mod errors;

pub use self::memory::{Memory, SeqMemory};
pub use self::stack::Stack;
pub use self::pc::{PC, PCMut, Instruction, Valids};
pub use self::params::*;
pub use self::patch::*;
pub use self::eval::{State, Machine, Runtime, MachineStatus};
pub use self::commit::{AccountCommitment, AccountChange, AccountState, BlockhashState, Storage};
pub use self::transaction::{ValidTransaction, TransactionVM, UntrustedTransaction};
pub use self::errors::{OnChainError, NotSupportedError, RequireError, CommitError, PreExecutionError};
pub use self::util::opcode::Opcode;
pub use block_core::TransactionAction;

#[cfg(not(feature = "std"))]
use alloc::Vec;

#[cfg(feature = "std")] use std::collections::{HashSet as Set, hash_map as map};
#[cfg(not(feature = "std"))] use alloc::{BTreeSet as Set, btree_map as map};
#[cfg(feature = "std")] use std::cmp::min;
#[cfg(not(feature = "std"))] use core::cmp::min;
use bigint::{U256, H256, Gas, Address};

#[derive(Debug, Clone)]
/// VM Status
pub enum VMStatus {
    /// A running VM.
    Running,
    /// VM is stopped without errors.
    ExitedOk,
    /// VM is stopped due to an error. The state of the VM is before
    /// the last failing instruction.
    ExitedErr(OnChainError),
    /// VM is stopped because it does not support certain
    /// operations. The client is expected to either drop the
    /// transaction or panic. This rarely happens unless the executor
    /// agrees upon on a really large number of gas limit, so it
    /// usually can be safely ignored.
    ExitedNotSupported(NotSupportedError),
}

/// Represents an EVM. This is usually the main interface for clients
/// to interact with.
pub trait VM {
    /// Commit an account information to this VM. This should only
    /// be used when receiving `RequireError`.
    fn commit_account(&mut self, commitment: AccountCommitment) -> Result<(), CommitError>;
    /// Commit a block hash to this VM. This should only be used when
    /// receiving `RequireError`.
    fn commit_blockhash(&mut self, number: U256, hash: H256) -> Result<(), CommitError>;
    /// Returns the current status of the VM.
    fn status(&self) -> VMStatus;
    /// Read the next instruction to be executed.
    fn peek(&self) -> Option<Instruction>;
    /// Read the next opcode to be executed.
    fn peek_opcode(&self) -> Option<Opcode>;
    /// Run one instruction and return. If it succeeds, VM status can
    /// still be `Running`. If the call stack has more than one items,
    /// this will only executes the last items' one single
    /// instruction.
    fn step(&mut self) -> Result<(), RequireError>;
    /// Run instructions until it reaches a `RequireError` or
    /// exits. If this function succeeds, the VM status can only be
    /// either `ExitedOk` or `ExitedErr`.
    fn fire(&mut self) -> Result<(), RequireError> {
        loop {
            match self.status() {
                VMStatus::Running => self.step()?,
                VMStatus::ExitedOk | VMStatus::ExitedErr(_) |
                VMStatus::ExitedNotSupported(_) => return Ok(()),
            }
        }
    }
    /// Returns the changed or committed accounts information up to
    /// current execution status.
    fn accounts(&self) -> map::Values<Address, AccountChange>;
    /// Returns all fetched or modified addresses.
    fn used_addresses(&self) -> Set<Address>;
    /// Returns the out value, if any.
    fn out(&self) -> &[u8];
    /// Returns the available gas of this VM.
    fn available_gas(&self) -> Gas;
    /// Returns the refunded gas of this VM.
    fn refunded_gas(&self) -> Gas;
    /// Returns logs to be appended to the current block if the user
    /// decided to accept the running status of this VM.
    fn logs(&self) -> &[Log];
    /// Returns all removed account addresses as for current VM execution.
    fn removed(&self) -> &[Address];
    /// Returns the real used gas by the transaction or the VM
    /// context. Only available when the status of the VM is
    /// exited. Otherwise returns zero.
    fn used_gas(&self) -> Gas;
}

/// A sequencial VM. It uses sequencial memory representation and hash
/// map storage for accounts.
pub type SeqContextVM<P> = ContextVM<SeqMemory<P>, P>;
/// A sequencial transaction VM. This is same as `SeqContextVM` except
/// it runs at transaction level.
pub type SeqTransactionVM<P> = TransactionVM<SeqMemory<P>, P>;

/// A VM that executes using a context and block information.
pub struct ContextVM<M, P: Patch> {
    runtime: Runtime,
    machines: Vec<Machine<M, P>>,
    fresh_account_state: AccountState<P::Account>,
}

impl<M: Memory + Default, P: Patch> ContextVM<M, P> {
    /// Create a new VM using the given context, block header and patch.
    pub fn new(context: Context, block: HeaderParams) -> Self {
        let mut machines = Vec::new();
        machines.push(Machine::new(context, 1));
        ContextVM {
            machines,
            runtime: Runtime::new(block),
            fresh_account_state: AccountState::default(),
        }
    }

    /// Create a new VM with the given account state and blockhash state.
    pub fn with_states(context: Context, block: HeaderParams,
                       account_state: AccountState<P::Account>, blockhash_state: BlockhashState) -> Self {
        let mut machines = Vec::new();
        machines.push(Machine::with_states(context, 1, account_state.clone()));
        ContextVM {
            machines,
            runtime: Runtime::with_states(block, blockhash_state),
            fresh_account_state: account_state,
        }
    }

    /// Create a new VM with customized initialization code.
    pub fn with_init<F: FnOnce(&mut ContextVM<M, P>)>(
        context: Context, block: HeaderParams,
        account_state: AccountState<P::Account>, blockhash_state: BlockhashState,
        f: F) -> Self {
        let mut vm = Self::with_states(context, block, account_state, blockhash_state);
        f(&mut vm);
        vm.fresh_account_state = vm.machines[0].state().account_state.clone();
        vm
    }

    /// Create a new VM with the result of the previous VM. This is
    /// usually used by transaction for chainning them.
    pub fn with_previous(context: Context, block: HeaderParams, vm: &ContextVM<M, P>) -> Self {
        Self::with_states(context, block,
                          vm.machines[0].state().account_state.clone(),
                          vm.runtime.blockhash_state.clone())
    }

    /// Returns the current state of the VM.
    pub fn current_state(&self) -> &State<M, P> {
        self.current_machine().state()
    }

    /// Returns the current runtime machine.
    pub fn current_machine(&self) -> &Machine<M, P> {
        self.machines.last().unwrap()
    }

    /// Add a new context history hook.
    pub fn add_context_history_hook<F: 'static + Fn(&Context)>(&mut self, f: F) {
        self.runtime.context_history_hooks.push(Box::new(f));
    }
}

impl<M: Memory + Default, P: Patch> VM for ContextVM<M, P> {
    fn commit_account(&mut self, commitment: AccountCommitment) -> Result<(), CommitError> {
        for machine in &mut self.machines {
            machine.commit_account(commitment.clone())?;
        }
        Ok(())
    }

    fn commit_blockhash(&mut self, number: U256, hash: H256) -> Result<(), CommitError> {
        self.runtime.blockhash_state.commit(number, hash)
    }

    fn status(&self) -> VMStatus {
        match self.machines.last().unwrap().status().clone() {
            MachineStatus::ExitedNotSupported(err) => return VMStatus::ExitedNotSupported(err),
            _ => (),
        }

        match self.machines[0].status() {
            MachineStatus::Running | MachineStatus::InvokeCreate(_) | MachineStatus::InvokeCall(_, _) => VMStatus::Running,
            MachineStatus::ExitedOk => VMStatus::ExitedOk,
            MachineStatus::ExitedErr(err) => VMStatus::ExitedErr(err.into()),
            MachineStatus::ExitedNotSupported(err) => VMStatus::ExitedNotSupported(err),
        }
    }

    fn peek(&self) -> Option<Instruction> {
        match self.machines.last().unwrap().status().clone() {
            MachineStatus::Running => {
                self.machines.last().unwrap().peek()
            },
            _ => None,
        }
    }

    fn peek_opcode(&self) -> Option<Opcode> {
        match self.machines.last().unwrap().status().clone() {
            MachineStatus::Running => {
                self.machines.last().unwrap().peek_opcode()
            },
            _ => None,
        }
    }

    fn step(&mut self) -> Result<(), RequireError> {
        match self.machines.last().unwrap().status().clone() {
            MachineStatus::Running => {
                self.machines.last_mut().unwrap().step(&self.runtime)?;
                if self.machines.len() == 1 {
                    match self.machines.last().unwrap().status().clone() {
                        MachineStatus::ExitedOk | MachineStatus::ExitedErr(_) =>
                            self.machines.last_mut().unwrap().finalize_context(&self.fresh_account_state),
                        _ => (),
                    }
                }
                Ok(())
            },
            MachineStatus::ExitedOk | MachineStatus::ExitedErr(_) => {
                if self.machines.len() == 0 {
                    panic!()
                } else if self.machines.len() == 1 {
                    Ok(())
                } else {
                    let finished = self.machines.pop().unwrap();
                    self.machines.last_mut().unwrap().apply_sub(finished);
                    Ok(())
                }
            },
            MachineStatus::ExitedNotSupported(_) => {
                Ok(())
            },
            MachineStatus::InvokeCall(context, _) => {
                for hook in &self.runtime.context_history_hooks {
                    hook(&context)
                }

                let mut sub = self.machines.last().unwrap().derive(context);
                sub.invoke_call()?;
                self.machines.push(sub);
                Ok(())
            },
            MachineStatus::InvokeCreate(context) => {
               for hook in &self.runtime.context_history_hooks {
                    hook(&context)
                }

                let mut sub = self.machines.last().unwrap().derive(context);
                sub.invoke_create()?;
                self.machines.push(sub);
                Ok(())
            },
        }
    }

    fn fire(&mut self) -> Result<(), RequireError> {
        loop {
            match self.status() {
                VMStatus::Running => self.step()?,
                VMStatus::ExitedOk | VMStatus::ExitedErr(_) |
                VMStatus::ExitedNotSupported(_) => return Ok(()),
            }
        }
    }

    fn accounts(&self) -> map::Values<Address, AccountChange> {
        self.machines[0].state().account_state.accounts()
    }

    fn used_addresses(&self) -> Set<Address> {
        self.machines[0].state().account_state.used_addresses()
    }

    fn out(&self) -> &[u8] {
        self.machines[0].state().out.as_slice()
    }

    fn available_gas(&self) -> Gas {
        self.machines[0].state().available_gas()
    }

    fn refunded_gas(&self) -> Gas {
        self.machines[0].state().refunded_gas
    }

    fn logs(&self) -> &[Log] {
        self.machines[0].state().logs.as_slice()
    }

    fn removed(&self) -> &[Address] {
        self.machines[0].state().removed.as_slice()
    }

    fn used_gas(&self) -> Gas {
        let total_used = self.machines[0].state().total_used_gas();
        let refund_cap = total_used / Gas::from(2u64);
        let refunded = min(refund_cap, self.machines[0].state().refunded_gas);
        total_used - refunded
    }
}
<commit_msg>Crate-level docs<commit_after>//! SputnikVM implementation, traits and structs.
//!
//! SputnikVM work on two different levels. It can directly handles a
//! transaction, or a normal Etheruem execution context. To interact
//! with the virtual machine, you usually only need to work with the
//! [VM](trait.VM.html) trait.
//!
//! ### Lifecycle
//!
//! A VM can be started given a `Transaction` (or `Context`) and a
//! `BlockHeader`. The user can then `fire` or `step` to run it.
//! `fire` runs through all possible steps until it cannot continue,
//! while `step` only runs one step. Those functions would only fail
//! if it needs some information (accounts in the current block, or
//! block hashes of previous blocks) provided by `RequireError`. If
//! this happens, one can use the function `commit_account` and
//! `commit_blockhash` to commit those information to the VM, and
//! `fire` or `step` again until it succeeds. The current VM status
//! can always be obtained using the `status` function.
//!
//! ### Patch
//!
//! Every VM is associated with a `Patch`. This patch tells the VM
//! which Ethereum network and which hard fork it is on. You will need
//! to specify the patch as the type parameter. To interact with
//! multiple Patches at the same time, it is recommended that you use
//! trait objects.
//!
//! ```
//! extern crate bigint;
//! extern crate sputnikvm;
//!
//! use sputnikvm::{EmbeddedByzantiumPatch, VMTestPatch,
//!                 HeaderParams, ValidTransaction, TransactionAction,
//!                 VM, SeqTransactionVM};
//! use bigint::{Gas, U256, Address};
//! use std::rc::Rc;
//!
//! fn main() {
//!   let block_number = 1000;
//!   let transaction = ValidTransaction {
//!     caller: Some(Address::default()),
//!     gas_price: Gas::zero(),
//!     gas_limit: Gas::max_value(),
//!     action: TransactionAction::Create,
//!     value: U256::zero(),
//!     input: Rc::new(Vec::new()),
//!     nonce: U256::zero()
//!   };
//!   let header = HeaderParams {
//!     beneficiary: Address::default(),
//!     timestamp: 0,
//!     number: U256::zero(),
//!     difficulty: U256::zero(),
//!     gas_limit: Gas::zero()
//!   };
//!   let vm = if block_number < 500 {
//!     SeqTransactionVM::<VMTestPatch>::new(
//!       transaction, header);
//!   } else {
//!     SeqTransactionVM::<EmbeddedByzantiumPatch>::new(
//!       transaction, header);
//!   };
//! }
//! ```
//!
//! ### Transaction Execution
//!
//! To start a VM on the Transaction level, use the `TransactionVM`
//! struct. Usually, you use the sequencial memory module, which we
//! have a definition called `SeqTransactionVM`. Call to
//! `TransactionVM::new` would require the transaction to be valid
//! (according to the rules for an Ethereum transaction). For an
//! invalid transaction, it is possible for the VM to panic. If you
//! want to handle untrusted transactions, you should use
//! `SeqTransactionVM::new_untrusted` which will return an error if
//! the transaction is invalid.
//!
//! ### Context Execution
//!
//! To start a VM on the Context leve, use the `ContextVM`
//! struct. Usually, you use the sequencial memory module, which we
//! have a definition called `SeqContextVM`. Context execution, as the
//! same with other EVM implementations, will not handle
//! transaction-level gas reductions.

#![deny(unused_import_braces, unused_imports,
        unused_comparisons, unused_must_use,
        unused_variables, non_shorthand_field_patterns,
        unreachable_code, missing_docs)]

#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]

#[cfg(not(feature = "std"))]
extern crate alloc;

extern crate rlp;
extern crate bigint;
extern crate block_core;
extern crate sha3;
extern crate ripemd160;
extern crate sha2;
extern crate digest;

#[cfg(feature = "c-secp256k1")]
extern crate secp256k1;

#[cfg(feature = "rust-secp256k1")]
extern crate secp256k1;

#[cfg(feature = "std")]
extern crate block;

#[cfg(test)]
extern crate hexutil;

mod util;
mod memory;
mod stack;
mod pc;
mod params;
mod eval;
mod commit;
mod patch;
mod transaction;
pub mod errors;

pub use self::memory::{Memory, SeqMemory};
pub use self::stack::Stack;
pub use self::pc::{PC, PCMut, Instruction, Valids};
pub use self::params::*;
pub use self::patch::*;
pub use self::eval::{State, Machine, Runtime, MachineStatus};
pub use self::commit::{AccountCommitment, AccountChange, AccountState, BlockhashState, Storage};
pub use self::transaction::{ValidTransaction, TransactionVM, UntrustedTransaction};
pub use self::errors::{OnChainError, NotSupportedError, RequireError, CommitError, PreExecutionError};
pub use self::util::opcode::Opcode;
pub use block_core::TransactionAction;

#[cfg(not(feature = "std"))]
use alloc::Vec;

#[cfg(feature = "std")] use std::collections::{HashSet as Set, hash_map as map};
#[cfg(not(feature = "std"))] use alloc::{BTreeSet as Set, btree_map as map};
#[cfg(feature = "std")] use std::cmp::min;
#[cfg(not(feature = "std"))] use core::cmp::min;
use bigint::{U256, H256, Gas, Address};

#[derive(Debug, Clone)]
/// VM Status
pub enum VMStatus {
    /// A running VM.
    Running,
    /// VM is stopped without errors.
    ExitedOk,
    /// VM is stopped due to an error. The state of the VM is before
    /// the last failing instruction.
    ExitedErr(OnChainError),
    /// VM is stopped because it does not support certain
    /// operations. The client is expected to either drop the
    /// transaction or panic. This rarely happens unless the executor
    /// agrees upon on a really large number of gas limit, so it
    /// usually can be safely ignored.
    ExitedNotSupported(NotSupportedError),
}

/// Represents an EVM. This is usually the main interface for clients
/// to interact with.
pub trait VM {
    /// Commit an account information to this VM. This should only
    /// be used when receiving `RequireError`.
    fn commit_account(&mut self, commitment: AccountCommitment) -> Result<(), CommitError>;
    /// Commit a block hash to this VM. This should only be used when
    /// receiving `RequireError`.
    fn commit_blockhash(&mut self, number: U256, hash: H256) -> Result<(), CommitError>;
    /// Returns the current status of the VM.
    fn status(&self) -> VMStatus;
    /// Read the next instruction to be executed.
    fn peek(&self) -> Option<Instruction>;
    /// Read the next opcode to be executed.
    fn peek_opcode(&self) -> Option<Opcode>;
    /// Run one instruction and return. If it succeeds, VM status can
    /// still be `Running`. If the call stack has more than one items,
    /// this will only executes the last items' one single
    /// instruction.
    fn step(&mut self) -> Result<(), RequireError>;
    /// Run instructions until it reaches a `RequireError` or
    /// exits. If this function succeeds, the VM status can only be
    /// either `ExitedOk` or `ExitedErr`.
    fn fire(&mut self) -> Result<(), RequireError> {
        loop {
            match self.status() {
                VMStatus::Running => self.step()?,
                VMStatus::ExitedOk | VMStatus::ExitedErr(_) |
                VMStatus::ExitedNotSupported(_) => return Ok(()),
            }
        }
    }
    /// Returns the changed or committed accounts information up to
    /// current execution status.
    fn accounts(&self) -> map::Values<Address, AccountChange>;
    /// Returns all fetched or modified addresses.
    fn used_addresses(&self) -> Set<Address>;
    /// Returns the out value, if any.
    fn out(&self) -> &[u8];
    /// Returns the available gas of this VM.
    fn available_gas(&self) -> Gas;
    /// Returns the refunded gas of this VM.
    fn refunded_gas(&self) -> Gas;
    /// Returns logs to be appended to the current block if the user
    /// decided to accept the running status of this VM.
    fn logs(&self) -> &[Log];
    /// Returns all removed account addresses as for current VM execution.
    fn removed(&self) -> &[Address];
    /// Returns the real used gas by the transaction or the VM
    /// context. Only available when the status of the VM is
    /// exited. Otherwise returns zero.
    fn used_gas(&self) -> Gas;
}

/// A sequencial VM. It uses sequencial memory representation and hash
/// map storage for accounts.
pub type SeqContextVM<P> = ContextVM<SeqMemory<P>, P>;
/// A sequencial transaction VM. This is same as `SeqContextVM` except
/// it runs at transaction level.
pub type SeqTransactionVM<P> = TransactionVM<SeqMemory<P>, P>;

/// A VM that executes using a context and block information.
pub struct ContextVM<M, P: Patch> {
    runtime: Runtime,
    machines: Vec<Machine<M, P>>,
    fresh_account_state: AccountState<P::Account>,
}

impl<M: Memory + Default, P: Patch> ContextVM<M, P> {
    /// Create a new VM using the given context, block header and patch.
    pub fn new(context: Context, block: HeaderParams) -> Self {
        let mut machines = Vec::new();
        machines.push(Machine::new(context, 1));
        ContextVM {
            machines,
            runtime: Runtime::new(block),
            fresh_account_state: AccountState::default(),
        }
    }

    /// Create a new VM with the given account state and blockhash state.
    pub fn with_states(context: Context, block: HeaderParams,
                       account_state: AccountState<P::Account>, blockhash_state: BlockhashState) -> Self {
        let mut machines = Vec::new();
        machines.push(Machine::with_states(context, 1, account_state.clone()));
        ContextVM {
            machines,
            runtime: Runtime::with_states(block, blockhash_state),
            fresh_account_state: account_state,
        }
    }

    /// Create a new VM with customized initialization code.
    pub fn with_init<F: FnOnce(&mut ContextVM<M, P>)>(
        context: Context, block: HeaderParams,
        account_state: AccountState<P::Account>, blockhash_state: BlockhashState,
        f: F) -> Self {
        let mut vm = Self::with_states(context, block, account_state, blockhash_state);
        f(&mut vm);
        vm.fresh_account_state = vm.machines[0].state().account_state.clone();
        vm
    }

    /// Create a new VM with the result of the previous VM. This is
    /// usually used by transaction for chainning them.
    pub fn with_previous(context: Context, block: HeaderParams, vm: &ContextVM<M, P>) -> Self {
        Self::with_states(context, block,
                          vm.machines[0].state().account_state.clone(),
                          vm.runtime.blockhash_state.clone())
    }

    /// Returns the current state of the VM.
    pub fn current_state(&self) -> &State<M, P> {
        self.current_machine().state()
    }

    /// Returns the current runtime machine.
    pub fn current_machine(&self) -> &Machine<M, P> {
        self.machines.last().unwrap()
    }

    /// Add a new context history hook.
    pub fn add_context_history_hook<F: 'static + Fn(&Context)>(&mut self, f: F) {
        self.runtime.context_history_hooks.push(Box::new(f));
    }
}

impl<M: Memory + Default, P: Patch> VM for ContextVM<M, P> {
    fn commit_account(&mut self, commitment: AccountCommitment) -> Result<(), CommitError> {
        for machine in &mut self.machines {
            machine.commit_account(commitment.clone())?;
        }
        Ok(())
    }

    fn commit_blockhash(&mut self, number: U256, hash: H256) -> Result<(), CommitError> {
        self.runtime.blockhash_state.commit(number, hash)
    }

    fn status(&self) -> VMStatus {
        match self.machines.last().unwrap().status().clone() {
            MachineStatus::ExitedNotSupported(err) => return VMStatus::ExitedNotSupported(err),
            _ => (),
        }

        match self.machines[0].status() {
            MachineStatus::Running | MachineStatus::InvokeCreate(_) | MachineStatus::InvokeCall(_, _) => VMStatus::Running,
            MachineStatus::ExitedOk => VMStatus::ExitedOk,
            MachineStatus::ExitedErr(err) => VMStatus::ExitedErr(err.into()),
            MachineStatus::ExitedNotSupported(err) => VMStatus::ExitedNotSupported(err),
        }
    }

    fn peek(&self) -> Option<Instruction> {
        match self.machines.last().unwrap().status().clone() {
            MachineStatus::Running => {
                self.machines.last().unwrap().peek()
            },
            _ => None,
        }
    }

    fn peek_opcode(&self) -> Option<Opcode> {
        match self.machines.last().unwrap().status().clone() {
            MachineStatus::Running => {
                self.machines.last().unwrap().peek_opcode()
            },
            _ => None,
        }
    }

    fn step(&mut self) -> Result<(), RequireError> {
        match self.machines.last().unwrap().status().clone() {
            MachineStatus::Running => {
                self.machines.last_mut().unwrap().step(&self.runtime)?;
                if self.machines.len() == 1 {
                    match self.machines.last().unwrap().status().clone() {
                        MachineStatus::ExitedOk | MachineStatus::ExitedErr(_) =>
                            self.machines.last_mut().unwrap().finalize_context(&self.fresh_account_state),
                        _ => (),
                    }
                }
                Ok(())
            },
            MachineStatus::ExitedOk | MachineStatus::ExitedErr(_) => {
                if self.machines.len() == 0 {
                    panic!()
                } else if self.machines.len() == 1 {
                    Ok(())
                } else {
                    let finished = self.machines.pop().unwrap();
                    self.machines.last_mut().unwrap().apply_sub(finished);
                    Ok(())
                }
            },
            MachineStatus::ExitedNotSupported(_) => {
                Ok(())
            },
            MachineStatus::InvokeCall(context, _) => {
                for hook in &self.runtime.context_history_hooks {
                    hook(&context)
                }

                let mut sub = self.machines.last().unwrap().derive(context);
                sub.invoke_call()?;
                self.machines.push(sub);
                Ok(())
            },
            MachineStatus::InvokeCreate(context) => {
               for hook in &self.runtime.context_history_hooks {
                    hook(&context)
                }

                let mut sub = self.machines.last().unwrap().derive(context);
                sub.invoke_create()?;
                self.machines.push(sub);
                Ok(())
            },
        }
    }

    fn fire(&mut self) -> Result<(), RequireError> {
        loop {
            match self.status() {
                VMStatus::Running => self.step()?,
                VMStatus::ExitedOk | VMStatus::ExitedErr(_) |
                VMStatus::ExitedNotSupported(_) => return Ok(()),
            }
        }
    }

    fn accounts(&self) -> map::Values<Address, AccountChange> {
        self.machines[0].state().account_state.accounts()
    }

    fn used_addresses(&self) -> Set<Address> {
        self.machines[0].state().account_state.used_addresses()
    }

    fn out(&self) -> &[u8] {
        self.machines[0].state().out.as_slice()
    }

    fn available_gas(&self) -> Gas {
        self.machines[0].state().available_gas()
    }

    fn refunded_gas(&self) -> Gas {
        self.machines[0].state().refunded_gas
    }

    fn logs(&self) -> &[Log] {
        self.machines[0].state().logs.as_slice()
    }

    fn removed(&self) -> &[Address] {
        self.machines[0].state().removed.as_slice()
    }

    fn used_gas(&self) -> Gas {
        let total_used = self.machines[0].state().total_used_gas();
        let refund_cap = total_used / Gas::from(2u64);
        let refunded = min(refund_cap, self.machines[0].state().refunded_gas);
        total_used - refunded
    }
}
<|endoftext|>