<commit_before>use field::{Field, Content};
use ui::UI;
use ui::EndMessage;
use piston_window::*;
use common::{ParamType, MoveDestination, GameEndState};
use chrono::{DateTime, UTC, Duration};

enum RenderState {
    // redraw picture on current buffer
    First,

    // redraw picture on next buffer
    Second,

    // needn't redraw picture
    None
}

impl RenderState {

    // Update render state and return flag necessity of redrawing pickture
    fn update_state(&mut self) -> bool {
        match *self {
            RenderState::First  => *self = RenderState::Second,
            RenderState::Second => *self = RenderState::None,
            RenderState::None   => return false
        }

        true
    }

    fn reset(&mut self) {
        *self = RenderState::First
    }
}

pub struct Game<'a> {
    field: Field,
    ui: UI<'a>,
    msg: EndMessage<'a>,
    glyphs: Glyphs,
    mouse_x: f64,
    mouse_y: f64,
    game_ended: bool,
    panel_width: u32,
    in_ui: bool,
    game_start : Option<DateTime<UTC>>,
    last_time : Option<DateTime<UTC>>,
    game_end : Option<DateTime<UTC>>,
    // state of rendering for drawing picture on both buffers
    render_state: RenderState
}

impl<'a> Game<'a> {
    pub fn new(glyphs: Glyphs, width: u32, height: u32, mines: u32) -> Game<'a> {
        Game {
            field: Field::new(width, height, mines),
            ui: UI::new(width, height, mines),
            msg: EndMessage::new(),
            glyphs: glyphs,
            mouse_x: 0.0,
            mouse_y: 0.0,
            game_ended: false,
            panel_width: 350,
            in_ui: false,
            game_start: None,
            game_end: None,
            last_time: None,
            render_state: RenderState::First
        }
    }

    pub fn render(&mut self, window: &PistonWindow) {
        if !self.render_state.update_state() {
            return;
        }

        window.draw_2d(|c, g| {
            clear([0.0, 0.0, 0.0, 1.0], g);
            let field_rect = self.get_field_rect(window);
            self.field.draw(c, g, field_rect, &mut self.glyphs);

            let ui_rect = self.get_ui_rect(window);

            let dur = match self.game_start {
                Some(game_start) => match self.game_end {
                    Some(game_end) => game_end - game_start,
                    None => UTC::now() - game_start,
                },
                None => Duration::seconds(0),
            };

            self.ui.draw(c, g, ui_rect, &mut self.glyphs, self.field.total_mines(), self.field.count_marked(), dur);

            let msg_rect = self.get_msg_rect(window);
            self.msg.draw(c, g, msg_rect, &mut self.glyphs);
        });
    }

    fn get_field_rect(&self, window: &PistonWindow) -> [u32; 4] {
        let mut w = window.size().width - self.panel_width;
        w = (w /self.field.get_width()) * self.field.get_width();
        let mut h = window.size().height;
        h = (h /self.field.get_height()) * self.field.get_height();
        [0, 0, w, h]
    }

    fn get_ui_rect(&self, window: &PistonWindow) -> [u32; 4] {
        let mut field_w = window.size().width - self.panel_width;
        field_w = (field_w /self.field.get_width()) * self.field.get_width();
        let w = window.size().width - field_w;
        let h = window.size().height;
        [field_w, 0, w, h]
    }

    fn get_msg_rect(&self, window: &PistonWindow) -> [u32; 4] {
        let w_w = window.size().width;
        let w_h = window.size().height;
        let (m_w, m_h) = EndMessage::size();

        [
            ( (w_w-m_w) / 2 ),
            ( (w_h-m_h) / 2 ),
            m_w,
            m_h
        ]
    }

    pub fn proc_key(&mut self, button: Button, window: &PistonWindow) {
        let mut need_redraw = true;
        if self.in_ui {
            match button {
                Button::Keyboard(key) => {
                    match  key {
                        Key::H => {
                            match self.ui.proc_key(ParamType::Height) {
                                Some(h) => {
                                    self.in_ui = false;
                                    self.msg.hide();
                                    self.field.reinit_field(h, ParamType::Height);
                                }
                                _ => need_redraw = false
                            }
                        },
                        Key::M => {
                            match self.ui.proc_key(ParamType::Mines) {
                                Some(m) => {
                                    self.in_ui = false;
                                    self.msg.hide();
                                    self.field.reinit_field(m, ParamType::Mines);
                                }
                                _ => need_redraw = false
                            }
                        },
                        Key::W => {
                            match self.ui.proc_key(ParamType::Width) {
                                Some(w) => {
                                    self.in_ui = false;
                                    self.msg.hide();
                                    self.field.reinit_field(w, ParamType::Width);
                                }
                                _ => need_redraw = false
                            }
                        },
                        Key::Up => self.ui.change_selected(MoveDestination::Up),
                        Key::Down => self.ui.change_selected(MoveDestination::Down),
                        Key::Left => self.ui.change_selected(MoveDestination::Left),
                        Key::Right => self.ui.change_selected(MoveDestination::Right),
                        _ => need_redraw = false
                    }
                }
                _ => need_redraw = false
            }
        } else {
            match button {
                Button::Keyboard(key) => {
                    match key {
                        Key::R => self.restart(),
                        Key::Up => self.field.move_selection(MoveDestination::Up),
                        Key::Down => self.field.move_selection(MoveDestination::Down),
                        Key::Left => self.field.move_selection(MoveDestination::Left),
                        Key::Right => self.field.move_selection(MoveDestination::Right),
                        Key::Space => {
                            let ind = self.field.get_selected_ind();
                            self.open_cell(ind);
                        },
                        Key::LCtrl | Key::RCtrl => {
                            let ind = self.field.get_selected_ind();
                            self.toggle_mark(ind);
                        }
                        Key::H => {
                            self.ui.proc_key(ParamType::Height);
                            self.in_ui = true;
                        },
                        Key::M =>{
                            self.ui.proc_key(ParamType::Mines);
                            self.in_ui = true;
                        },
                        Key::W => {
                            self.ui.proc_key(ParamType::Width);
                            self.in_ui = true;
                        },
                        _ => need_redraw = false
                    }
                },
                Button::Mouse(btn) => {
                    let field_rect = self.get_field_rect(window);
                    let cell_w = field_rect[2] / self.field.get_width();
                    let cell_h = field_rect[3] / self.field.get_height();
                    let mouse_x = self.mouse_x.floor() as u32;
                    let mouse_y = self.mouse_y.floor() as u32;
                    if (mouse_x < field_rect[0]) || (mouse_x > field_rect[0] + field_rect[2]) ||
                       (mouse_y < field_rect[1]) || (mouse_y > field_rect[1] + field_rect[3]) {
                        return;
                    }
                    let x = (mouse_x - field_rect[0]) / cell_w;
                    let y = (mouse_y - field_rect[1]) / cell_h;
                    let w = self.field.get_width();
                    match btn {
                        MouseButton::Left => {
                            self.open_cell(x + y*w);
                        },
                        MouseButton::Right => {

                            self.toggle_mark(x + y*w);
                        },
                        _ => need_redraw = false
                    }
                }
            }
        }

        if need_redraw {
            self.render_state.reset();
        }
    }

    fn toggle_mark(&mut self, i: u32) {
        if self.game_ended || self.field.revealed(i) {
            return;
        }
        self.field.toggle_mark(i);
    }

    fn open_cell(&mut self, i: u32) {
        if self.game_ended {
            return;
        }
        if self.game_start == None {
            self.game_start = Some(UTC::now());
        }

        if !self.field.revealed(i) {
            self.check_reveal(i);
        } else {
            self.reveal_neighborhood(i);
        }
    }

    fn reveal_neighborhood(&mut self, i: u32) {
        let cells_count_opt = {
            if let &Content::Number(cells_count) = self.field.get_content(i) {
                Some(cells_count)
            } else {
                None
            }
        };

        if let Some(cells_count) = cells_count_opt {
            if self.field.get_neighborhood_count(i) == cells_count {
                let on_left_edge = i % self.field.get_width() == 0;
                let on_right_edge = (i+1) % self.field.get_width() == 0;

                for rdelta in -1..2i32 {
                    for cdelta in -1..2i32 {
                        if on_left_edge && (cdelta == -1) {
                            continue;
                        }
                        if on_right_edge && (cdelta == 1) {
                            continue;
                        }
                        let tgt = (i as i32) + rdelta*(self.field.get_width() as i32) + cdelta;
                        if (tgt < 0) || (tgt >= self.field.get_size() as i32) {
                            continue;
                        }
                        self.check_reveal(tgt as u32);
                    }
                }
            }
        }
    }

    pub fn check_reveal(&mut self, i : u32) {
        if self.field.marked(i) {
            return;
        }
        match *self.field.reveal(i) {
            Content::Mine(_) => {
                self.field.reveal_all();
                self.game_ended = true;
                self.field.set_killer(i);
                self.game_end = Some(UTC::now());
                self.msg.show( GameEndState::Lose );
                println!("Game over :(");
            },
            Content::None => {
                self.field.chain_reveal(i);
                if self.field.is_victory() {
                    self.msg.show( GameEndState::Win );
                    println!("You win :)");
                    self.game_ended = true;
                    self.game_end = Some(UTC::now());
                }
            }
            Content::Number(_i) => {
                if self.field.is_victory() {
                    self.msg.show( GameEndState::Win );
                    println!("You win :)");
                    self.game_ended = true;
                    self.game_end = Some(UTC::now());
                }
            }
        }
    }

    pub fn mouse_move(&mut self, mouse_rel: [f64; 2]) {
        self.mouse_x = mouse_rel[0];
        self.mouse_y = mouse_rel[1];
    }

    pub fn update_state(&mut self) {
        if let Some(_) = self.game_start {
            if let None = self.game_end {
                let now = UTC::now();
                match self.last_time {
                    Some(last_time) => {
                        let time_from_last_tick = now - last_time;
                        if time_from_last_tick >= Duration::seconds(1) {
                            self.last_time = Some(now);
                            self.render_state.reset();
                        }
                    },
                    None => self.last_time = Some(now),
                }
            }
        }
    }

    fn restart(&mut self) {
        self.game_ended = false;
        self.msg.hide();
        self.game_start = None;
        self.game_end = None;
        self.last_time = None;
        self.field.restart();
        self.render_state.reset();
    }
}
<commit_msg>Fix restart game after changing field size or mines count<commit_after>use field::{Field, Content};
use ui::UI;
use ui::EndMessage;
use piston_window::*;
use common::{ParamType, MoveDestination, GameEndState};
use chrono::{DateTime, UTC, Duration};

enum RenderState {
    // redraw picture on current buffer
    First,

    // redraw picture on next buffer
    Second,

    // needn't redraw picture
    None
}

impl RenderState {

    // Update render state and return flag necessity of redrawing pickture
    fn update_state(&mut self) -> bool {
        match *self {
            RenderState::First  => *self = RenderState::Second,
            RenderState::Second => *self = RenderState::None,
            RenderState::None   => return false
        }

        true
    }

    fn reset(&mut self) {
        *self = RenderState::First
    }
}

pub struct Game<'a> {
    field: Field,
    ui: UI<'a>,
    msg: EndMessage<'a>,
    glyphs: Glyphs,
    mouse_x: f64,
    mouse_y: f64,
    game_ended: bool,
    panel_width: u32,
    in_ui: bool,
    game_start : Option<DateTime<UTC>>,
    last_time : Option<DateTime<UTC>>,
    game_end : Option<DateTime<UTC>>,
    // state of rendering for drawing picture on both buffers
    render_state: RenderState
}

impl<'a> Game<'a> {
    pub fn new(glyphs: Glyphs, width: u32, height: u32, mines: u32) -> Game<'a> {
        Game {
            field: Field::new(width, height, mines),
            ui: UI::new(width, height, mines),
            msg: EndMessage::new(),
            glyphs: glyphs,
            mouse_x: 0.0,
            mouse_y: 0.0,
            game_ended: false,
            panel_width: 350,
            in_ui: false,
            game_start: None,
            game_end: None,
            last_time: None,
            render_state: RenderState::First
        }
    }

    pub fn render(&mut self, window: &PistonWindow) {
        if !self.render_state.update_state() {
            return;
        }

        window.draw_2d(|c, g| {
            clear([0.0, 0.0, 0.0, 1.0], g);
            let field_rect = self.get_field_rect(window);
            self.field.draw(c, g, field_rect, &mut self.glyphs);

            let ui_rect = self.get_ui_rect(window);

            let dur = match self.game_start {
                Some(game_start) => match self.game_end {
                    Some(game_end) => game_end - game_start,
                    None => UTC::now() - game_start,
                },
                None => Duration::seconds(0),
            };

            self.ui.draw(c, g, ui_rect, &mut self.glyphs, self.field.total_mines(), self.field.count_marked(), dur);

            let msg_rect = self.get_msg_rect(window);
            self.msg.draw(c, g, msg_rect, &mut self.glyphs);
        });
    }

    fn get_field_rect(&self, window: &PistonWindow) -> [u32; 4] {
        let mut w = window.size().width - self.panel_width;
        w = (w /self.field.get_width()) * self.field.get_width();
        let mut h = window.size().height;
        h = (h /self.field.get_height()) * self.field.get_height();
        [0, 0, w, h]
    }

    fn get_ui_rect(&self, window: &PistonWindow) -> [u32; 4] {
        let mut field_w = window.size().width - self.panel_width;
        field_w = (field_w /self.field.get_width()) * self.field.get_width();
        let w = window.size().width - field_w;
        let h = window.size().height;
        [field_w, 0, w, h]
    }

    fn get_msg_rect(&self, window: &PistonWindow) -> [u32; 4] {
        let w_w = window.size().width;
        let w_h = window.size().height;
        let (m_w, m_h) = EndMessage::size();

        [
            ( (w_w-m_w) / 2 ),
            ( (w_h-m_h) / 2 ),
            m_w,
            m_h
        ]
    }

    pub fn proc_key(&mut self, button: Button, window: &PistonWindow) {
        let mut need_redraw = true;
        if self.in_ui {
            match button {
                Button::Keyboard(key) => {
                    match  key {
                        Key::H => {
                            match self.ui.proc_key(ParamType::Height) {
                                Some(h) => {
                                    self.in_ui = false;
                                    self.field.reinit_field(h, ParamType::Height);
                                    self.restart();
                                }
                                _ => need_redraw = false
                            }
                        },
                        Key::M => {
                            match self.ui.proc_key(ParamType::Mines) {
                                Some(m) => {
                                    self.in_ui = false;
                                    self.field.reinit_field(m, ParamType::Mines);
                                    self.restart();
                                }
                                _ => need_redraw = false
                            }
                        },
                        Key::W => {
                            match self.ui.proc_key(ParamType::Width) {
                                Some(w) => {
                                    self.in_ui = false;
                                    self.field.reinit_field(w, ParamType::Width);
                                    self.restart();
                                }
                                _ => need_redraw = false
                            }
                        },
                        Key::Up => self.ui.change_selected(MoveDestination::Up),
                        Key::Down => self.ui.change_selected(MoveDestination::Down),
                        Key::Left => self.ui.change_selected(MoveDestination::Left),
                        Key::Right => self.ui.change_selected(MoveDestination::Right),
                        _ => need_redraw = false
                    }
                }
                _ => need_redraw = false
            }
        } else {
            match button {
                Button::Keyboard(key) => {
                    match key {
                        Key::R => self.restart(),
                        Key::Up => self.field.move_selection(MoveDestination::Up),
                        Key::Down => self.field.move_selection(MoveDestination::Down),
                        Key::Left => self.field.move_selection(MoveDestination::Left),
                        Key::Right => self.field.move_selection(MoveDestination::Right),
                        Key::Space => {
                            let ind = self.field.get_selected_ind();
                            self.open_cell(ind);
                        },
                        Key::LCtrl | Key::RCtrl => {
                            let ind = self.field.get_selected_ind();
                            self.toggle_mark(ind);
                        }
                        Key::H => {
                            self.ui.proc_key(ParamType::Height);
                            self.in_ui = true;
                        },
                        Key::M =>{
                            self.ui.proc_key(ParamType::Mines);
                            self.in_ui = true;
                        },
                        Key::W => {
                            self.ui.proc_key(ParamType::Width);
                            self.in_ui = true;
                        },
                        _ => need_redraw = false
                    }
                },
                Button::Mouse(btn) => {
                    let field_rect = self.get_field_rect(window);
                    let cell_w = field_rect[2] / self.field.get_width();
                    let cell_h = field_rect[3] / self.field.get_height();
                    let mouse_x = self.mouse_x.floor() as u32;
                    let mouse_y = self.mouse_y.floor() as u32;
                    if (mouse_x < field_rect[0]) || (mouse_x > field_rect[0] + field_rect[2]) ||
                       (mouse_y < field_rect[1]) || (mouse_y > field_rect[1] + field_rect[3]) {
                        return;
                    }
                    let x = (mouse_x - field_rect[0]) / cell_w;
                    let y = (mouse_y - field_rect[1]) / cell_h;
                    let w = self.field.get_width();
                    match btn {
                        MouseButton::Left => {
                            self.open_cell(x + y*w);
                        },
                        MouseButton::Right => {

                            self.toggle_mark(x + y*w);
                        },
                        _ => need_redraw = false
                    }
                }
            }
        }

        if need_redraw {
            self.render_state.reset();
        }
    }

    fn toggle_mark(&mut self, i: u32) {
        if self.game_ended || self.field.revealed(i) {
            return;
        }
        self.field.toggle_mark(i);
    }

    fn open_cell(&mut self, i: u32) {
        if self.game_ended {
            return;
        }
        if self.game_start == None {
            self.game_start = Some(UTC::now());
        }

        if !self.field.revealed(i) {
            self.check_reveal(i);
        } else {
            self.reveal_neighborhood(i);
        }
    }

    fn reveal_neighborhood(&mut self, i: u32) {
        let cells_count_opt = {
            if let &Content::Number(cells_count) = self.field.get_content(i) {
                Some(cells_count)
            } else {
                None
            }
        };

        if let Some(cells_count) = cells_count_opt {
            if self.field.get_neighborhood_count(i) == cells_count {
                let on_left_edge = i % self.field.get_width() == 0;
                let on_right_edge = (i+1) % self.field.get_width() == 0;

                for rdelta in -1..2i32 {
                    for cdelta in -1..2i32 {
                        if on_left_edge && (cdelta == -1) {
                            continue;
                        }
                        if on_right_edge && (cdelta == 1) {
                            continue;
                        }
                        let tgt = (i as i32) + rdelta*(self.field.get_width() as i32) + cdelta;
                        if (tgt < 0) || (tgt >= self.field.get_size() as i32) {
                            continue;
                        }
                        self.check_reveal(tgt as u32);
                    }
                }
            }
        }
    }

    pub fn check_reveal(&mut self, i : u32) {
        if self.field.marked(i) {
            return;
        }
        match *self.field.reveal(i) {
            Content::Mine(_) => {
                self.field.reveal_all();
                self.game_ended = true;
                self.field.set_killer(i);
                self.game_end = Some(UTC::now());
                self.msg.show( GameEndState::Lose );
                println!("Game over :(");
            },
            Content::None => {
                self.field.chain_reveal(i);
                if self.field.is_victory() {
                    self.msg.show( GameEndState::Win );
                    println!("You win :)");
                    self.game_ended = true;
                    self.game_end = Some(UTC::now());
                }
            }
            Content::Number(_i) => {
                if self.field.is_victory() {
                    self.msg.show( GameEndState::Win );
                    println!("You win :)");
                    self.game_ended = true;
                    self.game_end = Some(UTC::now());
                }
            }
        }
    }

    pub fn mouse_move(&mut self, mouse_rel: [f64; 2]) {
        self.mouse_x = mouse_rel[0];
        self.mouse_y = mouse_rel[1];
    }

    pub fn update_state(&mut self) {
        if let Some(_) = self.game_start {
            if let None = self.game_end {
                let now = UTC::now();
                match self.last_time {
                    Some(last_time) => {
                        let time_from_last_tick = now - last_time;
                        if time_from_last_tick >= Duration::seconds(1) {
                            self.last_time = Some(now);
                            self.render_state.reset();
                        }
                    },
                    None => self.last_time = Some(now),
                }
            }
        }
    }

    fn restart(&mut self) {
        self.game_ended = false;
        self.msg.hide();
        self.game_start = None;
        self.game_end = None;
        self.last_time = None;
        self.field.restart();
        self.render_state.reset();
    }
}
<|endoftext|>


<commit_before>//! Game loop.

// External crates.
use gl;
use gl::types::*;
use time;
use graphics::*;

// Local crate.
use Gl = gl_back_end::Gl;
use GlData = gl_back_end::GlData;
use GameWindow = game_window::GameWindow;
use AssetStore = asset_store::AssetStore;
use keyboard;
use event;
use mouse;

/// Implemented by game applications.
pub trait Game {
    /// Render graphics.
    ///
    /// `context` is a Rust-Graphics context.
    /// `gl` is the Piston OpenGL back-end for Rust-Graphics.
    fn render(&self, _context: &Context, _gl: &mut Gl) {}

    /// Update the physical state of the game.
    ///
    /// `dt` is the delta time from last update in seconds.
    fn update(&mut self, _dt: f64, _asset_store: &mut AssetStore) {}

    /// Perform tasks for loading before showing anything.
    fn load(&mut self, _asset_store: &mut AssetStore) {}

    /// User pressed a key.
    ///
    /// This can be overridden to handle key pressed events.
    fn key_press(
        &mut self,
        _key: keyboard::Key,
        _asset_store: &mut AssetStore
    ) {}

    /// User released a key.
    ///
    /// This can be overridden to handle key released events.
    fn key_release(
        &mut self,
        _key: keyboard::Key,
        _asset_store: &mut AssetStore
    ) {}

    /// Pressed a mouse button.
    fn mouse_press(
        &mut self,
        _button: mouse::Button,
        _asset_store: &mut AssetStore
    ) {}

    /// Released a mouse button.
    fn mouse_release(
        &mut self,
        _button: mouse::Button,
        _asset_store: &mut AssetStore
    ) {}

    /// Moved mouse cursor.
    fn mouse_move(
        &mut self,
        _x: f64,
        _y: f64,
        _asset_store: &mut AssetStore
    ) {}

    /// Moved mouse relative, not bounded by cursor.
    fn mouse_relative_move(
        &mut self,
        _dx: f64,
        _dy: f64,
        _asset_store: &mut AssetStore
    ) {}

    /// Sets up viewport.
    ///
    /// A viewport is the region of the window where graphics is rendered.
    #[inline(always)]
    fn viewport<W: GameWindow>(&self, game_window: &W) {
        let (w, h) = game_window.get_size();
        gl::Viewport(0, 0, w as GLint, h as GLint);
    }

    /// Whether the window should be closed.
    ///
    /// When this is `true` the application shuts down.
    /// This can be overridden to emulate a user closing the window.
    /// One can also override this method to prevent window from closing.
    fn should_close<W: GameWindow>(&self, game_window: &W) -> bool {
        game_window.should_close()
    }

    /// Swaps the front buffer with the back buffer.
    ///
    /// When called, This shows the next frame.
    /// The graphics is rendered to the back buffer.
    /// The front buffer is displayed on the screen.
    fn swap_buffers<W: GameWindow>(&self, game_window: &W) {
        game_window.swap_buffers()
    }

    /// Handles events using current game window settings.
    ///
    /// This can be overriden to do custom event handling.
    fn handle_events<W: GameWindow>(
        &mut self,
        game_window: &mut W,
        asset_store: &mut AssetStore
    ) {
        loop {
            match game_window.poll_event() {
                event::KeyPressed(keycode) => {
                    self.key_press(keycode, asset_store)
                },
                event::KeyReleased(keycode) => {
                    self.key_release(keycode, asset_store)
                },
                event::MouseButtonPressed(mouse_button) => {
                    self.mouse_press(mouse_button, asset_store)
                },
                event::MouseButtonReleased(mouse_button) => {
                    self.mouse_release(mouse_button, asset_store)
                },
                event::MouseMoved(x, y, relative_move) => {
                    self.mouse_move(x, y, asset_store);
                    match relative_move {
                        Some((dx, dy)) =>
                            self.mouse_relative_move(dx, dy, asset_store),
                        None => {},
                    }
                },
                event::NoEvent => {
                    break
                },
            }
        }
    }

    /// Executes a game loop.
    ///
    /// The loop continues until `should_close` returns true.
    fn run<W: GameWindow>(
        &mut self,
        game_window: &mut W,
        asset_store: &mut AssetStore
    ) {
        use graphics::{Clear, AddColor};

        self.load(asset_store);
        let mut gl_data = GlData::new();
        let context = Context::new();
        let bg = game_window.get_settings().background_color;
        let bg = context.rgba(bg[0], bg[1], bg[2], bg[3]);
        let updates_per_second: u64 = 100;
        let dt: f64 = 1.0 / updates_per_second as f64;
        let update_time_in_ns: u64 = 1_000_000_000 / updates_per_second;
        let mut last_update = time::precise_time_ns();
        while !self.should_close(game_window) {
            self.viewport(game_window);
            let (w, h) = game_window.get_size();
            if w != 0 && h != 0 {
                let mut gl = Gl::new(&mut gl_data, asset_store);
                bg.clear(&mut gl);
                self.render(&context
                .trans_local(-1.0, 1.0)
                .scale_local(2.0 / w as f64, -2.0 / h as f64)
                .store_view()
                .reset(), &mut gl);
            }
            self.swap_buffers(game_window);
            // Perform updates by fixed time step until it catches up.
            loop {
                self.update(dt, asset_store);
                last_update += update_time_in_ns;
                let now = time::precise_time_ns();
                if now <= last_update { break; }
            }
            self.handle_events(game_window, asset_store);
        }
    }
}

<commit_msg>Made absolute coordinates the default<commit_after>//! Game loop.

// External crates.
use gl;
use gl::types::*;
use time;
use graphics::*;

// Local crate.
use Gl = gl_back_end::Gl;
use GlData = gl_back_end::GlData;
use GameWindow = game_window::GameWindow;
use AssetStore = asset_store::AssetStore;
use keyboard;
use event;
use mouse;

/// Implemented by game applications.
pub trait Game {
    /// Render graphics.
    ///
    /// `context` is a Rust-Graphics context.
    /// `gl` is the Piston OpenGL back-end for Rust-Graphics.
    fn render(&self, _context: &Context, _gl: &mut Gl) {}

    /// Update the physical state of the game.
    ///
    /// `dt` is the delta time from last update in seconds.
    fn update(&mut self, _dt: f64, _asset_store: &mut AssetStore) {}

    /// Perform tasks for loading before showing anything.
    fn load(&mut self, _asset_store: &mut AssetStore) {}

    /// User pressed a key.
    ///
    /// This can be overridden to handle key pressed events.
    fn key_press(
        &mut self,
        _key: keyboard::Key,
        _asset_store: &mut AssetStore
    ) {}

    /// User released a key.
    ///
    /// This can be overridden to handle key released events.
    fn key_release(
        &mut self,
        _key: keyboard::Key,
        _asset_store: &mut AssetStore
    ) {}

    /// Pressed a mouse button.
    fn mouse_press(
        &mut self,
        _button: mouse::Button,
        _asset_store: &mut AssetStore
    ) {}

    /// Released a mouse button.
    fn mouse_release(
        &mut self,
        _button: mouse::Button,
        _asset_store: &mut AssetStore
    ) {}

    /// Moved mouse cursor.
    fn mouse_move(
        &mut self,
        _x: f64,
        _y: f64,
        _asset_store: &mut AssetStore
    ) {}

    /// Moved mouse relative, not bounded by cursor.
    fn mouse_relative_move(
        &mut self,
        _dx: f64,
        _dy: f64,
        _asset_store: &mut AssetStore
    ) {}

    /// Sets up viewport.
    ///
    /// A viewport is the region of the window where graphics is rendered.
    #[inline(always)]
    fn viewport<W: GameWindow>(&self, game_window: &W) {
        let (w, h) = game_window.get_size();
        gl::Viewport(0, 0, w as GLint, h as GLint);
    }

    /// Whether the window should be closed.
    ///
    /// When this is `true` the application shuts down.
    /// This can be overridden to emulate a user closing the window.
    /// One can also override this method to prevent window from closing.
    fn should_close<W: GameWindow>(&self, game_window: &W) -> bool {
        game_window.should_close()
    }

    /// Swaps the front buffer with the back buffer.
    ///
    /// When called, This shows the next frame.
    /// The graphics is rendered to the back buffer.
    /// The front buffer is displayed on the screen.
    fn swap_buffers<W: GameWindow>(&self, game_window: &W) {
        game_window.swap_buffers()
    }

    /// Handles events using current game window settings.
    ///
    /// This can be overriden to do custom event handling.
    fn handle_events<W: GameWindow>(
        &mut self,
        game_window: &mut W,
        asset_store: &mut AssetStore
    ) {
        loop {
            match game_window.poll_event() {
                event::KeyPressed(keycode) => {
                    self.key_press(keycode, asset_store)
                },
                event::KeyReleased(keycode) => {
                    self.key_release(keycode, asset_store)
                },
                event::MouseButtonPressed(mouse_button) => {
                    self.mouse_press(mouse_button, asset_store)
                },
                event::MouseButtonReleased(mouse_button) => {
                    self.mouse_release(mouse_button, asset_store)
                },
                event::MouseMoved(x, y, relative_move) => {
                    self.mouse_move(x, y, asset_store);
                    match relative_move {
                        Some((dx, dy)) =>
                            self.mouse_relative_move(dx, dy, asset_store),
                        None => {},
                    }
                },
                event::NoEvent => {
                    break
                },
            }
        }
    }

    /// Executes a game loop.
    ///
    /// The loop continues until `should_close` returns true.
    fn run<W: GameWindow>(
        &mut self,
        game_window: &mut W,
        asset_store: &mut AssetStore
    ) {
        use graphics::{Clear, AddColor};

        self.load(asset_store);
        let mut gl_data = GlData::new();
        let context = Context::new();
        let bg = game_window.get_settings().background_color;
        let bg = context.rgba(bg[0], bg[1], bg[2], bg[3]);
        let updates_per_second: u64 = 100;
        let dt: f64 = 1.0 / updates_per_second as f64;
        let update_time_in_ns: u64 = 1_000_000_000 / updates_per_second;
        let mut last_update = time::precise_time_ns();
        while !self.should_close(game_window) {
            self.viewport(game_window);
            let (w, h) = game_window.get_size();
            if w != 0 && h != 0 {
                let mut gl = Gl::new(&mut gl_data, asset_store);
                bg.clear(&mut gl);
                self.render(&context
                .trans(-1.0, 1.0)
                .scale(2.0 / w as f64, -2.0 / h as f64)
                .store_view(), &mut gl);
            }
            self.swap_buffers(game_window);
            // Perform updates by fixed time step until it catches up.
            loop {
                self.update(dt, asset_store);
                last_update += update_time_in_ns;
                let now = time::precise_time_ns();
                if now <= last_update { break; }
            }
            self.handle_events(game_window, asset_store);
        }
    }
}

<|endoftext|>


<commit_before>//! Models versions of OpenGL Shader Language (GLSL)

use opengl::OpenGL;
use PickShader;

/// For OpenGL version 3.3 and above,
/// the GLSL version is the same as the OpenGL version.
///
/// Source: http://www.opengl.org/wiki/Core_Language_%28GLSL%29
#[allow(missing_docs)]
#[allow(non_camel_case_types)]
#[derive(Copy, PartialOrd, Ord, PartialEq, Eq)]
pub enum GLSL {
    _1_10,
    _1_20,
    _1_30,
    _1_40,
    _1_50,
    _3_30,
    _4_00,
    _4_10,
    _4_20,
    _4_30,
    _4_40,
    _4_50
}

impl GLSL {
    /// Gets OpenGL version associated with GLSL.
    #[allow(non_snake_case)]
    pub fn to_OpenGL(&self) -> OpenGL {
        match *self {
            GLSL::_1_10 => OpenGL::_2_0,
            GLSL::_1_20 => OpenGL::_2_1,
            GLSL::_1_30 => OpenGL::_3_0,
            GLSL::_1_40 => OpenGL::_3_1,
            GLSL::_1_50 => OpenGL::_3_2,
            GLSL::_3_30 => OpenGL::_3_3,
            GLSL::_4_00 => OpenGL::_4_0,
            GLSL::_4_10 => OpenGL::_4_1,
            GLSL::_4_20 => OpenGL::_4_2,
            GLSL::_4_30 => OpenGL::_4_3,
            GLSL::_4_40 => OpenGL::_4_4,
            GLSL::_4_50 => OpenGL::_4_5
        }
    }
}

impl PickShader for GLSL {
    fn pick_shader<'a, I>(&self, shaders: I) -> Option<&'a str>
        where
            I: Iterator<Item = (&'a Self, &'a &'a str)>
    {
        let low = if *self < GLSL::_1_50 {
            GLSL::_1_10
        } else {
            GLSL::_1_50
        };
        shaders
            .skip_while(|&(v, _)| *v < low)
            .take_while(|&(v, _)| *v <= *self)
            .last().map(|(_, &s)| s)
    }
}
<commit_msg>Added comment<commit_after>//! Models versions of OpenGL Shader Language (GLSL)

use opengl::OpenGL;
use PickShader;

/// For OpenGL version 3.3 and above,
/// the GLSL version is the same as the OpenGL version.
///
/// Source: http://www.opengl.org/wiki/Core_Language_%28GLSL%29
#[allow(missing_docs)]
#[allow(non_camel_case_types)]
#[derive(Copy, PartialOrd, Ord, PartialEq, Eq)]
pub enum GLSL {
    _1_10,
    _1_20,
    _1_30,
    _1_40,
    _1_50,
    _3_30,
    _4_00,
    _4_10,
    _4_20,
    _4_30,
    _4_40,
    _4_50
}

impl GLSL {
    /// Gets OpenGL version associated with GLSL.
    #[allow(non_snake_case)]
    pub fn to_OpenGL(&self) -> OpenGL {
        match *self {
            GLSL::_1_10 => OpenGL::_2_0,
            GLSL::_1_20 => OpenGL::_2_1,
            GLSL::_1_30 => OpenGL::_3_0,
            GLSL::_1_40 => OpenGL::_3_1,
            GLSL::_1_50 => OpenGL::_3_2,
            GLSL::_3_30 => OpenGL::_3_3,
            GLSL::_4_00 => OpenGL::_4_0,
            GLSL::_4_10 => OpenGL::_4_1,
            GLSL::_4_20 => OpenGL::_4_2,
            GLSL::_4_30 => OpenGL::_4_3,
            GLSL::_4_40 => OpenGL::_4_4,
            GLSL::_4_50 => OpenGL::_4_5
        }
    }
}

impl PickShader for GLSL {
    fn pick_shader<'a, I>(&self, shaders: I) -> Option<&'a str>
        where
            I: Iterator<Item = (&'a Self, &'a &'a str)>
    {
        // OpenGL since 3.20 in core profile doesn't support GLSL lower than 1.50.
        // Since there are no compatible shader in this case, it will return `None`.
        let low = if *self < GLSL::_1_50 {
            GLSL::_1_10
        } else {
            GLSL::_1_50
        };
        shaders
            .skip_while(|&(v, _)| *v < low)
            .take_while(|&(v, _)| *v <= *self)
            .last().map(|(_, &s)| s)
    }
}
<|endoftext|>


<commit_before>use sha;

const B: usize = 128;
const IPAD: u8 = 0x36;
const OPAD: u8 = 0x5c;

pub struct HmacSha384;

impl HmacSha384 {
    pub fn digest(key: &[u8], message: &[u8]) -> [u8; sha::SHA384_DIGEST_SIZE] {
        let mut padded_key = [0; B];
        if key.len() > B {
            padded_key[..sha::SHA384_DIGEST_SIZE].copy_from_slice(&Self::hash(key));
        } else {
            padded_key[..key.len()].copy_from_slice(key);
        }

        let mut input = Self::xor(&padded_key, IPAD);
        input.extend_from_slice(message);
        let hash = Self::hash(&input);

        input = Self::xor(&padded_key, OPAD);
        input.extend_from_slice(&hash);
        Self::hash(&input)
    }

    fn hash(input: &[u8]) -> [u8; sha::SHA384_DIGEST_SIZE] {
        sha::sha384(input)
    }

    fn xor(key: &[u8], pad: u8) -> Vec<u8> {
        key.iter().map(|x| x ^ pad).collect()
    }
}

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

    fn check(expected: &str, key: &[u8], data: &[u8]) {
        let actual = HmacSha384::digest(key, data);
        assert_eq!(h2b(expected), actual.to_vec());
    }

    #[test]
    fn test_digest() {
        let key = h2b("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
        let data = b"Hi There";
        let mut expected = "afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59c\
                            faea9ea9076ede7f4af152e8b2fa9cb6";
        check(expected, &key, data);

        let key = b"Jefe";
        let data = b"what do ya want for nothing?";
        expected = "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e\
                    8e2240ca5e69e2c78b3239ecfab21649";
        check(expected, key, data);

        let key = [0xaa; 20];
        let mut data = [0xdd; 50];
        expected = "88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b\
                    2a5ab39dc13814b94e3ab6e101a34f27";
        check(expected, &key, &data);

        let key: Vec<_> = (0x01..0x1a).collect();
        data = [0xcd; 50];
        expected = "3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e\
                    6801dd23c4a7d679ccf8a386c674cffb";
        check(expected, &key, &data);

        let key = [0xaa; 131];
        let data = b"Test Using Larger Than Block-Size Key - Hash Key First";
        expected = "4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c6\
                    0c2ef6ab4030fe8296248df163f44952";
        check(expected, &key, data);

        let data =
            b"This is a test using a larger than block-size key and a larger than block-\
              size data. The key needs to be hashed before being used by the HMAC algorithm.";
        expected = "6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5\
                    a678cc31e799176d3860e6110c46523e";
        check(expected, &key, data);
    }
}
<commit_msg>hmac: use incremental hash updates<commit_after>use sha::{HashFunction, Sha384, SHA384_DIGEST_SIZE};

const B: usize = 128;
const IPAD: u8 = 0x36;
const OPAD: u8 = 0x5c;

pub struct HmacSha384;

impl HmacSha384 {
    pub fn digest(key: &[u8], message: &[u8]) -> [u8; SHA384_DIGEST_SIZE] {
        let mut padded_key = [0; B];
        if key.len() > B {
            let mut hash_function = Self::hash_function();
            hash_function.update(key);
            hash_function.write_digest_into(&mut padded_key[..SHA384_DIGEST_SIZE]);
        } else {
            padded_key[..key.len()].copy_from_slice(key);
        }

        let mut input = Self::xor(&padded_key, IPAD);
        let mut hash_function = Self::hash_function();
        hash_function.update(&input);
        hash_function.update(message);
        let mut digest = [0; SHA384_DIGEST_SIZE];
        hash_function.write_digest_into(&mut digest);

        input = Self::xor(&padded_key, OPAD);
        hash_function = Self::hash_function();
        hash_function.update(&input);
        hash_function.update(&digest);
        hash_function.write_digest_into(&mut digest);
        digest
    }

    fn hash_function() -> Sha384 {
        Sha384::default()
    }

    fn xor(key: &[u8; B], pad: u8) -> [u8; B] {
        let mut xor = [0; B];
        for (x, y) in xor.iter_mut().zip(key.iter()) {
            *x = y ^ pad;
        }
        xor
    }
}

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

    fn check(expected: &str, key: &[u8], data: &[u8]) {
        let actual = HmacSha384::digest(key, data);
        assert_eq!(h2b(expected), actual.to_vec());
    }

    #[test]
    fn test_digest() {
        let key = h2b("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
        let data = b"Hi There";
        let mut expected = "afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59c\
                            faea9ea9076ede7f4af152e8b2fa9cb6";
        check(expected, &key, data);

        let key = b"Jefe";
        let data = b"what do ya want for nothing?";
        expected = "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e\
                    8e2240ca5e69e2c78b3239ecfab21649";
        check(expected, key, data);

        let key = [0xaa; 20];
        let mut data = [0xdd; 50];
        expected = "88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b\
                    2a5ab39dc13814b94e3ab6e101a34f27";
        check(expected, &key, &data);

        let key: Vec<_> = (0x01..0x1a).collect();
        data = [0xcd; 50];
        expected = "3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e\
                    6801dd23c4a7d679ccf8a386c674cffb";
        check(expected, &key, &data);

        let key = [0xaa; 131];
        let data = b"Test Using Larger Than Block-Size Key - Hash Key First";
        expected = "4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c6\
                    0c2ef6ab4030fe8296248df163f44952";
        check(expected, &key, data);

        let data =
            b"This is a test using a larger than block-size key and a larger than block-\
              size data. The key needs to be hashed before being used by the HMAC algorithm.";
        expected = "6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5\
                    a678cc31e799176d3860e6110c46523e";
        check(expected, &key, data);
    }
}
<|endoftext|>


<commit_before>use sha::{HashFunction, Sha384, SHA384_DIGEST_SIZE};

const B: usize = 128;
const IPAD: u8 = 0x36;
const OPAD: u8 = 0x5c;

pub struct HmacSha384;

impl HmacSha384 {
    pub fn digest(key: &[u8], message: &[u8]) -> [u8; SHA384_DIGEST_SIZE] {
        let mut padded_key = [0; B];
        if key.len() > B {
            let mut hash_function = Self::hash_function();
            hash_function.update(key);
            hash_function.write_digest_into(&mut padded_key[..SHA384_DIGEST_SIZE]);
        } else {
            padded_key[..key.len()].copy_from_slice(key);
        }

        let mut input = Self::xor(&padded_key, IPAD);
        let mut hash_function = Self::hash_function();
        hash_function.update(&input);
        hash_function.update(message);
        let mut digest = [0; SHA384_DIGEST_SIZE];
        hash_function.write_digest_into(&mut digest);

        input = Self::xor(&padded_key, OPAD);
        hash_function = Self::hash_function();
        hash_function.update(&input);
        hash_function.update(&digest);
        hash_function.write_digest_into(&mut digest);
        digest
    }

    fn hash_function() -> Sha384 {
        Sha384::default()
    }

    fn xor(key: &[u8; B], pad: u8) -> [u8; B] {
        let mut xor = [0; B];
        for (x, y) in xor.iter_mut().zip(key.iter()) {
            *x = y ^ pad;
        }
        xor
    }
}

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

    fn check(expected: &str, key: &[u8], data: &[u8]) {
        let actual = HmacSha384::digest(key, data);
        assert_eq!(h2b(expected), actual.to_vec());
    }

    #[test]
    fn test_digest() {
        let key = h2b("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
        let data = b"Hi There";
        let mut expected = "afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59c\
                            faea9ea9076ede7f4af152e8b2fa9cb6";
        check(expected, &key, data);

        let key = b"Jefe";
        let data = b"what do ya want for nothing?";
        expected = "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e\
                    8e2240ca5e69e2c78b3239ecfab21649";
        check(expected, key, data);

        let key = [0xaa; 20];
        let mut data = [0xdd; 50];
        expected = "88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b\
                    2a5ab39dc13814b94e3ab6e101a34f27";
        check(expected, &key, &data);

        let key: Vec<_> = (0x01..0x1a).collect();
        data = [0xcd; 50];
        expected = "3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e\
                    6801dd23c4a7d679ccf8a386c674cffb";
        check(expected, &key, &data);

        let key = [0xaa; 131];
        let data = b"Test Using Larger Than Block-Size Key - Hash Key First";
        expected = "4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c6\
                    0c2ef6ab4030fe8296248df163f44952";
        check(expected, &key, data);

        let data =
            b"This is a test using a larger than block-size key and a larger than block-\
              size data. The key needs to be hashed before being used by the HMAC algorithm.";
        expected = "6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5\
                    a678cc31e799176d3860e6110c46523e";
        check(expected, &key, data);
    }
}
<commit_msg>hmac: work toward incremental processing<commit_after>use sha::{HashFunction, Sha384, SHA384_DIGEST_SIZE};

const B: usize = 128;
const IPAD: u8 = 0x36;
const OPAD: u8 = 0x5c;

pub struct HmacSha384 {
    padded_key: [u8; B],
    hash_function: Sha384,
}

impl HmacSha384 {
    pub fn digest(key: &[u8], message: &[u8]) -> [u8; SHA384_DIGEST_SIZE] {
        let mut digest = [0; SHA384_DIGEST_SIZE];
        let mut hmac = Self::new(key);
        hmac.update(message);
        hmac.write_digest_into(&mut digest);
        digest
    }

    fn new(key: &[u8]) -> Self {
        let mut padded_key = [0; B];
        if key.len() > B {
            let mut hash_function = Self::hash_function();
            hash_function.update(key);
            hash_function.write_digest_into(&mut padded_key[..SHA384_DIGEST_SIZE]);
        } else {
            padded_key[..key.len()].copy_from_slice(key);
        }

        let input = Self::xor(&padded_key, IPAD);
        let mut hash_function = Self::hash_function();
        hash_function.update(&input);
        Self {
            padded_key: padded_key,
            hash_function: hash_function,
        }
    }

    fn update(&mut self, input: &[u8]) {
        self.hash_function.update(input);
    }

    fn write_digest_into(&mut self, output: &mut [u8]) {
        self.hash_function.write_digest_into(output);
        let input = Self::xor(&self.padded_key, OPAD);
        let mut hash_function = Self::hash_function();
        hash_function.update(&input);
        hash_function.update(output);
        hash_function.write_digest_into(output);
    }

    fn hash_function() -> Sha384 {
        Sha384::default()
    }

    fn xor(key: &[u8; B], pad: u8) -> [u8; B] {
        let mut xor = [0; B];
        for (x, y) in xor.iter_mut().zip(key.iter()) {
            *x = y ^ pad;
        }
        xor
    }
}

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

    fn check(expected: &str, key: &[u8], data: &[u8]) {
        let actual = HmacSha384::digest(key, data);
        assert_eq!(h2b(expected), actual.to_vec());
    }

    #[test]
    fn test_digest() {
        let key = h2b("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
        let data = b"Hi There";
        let mut expected = "afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59c\
                            faea9ea9076ede7f4af152e8b2fa9cb6";
        check(expected, &key, data);

        let key = b"Jefe";
        let data = b"what do ya want for nothing?";
        expected = "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e\
                    8e2240ca5e69e2c78b3239ecfab21649";
        check(expected, key, data);

        let key = [0xaa; 20];
        let mut data = [0xdd; 50];
        expected = "88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b\
                    2a5ab39dc13814b94e3ab6e101a34f27";
        check(expected, &key, &data);

        let key: Vec<_> = (0x01..0x1a).collect();
        data = [0xcd; 50];
        expected = "3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e\
                    6801dd23c4a7d679ccf8a386c674cffb";
        check(expected, &key, &data);

        let key = [0xaa; 131];
        let data = b"Test Using Larger Than Block-Size Key - Hash Key First";
        expected = "4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c6\
                    0c2ef6ab4030fe8296248df163f44952";
        check(expected, &key, data);

        let data =
            b"This is a test using a larger than block-size key and a larger than block-\
              size data. The key needs to be hashed before being used by the HMAC algorithm.";
        expected = "6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5\
                    a678cc31e799176d3860e6110c46523e";
        check(expected, &key, data);
    }
}
<|endoftext|>


<commit_before>use std;
use tuple_utils::Split;
use bitset;
use Index;
use {BitSet, BitSetAnd, BitSetLike, Storage, UnprotectedStorage};

/// BitAnd is a helper method to & bitsets togather resulting in a tree
pub trait BitAnd {
    type Value: BitSetLike;
    fn and(self) -> Self::Value;
}

/// This needs to be special cased
impl<A> BitAnd for (A,)
    where A: BitSetLike
{
    type Value = A;
    fn and(self) -> Self::Value {
        self.0
    }
}

macro_rules! bitset_and {
    // use variables to indicate the arity of the tuple
    ($($from:ident),*) => {
        impl<$($from),*> BitAnd for ($($from),*)
            where $($from: BitSetLike),*
        {
            type Value = BitSetAnd<
                <<Self as Split>::Left as BitAnd>::Value,
                <<Self as Split>::Right as BitAnd>::Value
            >;
            fn and(self) -> Self::Value {
              let (l, r) = self.split();
              BitSetAnd(l.and(), r.and())
            }
        }
    }
}

bitset_and!{A, B}
bitset_and!{A, B, C}
bitset_and!{A, B, C, D}
bitset_and!{A, B, C, D, E}
bitset_and!{A, B, C, D, E, F}
bitset_and!{A, B, C, D, E, F, G}
bitset_and!{A, B, C, D, E, F, G, H}
bitset_and!{A, B, C, D, E, F, G, H, I}
bitset_and!{A, B, C, D, E, F, G, H, I, J}
bitset_and!{A, B, C, D, E, F, G, H, I, J, K}
bitset_and!{A, B, C, D, E, F, G, H, I, J, K, L}
bitset_and!{A, B, C, D, E, F, G, H, I, J, K, L, M}
bitset_and!{A, B, C, D, E, F, G, H, I, J, K, L, M, N}
bitset_and!{A, B, C, D, E, F, G, H, I, J, K, L, M, N, O}
bitset_and!{A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P}

/// The only purpose of the `Open` trait is to provide a way
/// to access the `open` or `open_mut` trait in a generic way
/// This way the fact that the type is immutable or mutable
/// is not lost when it is used later.
pub trait Open {
    type Value;
    type Mask: BitSetLike;
    fn open(self) -> (Self::Mask, Self::Value);
}

impl<'a, T> Open for &'a T
    where T: Storage
{
    type Value = GetRef<'a, <T as Storage>::UnprotectedStorage>;
    type Mask = &'a BitSet;
    fn open(self) -> (Self::Mask, Self::Value) {
        let (l, r) = self.open();
        (l, GetRef(r))
    }
}

impl<'a, T> Open for &'a mut T
    where T: Storage
{
    type Value = GetMut<'a, <T as Storage>::UnprotectedStorage>;
    type Mask = &'a BitSet;
    fn open(self) -> (Self::Mask, Self::Value) {
        let (l, r) = self.open_mut();
        (l, GetMut(r))
    }
}

/// Get like `Open` provides the same feature of providing
/// mutable vs immutable preserving around the UnprotectedStorage
/// trait
pub trait Get {
    type Value;
    unsafe fn get(&self, idx: Index) -> Self::Value;
}

pub struct GetRef<'a, T: 'a>(&'a T);
impl<'a, T> Get for GetRef<'a, T>
    where T: UnprotectedStorage
{
    type Value = &'a <T as UnprotectedStorage>::Component;
    unsafe fn get(&self, idx: Index) -> Self::Value {
        self.0.get(idx)
    }
}

pub struct GetMut<'a, T: 'a>(&'a mut T);
impl<'a, T> Get for GetMut<'a, T>
    where T: UnprotectedStorage
{
    type Value = &'a mut <T as UnprotectedStorage>::Component;
    #[allow(mutable_transmutes)]
    unsafe fn get(&self, idx: Index) -> Self::Value {
        let x: &mut Self = std::mem::transmute(self);
        x.0.get_mut(idx)
    }
}

pub struct Joined<K, V> {
    keys: bitset::Iter<K>,
    values: V,
}

impl<K, V> Joined<K, V>
    where K: BitSetLike
{
    fn new(k: K, v: V) -> Joined<K, V> {
        Joined {
            keys: k.iter(),
            values: v,
        }
    }
}

impl<K, V> std::iter::Iterator for Joined<K, V>
    where K: BitSetLike,
          V: Get
{
    type Item = <V as Get>::Value;
    fn next(&mut self) -> Option<Self::Item> {
        if let Some(idx) = self.keys.next() {
            unsafe { Some(self.values.get(idx)) }
        } else {
            None
        }
    }
}

/// Join one or more `Storage` components together
/// this will return an iterator that will return
/// the components of an entity
pub trait Join {
    /// The Mask selects which elements are found
    /// in the  Values collection
    type Mask;
    /// The Values is a tuple of `UnprotectedStorage`
    type Values;
    /// Join the `Storages` togather
    fn join(self) -> Joined<Self::Mask, Self::Values>;
}

macro_rules! define_open {
    // use variables to indicate the arity of the tuple
    ($($from:ident),*) => {
        impl<'a, $($from,)*> Open for ($($from),*,)
            where $($from: Open),*,
                  ($(<$from as Open>::Mask,)*): BitAnd,
        {
            type Value = ($(<$from as Open>::Value),*,);
            type Mask = <($(<$from as Open>::Mask,)*) as BitAnd>::Value;
            #[allow(non_snake_case)]
            fn open(self) -> (Self::Mask, Self::Value) {
                let ($($from,)*) = self;
                let ($($from,)*) = ($($from.open(),)*);
                (
                    ($($from.0),*,).and(),
                    ($($from.1),*,)
                )
            }
        }

        impl<'a, $($from,)*> Get for ($($from),*,)
            where $($from: Get),*,
        {
            type Value = ($(<$from as Get>::Value),*,);
            #[allow(non_snake_case)]
            unsafe fn get(&self, idx: Index) -> Self::Value {
                let &($(ref $from,)*) = self;
                ($($from.get(idx)),*,)
            }
        }

        impl<'a, $($from,)*> Join for ($($from),*,)
            where $($from: Open),*,
                  ($(<$from as Open>::Mask),*,): BitAnd,
        {
            type Mask = <($(<$from as Open>::Mask),*,) as BitAnd>::Value;
            type Values = ($(<$from as Open>::Value),*,);

            fn join(self) -> Joined<Self::Mask, Self::Values> {
                let (mask, value) = self.open();
                Joined::new(mask, value)
            }
        }

    }
}

define_open!{A}
define_open!{A, B}
define_open!{A, B, C}
define_open!{A, B, C, D}
define_open!{A, B, C, D, E}
define_open!{A, B, C, D, E, F}
define_open!{A, B, C, D, E, F, G}
define_open!{A, B, C, D, E, F, G, H}
define_open!{A, B, C, D, E, F, G, H, I}
define_open!{A, B, C, D, E, F, G, H, I, J}
define_open!{A, B, C, D, E, F, G, H, I, J, K}
define_open!{A, B, C, D, E, F, G, H, I, J, K, L}
define_open!{A, B, C, D, E, F, G, H, I, J, K, L, M}
define_open!{A, B, C, D, E, F, G, H, I, J, K, L, M, N}
define_open!{A, B, C, D, E, F, G, H, I, J, K, L, M, N, O}
define_open!{A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P}
<commit_msg>Cleanup<commit_after>use std;
use tuple_utils::Split;
use bitset;
use Index;
use {BitSet, BitSetAnd, BitSetLike, Storage, UnprotectedStorage};

/// BitAnd is a helper method to & bitsets togather resulting in a tree
pub trait BitAnd {
    type Value: BitSetLike;
    fn and(self) -> Self::Value;
}

/// This needs to be special cased
impl<A> BitAnd for (A,)
    where A: BitSetLike
{
    type Value = A;
    fn and(self) -> Self::Value {
        self.0
    }
}

macro_rules! bitset_and {
    // use variables to indicate the arity of the tuple
    ($($from:ident),*) => {
        impl<$($from),*> BitAnd for ($($from),*)
            where $($from: BitSetLike),*
        {
            type Value = BitSetAnd<
                <<Self as Split>::Left as BitAnd>::Value,
                <<Self as Split>::Right as BitAnd>::Value
            >;
            fn and(self) -> Self::Value {
              let (l, r) = self.split();
              BitSetAnd(l.and(), r.and())
            }
        }
    }
}

bitset_and!{A, B}
bitset_and!{A, B, C}
bitset_and!{A, B, C, D}
bitset_and!{A, B, C, D, E}
bitset_and!{A, B, C, D, E, F}
bitset_and!{A, B, C, D, E, F, G}
bitset_and!{A, B, C, D, E, F, G, H}
bitset_and!{A, B, C, D, E, F, G, H, I}
bitset_and!{A, B, C, D, E, F, G, H, I, J}
bitset_and!{A, B, C, D, E, F, G, H, I, J, K}
bitset_and!{A, B, C, D, E, F, G, H, I, J, K, L}
bitset_and!{A, B, C, D, E, F, G, H, I, J, K, L, M}
bitset_and!{A, B, C, D, E, F, G, H, I, J, K, L, M, N}
bitset_and!{A, B, C, D, E, F, G, H, I, J, K, L, M, N, O}
bitset_and!{A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P}

/// The only purpose of the `Open` trait is to provide a way
/// to access the `open` or `open_mut` trait in a generic way
/// This way the fact that the type is immutable or mutable
/// is not lost when it is used later.
pub trait Open {
    type Value;
    type Mask: BitSetLike;
    fn open(self) -> (Self::Mask, Self::Value);
}

impl<'a, T> Open for &'a T
    where T: Storage
{
    type Value = GetRef<'a, T::UnprotectedStorage>;
    type Mask = &'a BitSet;
    fn open(self) -> (Self::Mask, Self::Value) {
        let (l, r) = self.open();
        (l, GetRef(r))
    }
}

impl<'a, T> Open for &'a mut T
    where T: Storage
{
    type Value = GetMut<'a, T::UnprotectedStorage>;
    type Mask = &'a BitSet;
    fn open(self) -> (Self::Mask, Self::Value) {
        let (l, r) = self.open_mut();
        (l, GetMut(r))
    }
}

/// Get like `Open` provides the same feature of providing
/// mutable vs immutable preserving around the UnprotectedStorage
/// trait
pub trait Get {
    type Value;
    unsafe fn get(&self, idx: Index) -> Self::Value;
}

pub struct GetRef<'a, T: 'a>(&'a T);
impl<'a, T> Get for GetRef<'a, T>
    where T: UnprotectedStorage
{
    type Value = &'a T::Component;
    unsafe fn get(&self, idx: Index) -> Self::Value {
        self.0.get(idx)
    }
}

pub struct GetMut<'a, T: 'a>(&'a mut T);
impl<'a, T> Get for GetMut<'a, T>
    where T: UnprotectedStorage
{
    type Value = &'a mut T::Component;
    #[allow(mutable_transmutes)]
    unsafe fn get(&self, idx: Index) -> Self::Value {
        // This is obviously unsafe and is one of the reasons this
        // trait is marked as unsafe to being with. It is safe
        // an an external api point of view because the bitmask
        // iterator never visits the same index twice, otherwise
        // this would provide multiple aliased mutable pointers which
        // is illegal in rust.
        let x: &mut Self = std::mem::transmute(self);
        x.0.get_mut(idx)
    }
}

/// Joined is an Iterator over a group of `Storages`
pub struct Joined<K, V> {
    keys: bitset::Iter<K>,
    values: V,
}

impl<K, V> Joined<K, V>
    where K: BitSetLike
{
    fn new(k: K, v: V) -> Joined<K, V> {
        Joined {
            keys: k.iter(),
            values: v,
        }
    }
}

impl<K, V> std::iter::Iterator for Joined<K, V>
    where K: BitSetLike,
          V: Get
{
    type Item = V::Value;
    fn next(&mut self) -> Option<Self::Item> {
        if let Some(idx) = self.keys.next() {
            unsafe { Some(self.values.get(idx)) }
        } else {
            None
        }
    }
}

/// Join one or more `Storage` components together
/// this will return an iterator that will return
/// the components of an entity
pub trait Join {
    /// The Mask selects which elements are found
    /// in the  Values collection
    type Mask;
    /// The Values is a tuple of `UnprotectedStorage`
    type Values;
    /// Join the `Storages` togather
    fn join(self) -> Joined<Self::Mask, Self::Values>;
}

macro_rules! define_open {
    // use variables to indicate the arity of the tuple
    ($($from:ident),*) => {
        impl<'a, $($from,)*> Open for ($($from),*,)
            where $($from: Open),*,
                  ($(<$from as Open>::Mask,)*): BitAnd,
        {
            type Value = ($($from::Value),*,);
            type Mask = <($($from::Mask,)*) as BitAnd>::Value;
            #[allow(non_snake_case)]
            fn open(self) -> (Self::Mask, Self::Value) {
                let ($($from,)*) = self;
                let ($($from,)*) = ($($from.open(),)*);
                (
                    ($($from.0),*,).and(),
                    ($($from.1),*,)
                )
            }
        }

        impl<'a, $($from,)*> Get for ($($from),*,)
            where $($from: Get),*,
        {
            type Value = ($($from::Value),*,);
            #[allow(non_snake_case)]
            unsafe fn get(&self, idx: Index) -> Self::Value {
                let &($(ref $from,)*) = self;
                ($($from.get(idx)),*,)
            }
        }

        impl<'a, $($from,)*> Join for ($($from),*,)
            where $($from: Open),*,
                  ($(<$from as Open>::Mask),*,): BitAnd,
        {
            type Mask = <($($from::Mask),*,) as BitAnd>::Value;
            type Values = ($($from::Value),*,);

            fn join(self) -> Joined<Self::Mask, Self::Values> {
                let (mask, value) = self.open();
                Joined::new(mask, value)
            }
        }

    }
}

define_open!{A}
define_open!{A, B}
define_open!{A, B, C}
define_open!{A, B, C, D}
define_open!{A, B, C, D, E}
define_open!{A, B, C, D, E, F}
define_open!{A, B, C, D, E, F, G}
define_open!{A, B, C, D, E, F, G, H}
define_open!{A, B, C, D, E, F, G, H, I}
define_open!{A, B, C, D, E, F, G, H, I, J}
define_open!{A, B, C, D, E, F, G, H, I, J, K}
define_open!{A, B, C, D, E, F, G, H, I, J, K, L}
define_open!{A, B, C, D, E, F, G, H, I, J, K, L, M}
define_open!{A, B, C, D, E, F, G, H, I, J, K, L, M, N}
define_open!{A, B, C, D, E, F, G, H, I, J, K, L, M, N, O}
define_open!{A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P}
<|endoftext|>


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

use std::os::unix::io::RawFd;
use std::io::{Error, ErrorKind};

use libc;
use frame;
use socket::Socket;
use frame::FrameState;

#[derive(Clone)]
pub struct Nbstream {
    id: String,
    inner: Socket,
    state: FrameState,
    buffer: Vec<u8>,
    scratch: Vec<u8>,
    tx_queue: Vec<Vec<u8>>
}

impl Nbstream {
    pub fn new(stream: Socket) -> Result<Nbstream, Error> {
        let result = unsafe { libc::fcntl(stream.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK) };
        if result < 0 {
            return Err(Error::from_raw_os_error(result as i32))
        }

        Ok(Nbstream {
            id: "".to_string(),
            inner: stream,
            state: FrameState::Start,
            buffer: Vec::with_capacity(3),
            scratch: Vec::new(),
            tx_queue: Vec::new()
        })
    }

    pub fn id(&self) -> String {
        self.id.clone()
    }

    pub fn as_raw_fd(&self) -> RawFd {
        self.inner.as_raw_fd()
    }

    pub fn recv(&mut self) -> Result<Vec<u8>, Error> {
        loop {
            let mut buf = Vec::<u8>::with_capacity(512);
            unsafe { buf.set_len(512); }
            let result = self.inner.read(&mut buf[..]);
            if result.is_err() {
                return Err(result.unwrap_err())
            }
            let num_read = result.unwrap();

            buf = self.buf_with_scratch(&buf[..], num_read);
            let mut seek_pos = 0usize;

            if self.state == FrameState::Start {
                self.read_for_frame_start(&buf[..], &mut seek_pos, num_read);
            }

            if self.state == FrameState::PayloadLen {
                self.read_payload_len(&buf[..], &mut seek_pos, num_read);
            }

            if self.state == FrameState::Payload {
                self.read_payload(&buf[..], &mut seek_pos, num_read);
            }

            if self.state == FrameState::End {
                let result = self.read_for_frame_end(&buf[..], seek_pos, num_read);
                if result.is_ok() {
                    return Ok(result.unwrap())
                }
            }
        }
    }

    pub fn send(&mut self, buf: &[u8]) -> Result<usize, Error> {
        let mut total_written = 0usize;
        self.tx_queue.push(frame::from_slice(buf));
        for x in 0..self.tx_queue.len() {
            let b = self.tx_queue.remove(x);
            let result = self.inner.write(buf);
            if result.is_err() {
                let err = result.unwrap_err();
                if err.kind() == ErrorKind::WouldBlock {
                    self.tx_queue.insert(x, b);
                }
                return Err(err)
            }

            let num_written = result.unwrap();
            total_written += num_written;
            if num_written < b.len() {
                let remainder = self.vec_from_slice(&b[(b.len() - num_written) ..b.len()]);
                self.tx_queue.insert(x, remainder);
                return Ok(total_written)
            }
        }
        Ok(total_written)
    }

    fn buf_with_scratch(&mut self, buf: &[u8], len: usize) -> Vec<u8> {
        let mut new_buf = Vec::<u8>::with_capacity(self.scratch.len() + len);
        for byte in self.scratch.iter() {
            new_buf.push(*byte);
        }
        self.scratch = Vec::<u8>::new();
        for x in 0..len {
            new_buf.push(buf[x]);
        }
        new_buf
    }

    fn read_for_frame_start(&mut self, buf: &[u8], offset: &mut usize, len: usize) {
        for _ in *offset..len {
            if buf[*offset] == frame::START {
                self.buffer.push(buf[*offset]);
                self.state = FrameState::PayloadLen;
                *offset += 1;
                break;
            }
            *offset += 1;
        }
    }

    fn read_payload_len(&mut self, buf: &[u8], offset: &mut usize, len: usize) {
        for _ in *offset..len {
            self.buffer.push(buf[*offset]);
            if self.buffer.len() == 3 {
                let len = self.payload_len() + 1;
                self.buffer.reserve_exact(len);
                self.state = FrameState::Payload;
                *offset += 1;
                break;
            }
            *offset += 1;
        }
    }

    fn read_payload(&mut self, buf: &[u8], offset: &mut usize, len: usize) {
        for _ in *offset..len {
            self.buffer.push(buf[*offset]);
            if self.buffer.len() == self.payload_len() + 3 {
                self.buffer.push(buf[*offset]);
                self.state = FrameState::End;
                *offset += 1;
                break;
            }
            *offset += 1;
        }
    }

    fn read_for_frame_end(&mut self,
                          buf: &[u8],
                          offset: usize,
                          len: usize)
                          -> Result<Vec<u8>, ()> {
        if offset < len {
            let expected_end_byte = buf[offset];
            if expected_end_byte == frame::END {
                let mut payload = Vec::<u8>::with_capacity(self.payload_len());
                for x in 3..self.buffer.len() {
                    payload.push(self.buffer[x]);
                }
                self.state = FrameState::Start;
                self.buffer = Vec::<u8>::with_capacity(3);

                // If there is anything left in buf, we need to put it in our
                // scratch space because we're exiting here
                let mut offset = offset;
                offset += 1;
                self.scratch = Vec::<u8>::with_capacity(len - offset);
                for x in offset..len {
                    self.scratch.push(buf[x]);
                }
                return Ok(payload)
            }

            // If we're here, the frame was wrong. Maybe our fault, who knows?
            // Either way, we're going to reset and try to start again from the start byte.
            // We need to dump whatever is left in the buffer into our scratch because it
            // might be in there?
            self.state = FrameState::Start;
            self.buffer = Vec::<u8>::with_capacity(3);
            self.scratch = Vec::<u8>::with_capacity(len - offset);
            for x in offset..len {
                self.scratch.push(buf[x]);
            }
        }
        Err(())
    }

    fn payload_len(&self) -> usize {
        let mask = 0xFFFFu16;
        let len = ((self.buffer[1] as u16) << 8) & mask;
        (len | self.buffer[2] as u16) as usize
    }

    fn vec_from_slice(&self, slice: &[u8]) -> Vec<u8> {
        let mut buf = Vec::<u8>::with_capacity(slice.len());
        for byte in slice.iter() {
            buf.push(*byte);
        }
        buf
    }
}
<commit_msg>Whoops, len change bug found<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL was not
// distributed with this file, You can obtain one at
// http://mozilla.org/MPL/2.0/.

use std::os::unix::io::RawFd;
use std::io::{Error, ErrorKind};

use libc;
use frame;
use socket::Socket;
use frame::FrameState;

#[derive(Clone)]
pub struct Nbstream {
    id: String,
    inner: Socket,
    state: FrameState,
    buffer: Vec<u8>,
    scratch: Vec<u8>,
    tx_queue: Vec<Vec<u8>>
}

impl Nbstream {
    pub fn new(stream: Socket) -> Result<Nbstream, Error> {
        let result = unsafe { libc::fcntl(stream.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK) };
        if result < 0 {
            return Err(Error::from_raw_os_error(result as i32))
        }

        Ok(Nbstream {
            id: "".to_string(),
            inner: stream,
            state: FrameState::Start,
            buffer: Vec::with_capacity(3),
            scratch: Vec::new(),
            tx_queue: Vec::new()
        })
    }

    pub fn id(&self) -> String {
        self.id.clone()
    }

    pub fn as_raw_fd(&self) -> RawFd {
        self.inner.as_raw_fd()
    }

    pub fn recv(&mut self) -> Result<Vec<u8>, Error> {
        loop {
            let mut buf = Vec::<u8>::with_capacity(512);
            unsafe { buf.set_len(512); }
            let result = self.inner.read(&mut buf[..]);
            if result.is_err() {
                return Err(result.unwrap_err())
            }
            let num_read = result.unwrap();

            buf = self.buf_with_scratch(&buf[..], num_read);
            let len = buf.len();
            let mut seek_pos = 0usize;

            if self.state == FrameState::Start {
                self.read_for_frame_start(&buf[..], &mut seek_pos, len);
            }

            if self.state == FrameState::PayloadLen {
                self.read_payload_len(&buf[..], &mut seek_pos, len);
            }

            if self.state == FrameState::Payload {
                self.read_payload(&buf[..], &mut seek_pos, len);
            }

            if self.state == FrameState::End {
                let result = self.read_for_frame_end(&buf[..], seek_pos, len);
                if result.is_ok() {
                    return Ok(result.unwrap())
                }
            }
        }
    }

    pub fn send(&mut self, buf: &[u8]) -> Result<usize, Error> {
        let mut total_written = 0usize;
        self.tx_queue.push(frame::from_slice(buf));
        for x in 0..self.tx_queue.len() {
            let b = self.tx_queue.remove(x);
            let result = self.inner.write(buf);
            if result.is_err() {
                let err = result.unwrap_err();
                if err.kind() == ErrorKind::WouldBlock {
                    self.tx_queue.insert(x, b);
                }
                return Err(err)
            }

            let num_written = result.unwrap();
            total_written += num_written;
            if num_written < b.len() {
                let remainder = self.vec_from_slice(&b[(b.len() - num_written) ..b.len()]);
                self.tx_queue.insert(x, remainder);
                return Ok(total_written)
            }
        }
        Ok(total_written)
    }

    fn buf_with_scratch(&mut self, buf: &[u8], len: usize) -> Vec<u8> {
        let mut new_buf = Vec::<u8>::with_capacity(self.scratch.len() + len);
        for byte in self.scratch.iter() {
            new_buf.push(*byte);
        }
        self.scratch = Vec::<u8>::new();
        for x in 0..len {
            new_buf.push(buf[x]);
        }
        new_buf
    }

    fn read_for_frame_start(&mut self, buf: &[u8], offset: &mut usize, len: usize) {
        for _ in *offset..len {
            if buf[*offset] == frame::START {
                self.buffer.push(buf[*offset]);
                self.state = FrameState::PayloadLen;
                *offset += 1;
                break;
            }
            *offset += 1;
        }
    }

    fn read_payload_len(&mut self, buf: &[u8], offset: &mut usize, len: usize) {
        for _ in *offset..len {
            self.buffer.push(buf[*offset]);
            if self.buffer.len() == 3 {
                let len = self.payload_len() + 1;
                self.buffer.reserve_exact(len);
                self.state = FrameState::Payload;
                *offset += 1;
                break;
            }
            *offset += 1;
        }
    }

    fn read_payload(&mut self, buf: &[u8], offset: &mut usize, len: usize) {
        for _ in *offset..len {
            self.buffer.push(buf[*offset]);
            if self.buffer.len() == self.payload_len() + 3 {
                self.buffer.push(buf[*offset]);
                self.state = FrameState::End;
                *offset += 1;
                break;
            }
            *offset += 1;
        }
    }

    fn read_for_frame_end(&mut self,
                          buf: &[u8],
                          offset: usize,
                          len: usize)
                          -> Result<Vec<u8>, ()> {
        if offset < len {
            let expected_end_byte = buf[offset];
            if expected_end_byte == frame::END {
                let mut payload = Vec::<u8>::with_capacity(self.payload_len());
                for x in 3..self.buffer.len() {
                    payload.push(self.buffer[x]);
                }
                self.state = FrameState::Start;
                self.buffer = Vec::<u8>::with_capacity(3);

                // If there is anything left in buf, we need to put it in our
                // scratch space because we're exiting here
                let mut offset = offset;
                offset += 1;
                self.scratch = Vec::<u8>::with_capacity(len - offset);
                for x in offset..len {
                    self.scratch.push(buf[x]);
                }
                return Ok(payload)
            }

            // If we're here, the frame was wrong. Maybe our fault, who knows?
            // Either way, we're going to reset and try to start again from the start byte.
            // We need to dump whatever is left in the buffer into our scratch because it
            // might be in there?
            self.state = FrameState::Start;
            self.buffer = Vec::<u8>::with_capacity(3);
            self.scratch = Vec::<u8>::with_capacity(len - offset);
            for x in offset..len {
                self.scratch.push(buf[x]);
            }
        }
        Err(())
    }

    fn payload_len(&self) -> usize {
        let mask = 0xFFFFu16;
        let len = ((self.buffer[1] as u16) << 8) & mask;
        (len | self.buffer[2] as u16) as usize
    }

    fn vec_from_slice(&self, slice: &[u8]) -> Vec<u8> {
        let mut buf = Vec::<u8>::with_capacity(slice.len());
        for byte in slice.iter() {
            buf.push(*byte);
        }
        buf
    }
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

use log::{error, info};

use rrg::action;
use rrg::session;
use rrg::opts::{self, Opts};

fn main() {
    let opts = opts::from_args();
    init(&opts);

    fleetspeak::startup(env!("CARGO_PKG_VERSION"))
        .expect("failed to initialize Fleetspeak connection");

    match action::startup::handle(&mut session::Adhoc, ()) {
        Err(error) => {
            error!("failed to collect startup information: {}", error);
        }
        Ok(()) => {
            info!("successfully sent startup information");
        }
    }

    rrg::listen(&opts);
}

fn init(_: &Opts) {
    rrg::log::init();
}
<commit_msg>Improve logging in the main function.<commit_after>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

use rrg::action;
use rrg::session;
use rrg::opts::{self, Opts};

fn main() {
    let opts = opts::from_args();
    init(&opts);

    log::info!("sending Fleetspeak startup information");
    fleetspeak::startup(env!("CARGO_PKG_VERSION"))
        .expect("failed to initialize Fleetspeak connection");

    log::info!("sending RRG startup information");
    match action::startup::handle(&mut session::Adhoc, ()) {
        Err(error) => {
            log::error!("failed to collect startup information: {}", error);
        }
        Ok(()) => {
            log::info!("successfully sent startup information");
        }
    }

    log::info!("listening for messages");
    rrg::listen(&opts);
}

fn init(_: &Opts) {
    rrg::log::init();
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate serenity;
extern crate chrono;
extern crate rand;
extern crate time;

use std::string::*;
use serenity::model::*;
use serenity::Result as SerenityResult;
use serenity::Client;
use serenity::framework::standard::help_commands;
use serenity::framework::StandardFramework;
use serenity::client::{EventHandler,Context, CACHE};
use std::env;
use std::ascii::AsciiExt;
use std::time::{SystemTime, UNIX_EPOCH};
use serenity::model::permissions::Permissions;

mod commands;

struct Handler;

impl EventHandler for Handler {
    fn on_ready(&self, ctx: Context, ready: Ready) {
        	println!("{} is connected!", ready.user.name);
		ctx.set_game_name("lelcp.github.io/bot");
	}
	fn on_message(&self, _: Context, message: Message) {
		if !message.author.bot {
			if message.content.to_ascii_lowercase().contains("thx") || message.content.to_ascii_lowercase().contains("thank"){
				let guild_id = match CACHE.read().unwrap().guild_channel(message.channel_id) {
					Some(channel) => channel.read().unwrap().guild_id,
					None => {
						check_msg(message.channel_id.say(&"Groups and DMs not supported"));
						return ();
					},
				};
				let start = SystemTime::now();
	    			let since_the_epoch = start.duration_since(UNIX_EPOCH)
	       			.expect("Time went backwards");
	       			if message.mentions.len() > 0 {
				if since_the_epoch.as_secs() >= commands::pierogi::time_pierogi(&message.author.id.to_string(),&guild_id.to_string()) {
					let mut msg: String = "".to_string();
						for mention in message.mentions {
							if message.author.id != mention.id {
								msg = format!("{} <@{}>",msg,mention.id);
								let pierogi = commands::pierogi::read_pierogi(&mention.id.to_string(),&guild_id.to_string());
								commands::pierogi::new_pierogi(&mention.id.to_string(), &guild_id.to_string(), pierogi + 1, commands::pierogi::time_pierogi(&mention.id.to_string(),&guild_id.to_string()));
								commands::pierogi::new_pierogi(&message.author.id.to_string(), &guild_id.to_string(), commands::pierogi::read_pierogi(&message.author.id.to_string(),&guild_id.to_string()), since_the_epoch.as_secs() + 7140);
							}
						}
						if msg != "".to_string() {
							check_msg(message.channel_id.say(&format!("You recived thank you pieróg {}",msg)));
						}
					}
					else {
						check_msg(message.channel_id.say(format!("<@{}>, I know your mommy told you to thank as much as you can, but this is too much",message.author.id)));
					}
				}
			}
			else if message.content.to_ascii_lowercase().contains("i mean"){
				let _ = message.channel_id.send_message(|m| m.content(format!("You mean <@{}> ?",message.author.id)));
			}
		}
	}
}

fn main() {

	let token = env::var("DISCORD_TOKEN")
		.expect("Expected a token in the environment");
	let mut client = Client::new(&token, Handler);
	client.with_framework(StandardFramework::new()
		.bucket("basic", 5, 60, 3)
		.configure(|c| c
			.prefix("!")
			.on_mention(true))
		.group("Miscellaneous", |g| g
			.command("gnu", |c| c
				.desc("GNU Interjection copypasta")
				.usage("<GNU replacement> <Linux replacement>")
				.exec(commands::misc::gnu))
			.command("whiteface", |c| c
				.desc("This is not the gif on the internet")
				.exec(commands::misc::whiteface))
			.command("godtellmeyourways", |c| c
				.desc("Quote God himself, Richard Matthew Stallman")
				.exec(commands::misc::god))
			.command("donkey", |c| c
				.desc("Show current bot time and set nickname and playing message")
				.exec(commands::misc::donkey)))
		.group("Useful shit", |g| g
			.command("ddg", |c| c
				.desc("Powerful search with embeds")
				.usage("<search terms>")
				.exec(commands::useful::ddg))
			.command("emoji", |c| c
				.desc(":regional_indicator_s::regional_indicator_p::regional_indicator_e::regional_indicator_a::regional_indicator_k:   :regional_indicator_i::regional_indicator_n:   :regional_indicator_e::regional_indicator_m::regional_indicator_o::regional_indicator_j::regional_indicator_i:")
				.usage("<your text>")
				.bucket("basic")
				.exec(commands::useful::emoji))
			.command("info", |c| c
				.desc("Distro database")
				.usage("<distro name>")
				.exec(commands::useful::info))
			.command("wget", |c| c
				.desc("Sends wget script")
				.usage("<amount of messages in hundreds to download from channel>")
				.exec(commands::useful::wget)))
		.group("About bot", |g| g
			.command("github", |c| c
				.desc("Shilling open source nature of this project")
				.exec(commands::about::github))
			.command("rust", |c| c
				.desc("Shilling rust nature of this project")
				.exec(commands::about::rust))
			.command("lcpae", |c| c
				.exec_help(help_commands::with_embeds)))
		.group("Tux", |g| g
			.command("roasted", |c| c
				.desc("Daaaaaamn!")
				.exec(commands::tux::roasted))
			.command("hypertux", |c| c
				.desc("Laugh all you want")
				.exec(commands::tux::hypertux))
			.command("hyperthink", |c| c
				.desc("TFW hacked mainframe")
				.exec(commands::tux::hyperthink)))
		.group("Admin", |g| g
			.required_permissions(Permissions::ADMINISTRATOR)
			.command("clear", |c| c
				.desc("Clean previous messages")
				.exec(commands::admin::clear)))
		.group("Pierogi", |g| g
			.prefix("pierog")
			.command("score", |c| c
				.desc("Check your own score")
				.exec(commands::pierogi::score))
			.command("steal", |c| c
				.desc("Steal pierogi, but be careful")
				.exec(commands::pierogi::steal))
			.command("give", |c| c
				.desc("Steal pierogi, but be careful")
				.exec(commands::pierogi::give))

		));
	let _ = client.start().map_err(|why| println!("Client ended: {:?}", why));
}

fn check_msg(result: SerenityResult<Message>) {
	if let Err(why) = result {
		println!("Error sending message: {:?}", why);
	}
}
<commit_msg>Supposedly I mean is annoying<commit_after>#[macro_use]
extern crate serenity;
extern crate chrono;
extern crate rand;
extern crate time;

use std::string::*;
use serenity::model::*;
use serenity::Result as SerenityResult;
use serenity::Client;
use serenity::framework::standard::help_commands;
use serenity::framework::StandardFramework;
use serenity::client::{EventHandler,Context, CACHE};
use std::env;
use std::ascii::AsciiExt;
use std::time::{SystemTime, UNIX_EPOCH};
use serenity::model::permissions::Permissions;

mod commands;

struct Handler;

impl EventHandler for Handler {
    fn on_ready(&self, ctx: Context, ready: Ready) {
        	println!("{} is connected!", ready.user.name);
		ctx.set_game_name("lelcp.github.io/bot");
	}
	fn on_message(&self, _: Context, message: Message) {
		if !message.author.bot {
			if message.content.to_ascii_lowercase().contains("thx") || message.content.to_ascii_lowercase().contains("thank"){
				let guild_id = match CACHE.read().unwrap().guild_channel(message.channel_id) {
					Some(channel) => channel.read().unwrap().guild_id,
					None => {
						check_msg(message.channel_id.say(&"Groups and DMs not supported"));
						return ();
					},
				};
				let start = SystemTime::now();
	    			let since_the_epoch = start.duration_since(UNIX_EPOCH)
	       			.expect("Time went backwards");
	       			if message.mentions.len() > 0 {
				if since_the_epoch.as_secs() >= commands::pierogi::time_pierogi(&message.author.id.to_string(),&guild_id.to_string()) {
					let mut msg: String = "".to_string();
						for mention in message.mentions {
							if message.author.id != mention.id {
								msg = format!("{} <@{}>",msg,mention.id);
								let pierogi = commands::pierogi::read_pierogi(&mention.id.to_string(),&guild_id.to_string());
								commands::pierogi::new_pierogi(&mention.id.to_string(), &guild_id.to_string(), pierogi + 1, commands::pierogi::time_pierogi(&mention.id.to_string(),&guild_id.to_string()));
								commands::pierogi::new_pierogi(&message.author.id.to_string(), &guild_id.to_string(), commands::pierogi::read_pierogi(&message.author.id.to_string(),&guild_id.to_string()), since_the_epoch.as_secs() + 7140);
							}
						}
						if msg != "".to_string() {
							check_msg(message.channel_id.say(&format!("You recived thank you pieróg {}",msg)));
						}
					}
					else {
						check_msg(message.channel_id.say(format!("<@{}>, I know your mommy told you to thank as much as you can, but this is too much",message.author.id)));
					}
				}
			}
		}
	}
}

fn main() {

	let token = env::var("DISCORD_TOKEN")
		.expect("Expected a token in the environment");
	let mut client = Client::new(&token, Handler);
	client.with_framework(StandardFramework::new()
		.bucket("basic", 5, 60, 3)
		.configure(|c| c
			.prefix("!")
			.on_mention(true))
		.group("Miscellaneous", |g| g
			.command("gnu", |c| c
				.desc("GNU Interjection copypasta")
				.usage("<GNU replacement> <Linux replacement>")
				.exec(commands::misc::gnu))
			.command("whiteface", |c| c
				.desc("This is not the gif on the internet")
				.exec(commands::misc::whiteface))
			.command("godtellmeyourways", |c| c
				.desc("Quote God himself, Richard Matthew Stallman")
				.exec(commands::misc::god))
			.command("donkey", |c| c
				.desc("Show current bot time and set nickname and playing message")
				.exec(commands::misc::donkey)))
		.group("Useful shit", |g| g
			.command("ddg", |c| c
				.desc("Powerful search with embeds")
				.usage("<search terms>")
				.exec(commands::useful::ddg))
			.command("emoji", |c| c
				.desc(":regional_indicator_s::regional_indicator_p::regional_indicator_e::regional_indicator_a::regional_indicator_k:   :regional_indicator_i::regional_indicator_n:   :regional_indicator_e::regional_indicator_m::regional_indicator_o::regional_indicator_j::regional_indicator_i:")
				.usage("<your text>")
				.bucket("basic")
				.exec(commands::useful::emoji))
			.command("info", |c| c
				.desc("Distro database")
				.usage("<distro name>")
				.exec(commands::useful::info))
			.command("wget", |c| c
				.desc("Sends wget script")
				.usage("<amount of messages in hundreds to download from channel>")
				.exec(commands::useful::wget)))
		.group("About bot", |g| g
			.command("github", |c| c
				.desc("Shilling open source nature of this project")
				.exec(commands::about::github))
			.command("rust", |c| c
				.desc("Shilling rust nature of this project")
				.exec(commands::about::rust))
			.command("lcpae", |c| c
				.exec_help(help_commands::with_embeds)))
		.group("Tux", |g| g
			.command("roasted", |c| c
				.desc("Daaaaaamn!")
				.exec(commands::tux::roasted))
			.command("hypertux", |c| c
				.desc("Laugh all you want")
				.exec(commands::tux::hypertux))
			.command("hyperthink", |c| c
				.desc("TFW hacked mainframe")
				.exec(commands::tux::hyperthink)))
		.group("Admin", |g| g
			.required_permissions(Permissions::ADMINISTRATOR)
			.command("clear", |c| c
				.desc("Clean previous messages")
				.exec(commands::admin::clear)))
		.group("Pierogi", |g| g
			.prefix("pierog")
			.command("score", |c| c
				.desc("Check your own score")
				.exec(commands::pierogi::score))
			.command("steal", |c| c
				.desc("Steal pierogi, but be careful")
				.exec(commands::pierogi::steal))
			.command("give", |c| c
				.desc("Steal pierogi, but be careful")
				.exec(commands::pierogi::give))

		));
	let _ = client.start().map_err(|why| println!("Client ended: {:?}", why));
}

fn check_msg(result: SerenityResult<Message>) {
	if let Err(why) = result {
		println!("Error sending message: {:?}", why);
	}
}
<|endoftext|>


<commit_before>/* Stones esoteric programming language
 * (c) 2016 Zack Hixon - see LICENSE.txt */

fn main() {
    println!("Hello, world!");
}

<commit_msg>Add Stone struct<commit_after>/* Stones esoteric programming language
 * (c) 2016 Zack Hixon - see LICENSE.txt */

#[derive(Debug)]
//#[derive(Copy, Clone)]
struct Stone {
    x: i32,
    y: i32,
    id: i32
}

fn main() {
    let mut stone = Stone {x: 32, y: 32, id: 1};
    println!("{:?}", stone);

    stone.x = 64;
    stone.y = 64;
    stone.id = 2;

    println!("{:?}", stone);
}

<|endoftext|>