<commit_before>#![cfg_attr(test, deny(missing_docs, warnings))]
#![forbid(unused_variables)]

use std::{fmt, mem};
use std::borrow::{Borrow, ToOwned};
use std::default::Default;
use std::hash::{Hash, Hasher};
use std::ops::{Deref, Index, Range, RangeFrom, RangeFull, RangeTo};

/// An owned sequence of Unicode scalar values, equivalent to `String`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UString(Vec<char>);

/// A Unicode string slice, equivalent to `str`.
pub struct UStr([char]);

impl UStr {
    /// Returns the number of Unicode scalar values in this string.
    pub fn len(&self) -> usize {
        self.0.len()
    }
}

impl Borrow<UStr> for UString {
    fn borrow(&self) -> &UStr {
        &self
    }
}

impl Default for UString {
    fn default() -> UString {
        UString(Vec::new())
    }
}

impl Deref for UString {
    type Target = UStr;

    fn deref(&self) -> &UStr {
        unsafe {
            mem::transmute(&*self.0)
            // just so you can be clear what it is:
            //mem::transmute::<&[char], &UStr>(&*self.0)
        }
    }
}

impl From<Vec<char>> for UString {
    fn from(chars: Vec<char>) -> UString {
        UString(chars)
    }
}

impl<'a> From<&'a str> for UString {
    fn from(string: &'a str) -> UString {
        UString(string.chars().collect())
    }
}

impl<'a> From<&'a [char]> for UString {
    fn from(slice: &[char]) -> UString {
        UString(slice.to_vec())
    }
}

impl Hash for UString {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state);
    }
}

impl Index<usize> for UStr {
    type Output = char;

    fn index(&self, idx: usize) -> &char {
        &self.0[idx]
    }
}

impl Index<Range<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: Range<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFrom<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeFrom<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFull> for UStr {
    type Output = UStr;

    fn index(&self, _: RangeFull) -> &UStr {
        self
    }
}

impl Index<RangeTo<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeTo<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl ToOwned for UStr {
    type Owned = UString;

    fn to_owned(&self) -> UString {
        UString::from(self.0.to_owned())
    }
}

impl fmt::Display for UStr {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for c in &self.0 {
            try!(write!(f, "{}", c));
        }
        Ok(())
    }
}
<commit_msg>Add UStr::slice_shift_char<commit_after>#![cfg_attr(test, deny(missing_docs, warnings))]
#![forbid(unused_variables)]

use std::{fmt, mem};
use std::borrow::{Borrow, ToOwned};
use std::default::Default;
use std::hash::{Hash, Hasher};
use std::ops::{Deref, Index, Range, RangeFrom, RangeFull, RangeTo};

/// An owned sequence of Unicode scalar values, equivalent to `String`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UString(Vec<char>);

/// A Unicode string slice, equivalent to `str`.
pub struct UStr([char]);

impl UStr {
    /// Returns the number of Unicode scalar values in this string.
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Retrieves the first character from a `&UStr` and returns it.
    ///
    /// This does not allocate a new string; instead, it returns a slice that points one character beyond the character that was shifted.
    ///
    /// If the slice does not contain any characters, None is returned instead.
    pub fn slice_shift_char(&self) -> Option<(char, &UStr)> {
        if self.len() == 0 {
            None
        } else {
            let ch = self[0];
            let next_s = &self[1..];
            Some((ch, next_s))
        }
    }
}

impl Borrow<UStr> for UString {
    fn borrow(&self) -> &UStr {
        &self
    }
}

impl Default for UString {
    fn default() -> UString {
        UString(Vec::new())
    }
}

impl Deref for UString {
    type Target = UStr;

    fn deref(&self) -> &UStr {
        unsafe {
            mem::transmute(&*self.0)
            // just so you can be clear what it is:
            //mem::transmute::<&[char], &UStr>(&*self.0)
        }
    }
}

impl From<Vec<char>> for UString {
    fn from(chars: Vec<char>) -> UString {
        UString(chars)
    }
}

impl<'a> From<&'a str> for UString {
    fn from(string: &'a str) -> UString {
        UString(string.chars().collect())
    }
}

impl<'a> From<&'a [char]> for UString {
    fn from(slice: &[char]) -> UString {
        UString(slice.to_vec())
    }
}

impl Hash for UString {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state);
    }
}

impl Index<usize> for UStr {
    type Output = char;

    fn index(&self, idx: usize) -> &char {
        &self.0[idx]
    }
}

impl Index<Range<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: Range<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFrom<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeFrom<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFull> for UStr {
    type Output = UStr;

    fn index(&self, _: RangeFull) -> &UStr {
        self
    }
}

impl Index<RangeTo<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeTo<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl ToOwned for UStr {
    type Owned = UString;

    fn to_owned(&self) -> UString {
        UString::from(self.0.to_owned())
    }
}

impl fmt::Display for UStr {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for c in &self.0 {
            try!(write!(f, "{}", c));
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>// lib.rs
// Copyright 2017 Alexander Altman
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![feature(conservative_impl_trait)]
#![recursion_limit = "1024"]

extern crate itertools;
use itertools::*;

extern crate unicode_segmentation;
use unicode_segmentation::UnicodeSegmentation;

#[macro_use]
extern crate error_chain;

pub mod error {
    error_chain!{}
}

#[derive(Debug)]
pub struct Config;

#[derive(Debug)]
pub struct Value;

pub fn interpret<P: IntoIterator>(_config: Config, _program: P) -> error::Result<Value> where P::Item: Tokens  {
    unimplemented!()
}
<commit_msg>Vwv22<commit_after>// lib.rs
// Copyright 2017 Alexander Altman
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![feature(conservative_impl_trait)]
#![recursion_limit = "1024"]

extern crate itertools;
use itertools::*;

extern crate unicode_segmentation;
use unicode_segmentation::UnicodeSegmentation;

extern crate unicode_normalization;
use unicode_normalization::UnicodeNormalization;

#[macro_use]
extern crate error_chain;

pub mod error {
    error_chain!{}
}

#[derive(Debug)]
pub struct Config;

#[derive(Debug)]
pub struct Value;

pub fn interpret<P: IntoIterator>(_config: Config, _program: P) -> error::Result<Value> where P::Item: Tokens  {
    unimplemented!()
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! A Glutin window back-end for the Piston game engine.

extern crate glutin;
extern crate gl;
extern crate input;
extern crate window;
extern crate shader_version;

// External crates.
use input::{
    keyboard,
    MouseButton,
    Button,
    Input,
};
use window::{
    OpenGLWindow,
    Window,
    AdvancedWindow,
    ProcAddress,
    WindowSettings,
    Size,
};
use glutin::{ Api, GlRequest };

pub use shader_version::OpenGL;

/// Contains stuff for game window.
pub struct GlutinWindow {
    /// The window.
    pub window: glutin::Window,
    // Used to compute relative mouse movement.
    last_mouse_pos: Option<(f64, f64)>,
    // The back-end does not remember the title.
    title: String,
    exit_on_esc: bool,
    should_close: bool,
}

impl GlutinWindow {
    /// Creates a new game window for Glutin.
    pub fn new(opengl: OpenGL, settings: WindowSettings) -> Self {
        let (major, minor) = opengl.get_major_minor();
        let size = settings.get_size();
        let mut builder = glutin::WindowBuilder::new()
            .with_dimensions(size.width, size.height)
            .with_gl(GlRequest::Specific(Api::OpenGl, (major as u8, minor as u8)))
            .with_title(settings.get_title());
        let samples = settings.get_samples();
        if samples != 0 {
            builder = builder.with_multisampling(samples as u16);
        }
        if settings.get_fullscreen() {
            builder = builder.with_fullscreen(glutin::get_primary_monitor());
        }
        let window = builder.build().unwrap();
        unsafe { window.make_current(); }

        // Load the OpenGL function pointers.
        gl::load_with(|s| window.get_proc_address(s));

        GlutinWindow {
            window: window,
            last_mouse_pos: None,
            title: settings.get_title(),
            exit_on_esc: settings.get_exit_on_esc(),
            should_close: false,
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        use glutin::Event as E;
        use input::{ Key, Input, Motion };

        if let Some((x, y)) = self.last_mouse_pos {
            self.last_mouse_pos = None;
            return Some(Input::Move(Motion::MouseRelative(x, y)));
        }

        match self.window.poll_events().next() {
            None => None,
            Some(E::Resized(w, h)) =>
                Some(Input::Resize(w, h)),
            Some(E::ReceivedCharacter(ch)) => {
                let string = match ch {
                    // Ignore control characters and return ascii for Text event (like sdl2).
                    '\u{7f}' | // Delete
                    '\u{1b}' | // Escape
                    '\u{8}'  | // Backspace
                    '\r' | '\n' | '\t' => "".to_string(),
                    _ => ch.to_string()
                };
                Some(Input::Text(string))
            },
            Some(E::Focused(focused)) =>
                Some(Input::Focus(focused)),
            Some(E::KeyboardInput(glutin::ElementState::Pressed, _, Some(key))) => {
                let piston_key = map_key(key);
                if let (true, Key::Escape) = (self.exit_on_esc, piston_key) {
                    self.should_close = true;
                }
                Some(Input::Press(Button::Keyboard(piston_key)))
            },
            Some(E::KeyboardInput(glutin::ElementState::Released, _, Some(key))) =>
                Some(Input::Release(Button::Keyboard(map_key(key)))),
            Some(E::MouseMoved((x, y))) => {
                self.last_mouse_pos = Some((x as f64, y as f64));
                Some(Input::Move(
                    Motion::MouseCursor(x as f64, y as f64)))
            }
            Some(E::MouseWheel(y)) =>
                Some(Input::Move(
                    Motion::MouseScroll(0.0, y as f64))),
            Some(E::MouseInput(glutin::ElementState::Pressed, button)) =>
                Some(Input::Press(Button::Mouse(map_mouse(button)))),
            Some(E::MouseInput(glutin::ElementState::Released, button)) =>
                Some(Input::Release(Button::Mouse(map_mouse(button)))),
            _ => None,
        }
    }
}

impl Window for GlutinWindow {
    type Event = Input;

    fn size(&self) -> Size {
        let f = self.window.hidpi_factor();
        if let Some((w, h)) = self.window.get_inner_size() {
            ((w as f32 / f) as u32, (h as f32 / f) as u32).into()
        } else {
            (0, 0).into()
        }
    }
    fn draw_size(&self) -> Size {
        if let Some(size) = self.window.get_inner_size() {
            size.into()
        } else {
            (0, 0).into()
        }
    }
    fn should_close(&self) -> bool {
        self.window.is_closed() || self.should_close
    }
    fn swap_buffers(&mut self) { self.window.swap_buffers(); }
    fn poll_event(&mut self) -> Option<Input> { self.poll_event() }
}

impl AdvancedWindow for GlutinWindow {
    fn get_title(&self) -> String { self.title.clone() }
    fn set_title(&mut self, value: String) {
        self.title = value;
        self.window.set_title(&self.title);
    }
    fn get_exit_on_esc(&self) -> bool { self.exit_on_esc }
    fn set_exit_on_esc(&mut self, value: bool) { self.exit_on_esc = value; }
    fn set_capture_cursor(&mut self, value: bool) {
        use glutin::CursorState;
        if value {
            let _ = self.window.set_cursor_state(CursorState::Grab);
        } else {
            let _ = self.window.set_cursor_state(CursorState::Normal);
        }
    }
}

impl OpenGLWindow for GlutinWindow {
    fn get_proc_address(&mut self, proc_name: &str) -> ProcAddress {
        self.window.get_proc_address(proc_name)
    }

    fn is_current(&self) -> bool {
        self.window.is_current()
    }

    fn make_current(&mut self) {
        unsafe {
            self.window.make_current()
        }
    }
}

/// Maps Glutin's key to Piston's key.
pub fn map_key(keycode: glutin::VirtualKeyCode) -> keyboard::Key {
    use input::keyboard::Key;
    use glutin::VirtualKeyCode as K;

    match keycode {
        K::Key0 => Key::D0,
        K::Key1 => Key::D1,
        K::Key2 => Key::D2,
        K::Key3 => Key::D3,
        K::Key4 => Key::D4,
        K::Key5 => Key::D5,
        K::Key6 => Key::D6,
        K::Key7 => Key::D7,
        K::Key8 => Key::D8,
        K::Key9 => Key::D9,
        K::A => Key::A,
        K::B => Key::B,
        K::C => Key::C,
        K::D => Key::D,
        K::E => Key::E,
        K::F => Key::F,
        K::G => Key::G,
        K::H => Key::H,
        K::I => Key::I,
        K::J => Key::J,
        K::K => Key::K,
        K::L => Key::L,
        K::M => Key::M,
        K::N => Key::N,
        K::O => Key::O,
        K::P => Key::P,
        K::Q => Key::Q,
        K::R => Key::R,
        K::S => Key::S,
        K::T => Key::T,
        K::U => Key::U,
        K::V => Key::V,
        K::W => Key::W,
        K::X => Key::X,
        K::Y => Key::Y,
        K::Z => Key::Z,
        K::Apostrophe => Key::Unknown,
        K::Backslash => Key::Backslash,
        K::Back => Key::Backspace,
        // K::CapsLock => Key::CapsLock,
        K::Delete => Key::Delete,
        K::Comma => Key::Comma,
        K::Down => Key::Down,
        K::End => Key::End,
        K::Return => Key::Return,
        K::Equals => Key::Equals,
        K::Escape => Key::Escape,
        K::F1 => Key::F1,
        K::F2 => Key::F2,
        K::F3 => Key::F3,
        K::F4 => Key::F4,
        K::F5 => Key::F5,
        K::F6 => Key::F6,
        K::F7 => Key::F7,
        K::F8 => Key::F8,
        K::F9 => Key::F9,
        K::F10 => Key::F10,
        K::F11 => Key::F11,
        K::F12 => Key::F12,
        K::F13 => Key::F13,
        K::F14 => Key::F14,
        K::F15 => Key::F15,
        // K::F16 => Key::F16,
        // K::F17 => Key::F17,
        // K::F18 => Key::F18,
        // K::F19 => Key::F19,
        // K::F20 => Key::F20,
        // K::F21 => Key::F21,
        // K::F22 => Key::F22,
        // K::F23 => Key::F23,
        // K::F24 => Key::F24,
        // Possibly next code.
        // K::F25 => Key::Unknown,
        K::Numpad0 => Key::NumPad0,
        K::Numpad1 => Key::NumPad1,
        K::Numpad2 => Key::NumPad2,
        K::Numpad3 => Key::NumPad3,
        K::Numpad4 => Key::NumPad4,
        K::Numpad5 => Key::NumPad5,
        K::Numpad6 => Key::NumPad6,
        K::Numpad7 => Key::NumPad7,
        K::Numpad8 => Key::NumPad8,
        K::Numpad9 => Key::NumPad9,
        K::NumpadComma => Key::NumPadDecimal,
        K::Divide => Key::NumPadDivide,
        K::Multiply => Key::NumPadMultiply,
        K::Subtract => Key::NumPadMinus,
        K::Add => Key::NumPadPlus,
        K::NumpadEnter => Key::NumPadEnter,
        K::NumpadEquals => Key::NumPadEquals,
        K::LShift => Key::LShift,
        K::LControl => Key::LCtrl,
        K::LAlt => Key::LAlt,
        K::LMenu => Key::LGui,
        K::RShift => Key::RShift,
        K::RControl => Key::RCtrl,
        K::RAlt => Key::RAlt,
        K::RMenu => Key::RGui,
        // Map to backslash?
        // K::GraveAccent => Key::Unknown,
        K::Home => Key::Home,
        K::Insert => Key::Insert,
        K::Left => Key::Left,
        K::LBracket => Key::LeftBracket,
        // K::Menu => Key::Menu,
        K::Minus => Key::Minus,
        K::Numlock => Key::NumLockClear,
        K::PageDown => Key::PageDown,
        K::PageUp => Key::PageUp,
        K::Pause => Key::Pause,
        K::Period => Key::Period,
        // K::PrintScreen => Key::PrintScreen,
        K::Right => Key::Right,
        K::RBracket => Key::RightBracket,
        // K::ScrollLock => Key::ScrollLock,
        K::Semicolon => Key::Semicolon,
        K::Slash => Key::Slash,
        K::Space => Key::Space,
        K::Tab => Key::Tab,
        K::Up => Key::Up,
        // K::World1 => Key::Unknown,
        // K::World2 => Key::Unknown,
        _ => Key::Unknown,
    }
}

/// Maps Glutin's mouse button to Piston's mouse button.
pub fn map_mouse(mouse_button: glutin::MouseButton) -> MouseButton {
    use glutin::MouseButton as M;

    match mouse_button {
        M::Left => MouseButton::Left,
        M::Right => MouseButton::Right,
        M::Middle => MouseButton::Middle,
        M::Other(0) => MouseButton::X1,
        M::Other(1) => MouseButton::X2,
        M::Other(2) => MouseButton::Button6,
        M::Other(3) => MouseButton::Button7,
        M::Other(4) => MouseButton::Button8,
        _ => MouseButton::Unknown
    }
}
<commit_msg>Fixed application of hidpi_factor (should now work fine on retina displays)<commit_after>#![deny(missing_docs)]

//! A Glutin window back-end for the Piston game engine.

extern crate glutin;
extern crate gl;
extern crate input;
extern crate window;
extern crate shader_version;

// External crates.
use input::{
    keyboard,
    MouseButton,
    Button,
    Input,
};
use window::{
    OpenGLWindow,
    Window,
    AdvancedWindow,
    ProcAddress,
    WindowSettings,
    Size,
};
use glutin::{ Api, GlRequest };

pub use shader_version::OpenGL;

/// Contains stuff for game window.
pub struct GlutinWindow {
    /// The window.
    pub window: glutin::Window,
    // Used to compute relative mouse movement.
    last_mouse_pos: Option<(f64, f64)>,
    // The back-end does not remember the title.
    title: String,
    exit_on_esc: bool,
    should_close: bool,
}

impl GlutinWindow {

    /// Creates a new game window for Glutin.
    pub fn new(opengl: OpenGL, settings: WindowSettings) -> Self {
        let (major, minor) = opengl.get_major_minor();
        let size = settings.get_size();
        let mut builder = glutin::WindowBuilder::new()
            .with_dimensions(size.width, size.height)
            .with_gl(GlRequest::Specific(Api::OpenGl, (major as u8, minor as u8)))
            .with_title(settings.get_title());
        let samples = settings.get_samples();
        if samples != 0 {
            builder = builder.with_multisampling(samples as u16);
        }
        if settings.get_fullscreen() {
            builder = builder.with_fullscreen(glutin::get_primary_monitor());
        }
        let window = builder.build().unwrap();
        unsafe { window.make_current(); }

        // Load the OpenGL function pointers.
        gl::load_with(|s| window.get_proc_address(s));

        GlutinWindow {
            window: window,
            last_mouse_pos: None,
            title: settings.get_title(),
            exit_on_esc: settings.get_exit_on_esc(),
            should_close: false,
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        use glutin::Event as E;
        use input::{ Key, Input, Motion };

        if let Some((x, y)) = self.last_mouse_pos {
            self.last_mouse_pos = None;
            return Some(Input::Move(Motion::MouseRelative(x, y)));
        }

        match self.window.poll_events().next() {
            None => None,
            Some(E::Resized(w, h)) =>
                Some(Input::Resize(w, h)),
            Some(E::ReceivedCharacter(ch)) => {
                let string = match ch {
                    // Ignore control characters and return ascii for Text event (like sdl2).
                    '\u{7f}' | // Delete
                    '\u{1b}' | // Escape
                    '\u{8}'  | // Backspace
                    '\r' | '\n' | '\t' => "".to_string(),
                    _ => ch.to_string()
                };
                Some(Input::Text(string))
            },
            Some(E::Focused(focused)) =>
                Some(Input::Focus(focused)),
            Some(E::KeyboardInput(glutin::ElementState::Pressed, _, Some(key))) => {
                let piston_key = map_key(key);
                if let (true, Key::Escape) = (self.exit_on_esc, piston_key) {
                    self.should_close = true;
                }
                Some(Input::Press(Button::Keyboard(piston_key)))
            },
            Some(E::KeyboardInput(glutin::ElementState::Released, _, Some(key))) =>
                Some(Input::Release(Button::Keyboard(map_key(key)))),
            Some(E::MouseMoved((x, y))) => {
                self.last_mouse_pos = Some((x as f64, y as f64));
                let f = self.window.hidpi_factor();
                Some(Input::Move(Motion::MouseCursor(x as f64 / f as f64, y as f64 / f as f64)))
            }
            Some(E::MouseWheel(y)) =>
                Some(Input::Move(Motion::MouseScroll(0.0, y as f64))),
            Some(E::MouseInput(glutin::ElementState::Pressed, button)) =>
                Some(Input::Press(Button::Mouse(map_mouse(button)))),
            Some(E::MouseInput(glutin::ElementState::Released, button)) =>
                Some(Input::Release(Button::Mouse(map_mouse(button)))),
            _ => None,
        }
    }
}

impl Window for GlutinWindow {
    type Event = Input;

    fn size(&self) -> Size {
        if let Some(size) = self.window.get_inner_size() {
            size.into()
        } else {
            (0, 0).into()
        }
    }
    fn draw_size(&self) -> Size {
        let f = self.window.hidpi_factor();
        if let Some((w, h)) = self.window.get_inner_size() {
            ((w as f32 * f) as u32, (h as f32 * f) as u32).into()
        } else {
            (0, 0).into()
        }
    }
    fn should_close(&self) -> bool {
        self.window.is_closed() || self.should_close
    }
    fn swap_buffers(&mut self) { self.window.swap_buffers(); }
    fn poll_event(&mut self) -> Option<Input> { self.poll_event() }
}

impl AdvancedWindow for GlutinWindow {
    fn get_title(&self) -> String { self.title.clone() }
    fn set_title(&mut self, value: String) {
        self.title = value;
        self.window.set_title(&self.title);
    }
    fn get_exit_on_esc(&self) -> bool { self.exit_on_esc }
    fn set_exit_on_esc(&mut self, value: bool) { self.exit_on_esc = value; }
    fn set_capture_cursor(&mut self, value: bool) {
        use glutin::CursorState;
        if value {
            let _ = self.window.set_cursor_state(CursorState::Grab);
        } else {
            let _ = self.window.set_cursor_state(CursorState::Normal);
        }
    }
}

impl OpenGLWindow for GlutinWindow {
    fn get_proc_address(&mut self, proc_name: &str) -> ProcAddress {
        self.window.get_proc_address(proc_name)
    }

    fn is_current(&self) -> bool {
        self.window.is_current()
    }

    fn make_current(&mut self) {
        unsafe {
            self.window.make_current()
        }
    }
}

/// Maps Glutin's key to Piston's key.
pub fn map_key(keycode: glutin::VirtualKeyCode) -> keyboard::Key {
    use input::keyboard::Key;
    use glutin::VirtualKeyCode as K;

    match keycode {
        K::Key0 => Key::D0,
        K::Key1 => Key::D1,
        K::Key2 => Key::D2,
        K::Key3 => Key::D3,
        K::Key4 => Key::D4,
        K::Key5 => Key::D5,
        K::Key6 => Key::D6,
        K::Key7 => Key::D7,
        K::Key8 => Key::D8,
        K::Key9 => Key::D9,
        K::A => Key::A,
        K::B => Key::B,
        K::C => Key::C,
        K::D => Key::D,
        K::E => Key::E,
        K::F => Key::F,
        K::G => Key::G,
        K::H => Key::H,
        K::I => Key::I,
        K::J => Key::J,
        K::K => Key::K,
        K::L => Key::L,
        K::M => Key::M,
        K::N => Key::N,
        K::O => Key::O,
        K::P => Key::P,
        K::Q => Key::Q,
        K::R => Key::R,
        K::S => Key::S,
        K::T => Key::T,
        K::U => Key::U,
        K::V => Key::V,
        K::W => Key::W,
        K::X => Key::X,
        K::Y => Key::Y,
        K::Z => Key::Z,
        K::Apostrophe => Key::Unknown,
        K::Backslash => Key::Backslash,
        K::Back => Key::Backspace,
        // K::CapsLock => Key::CapsLock,
        K::Delete => Key::Delete,
        K::Comma => Key::Comma,
        K::Down => Key::Down,
        K::End => Key::End,
        K::Return => Key::Return,
        K::Equals => Key::Equals,
        K::Escape => Key::Escape,
        K::F1 => Key::F1,
        K::F2 => Key::F2,
        K::F3 => Key::F3,
        K::F4 => Key::F4,
        K::F5 => Key::F5,
        K::F6 => Key::F6,
        K::F7 => Key::F7,
        K::F8 => Key::F8,
        K::F9 => Key::F9,
        K::F10 => Key::F10,
        K::F11 => Key::F11,
        K::F12 => Key::F12,
        K::F13 => Key::F13,
        K::F14 => Key::F14,
        K::F15 => Key::F15,
        // K::F16 => Key::F16,
        // K::F17 => Key::F17,
        // K::F18 => Key::F18,
        // K::F19 => Key::F19,
        // K::F20 => Key::F20,
        // K::F21 => Key::F21,
        // K::F22 => Key::F22,
        // K::F23 => Key::F23,
        // K::F24 => Key::F24,
        // Possibly next code.
        // K::F25 => Key::Unknown,
        K::Numpad0 => Key::NumPad0,
        K::Numpad1 => Key::NumPad1,
        K::Numpad2 => Key::NumPad2,
        K::Numpad3 => Key::NumPad3,
        K::Numpad4 => Key::NumPad4,
        K::Numpad5 => Key::NumPad5,
        K::Numpad6 => Key::NumPad6,
        K::Numpad7 => Key::NumPad7,
        K::Numpad8 => Key::NumPad8,
        K::Numpad9 => Key::NumPad9,
        K::NumpadComma => Key::NumPadDecimal,
        K::Divide => Key::NumPadDivide,
        K::Multiply => Key::NumPadMultiply,
        K::Subtract => Key::NumPadMinus,
        K::Add => Key::NumPadPlus,
        K::NumpadEnter => Key::NumPadEnter,
        K::NumpadEquals => Key::NumPadEquals,
        K::LShift => Key::LShift,
        K::LControl => Key::LCtrl,
        K::LAlt => Key::LAlt,
        K::LMenu => Key::LGui,
        K::RShift => Key::RShift,
        K::RControl => Key::RCtrl,
        K::RAlt => Key::RAlt,
        K::RMenu => Key::RGui,
        // Map to backslash?
        // K::GraveAccent => Key::Unknown,
        K::Home => Key::Home,
        K::Insert => Key::Insert,
        K::Left => Key::Left,
        K::LBracket => Key::LeftBracket,
        // K::Menu => Key::Menu,
        K::Minus => Key::Minus,
        K::Numlock => Key::NumLockClear,
        K::PageDown => Key::PageDown,
        K::PageUp => Key::PageUp,
        K::Pause => Key::Pause,
        K::Period => Key::Period,
        // K::PrintScreen => Key::PrintScreen,
        K::Right => Key::Right,
        K::RBracket => Key::RightBracket,
        // K::ScrollLock => Key::ScrollLock,
        K::Semicolon => Key::Semicolon,
        K::Slash => Key::Slash,
        K::Space => Key::Space,
        K::Tab => Key::Tab,
        K::Up => Key::Up,
        // K::World1 => Key::Unknown,
        // K::World2 => Key::Unknown,
        _ => Key::Unknown,
    }
}

/// Maps Glutin's mouse button to Piston's mouse button.
pub fn map_mouse(mouse_button: glutin::MouseButton) -> MouseButton {
    use glutin::MouseButton as M;

    match mouse_button {
        M::Left => MouseButton::Left,
        M::Right => MouseButton::Right,
        M::Middle => MouseButton::Middle,
        M::Other(0) => MouseButton::X1,
        M::Other(1) => MouseButton::X2,
        M::Other(2) => MouseButton::Button6,
        M::Other(3) => MouseButton::Button7,
        M::Other(4) => MouseButton::Button8,
        _ => MouseButton::Unknown
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Kyle Mayes
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! A micro-benchmarking library.

#![feature(test)]

#![warn(missing_copy_implementations, missing_debug_implementations, missing_docs)]

#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![cfg_attr(feature="clippy", warn(clippy))]
#![cfg_attr(feature="clippy", allow(new_without_default_derive))]

extern crate test;
extern crate time;

use std::time::{Duration};

//================================================
// Structs
//================================================

// Options _______________________________________

/// Micro-benchmarking options.
#[derive(Copy, Clone, Debug)]
pub struct Options {
    factor: f64,
    maximum: u64,
}

impl Default for Options {
    fn default() -> Options {
        Options { factor: 1.01, maximum: 5_000_000_000 }
    }
}

impl Options {
    //- Consumers --------------------------------

    /// Sets the geometric growth factor.
    ///
    /// **Default:** `1.01`
    pub fn factor(mut self, factor: f64) -> Self {
        self.factor = factor;
        self
    }

    /// Sets the maximum amount of time a micro-benchmark will run for.
    ///
    /// **Default:** `Duration::new(5, 0)`
    pub fn maximum(mut self, maximum: Duration) -> Self {
        self.maximum = (maximum.as_secs() * 1_000_000_000) + maximum.subsec_nanos() as u64;
        self
    }
}

// Stopwatch _____________________________________

/// A high-precision stopwatch.
#[derive(Clone, Copy, Debug)]
pub struct Stopwatch {
    start: u64,
}

impl Stopwatch {
    //- Constructors -----------------------------

    /// Constructs a new `Stopwatch`.
    pub fn new() -> Self {
        Stopwatch { start: time::precise_time_ns() }
    }

    //- Accessors --------------------------------

    /// Returns the elapsed nanoseconds since this stopwatch was constructed or reset.
    pub fn elapsed(&self) -> u64 {
        time::precise_time_ns() - self.start
    }

    //- Mutators ---------------------------------

    /// Resets this stopwatch.
    pub fn reset(&mut self) {
        self.start = time::precise_time_ns();
    }
}

//================================================
// Functions
//================================================

/// A function that prevents the optimizer from eliminating the supplied value.
pub fn retain<T>(value: T) -> T {
    test::black_box(value)
}
<commit_msg>Add GeometricSequence struct<commit_after>// Copyright 2016 Kyle Mayes
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! A micro-benchmarking library.

#![feature(test)]

#![warn(missing_copy_implementations, missing_debug_implementations, missing_docs)]

#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![cfg_attr(feature="clippy", warn(clippy))]
#![cfg_attr(feature="clippy", allow(new_without_default_derive))]

extern crate test;
extern crate time;

use std::time::{Duration};

//================================================
// Structs
//================================================

// GeometricSequence _____________________________

/// Generates unique values from a geometric sequence.
#[derive(Copy, Clone, Debug)]
pub struct GeometricSequence {
    current: f64,
    factor: f64,
}

impl GeometricSequence {
    //- Constructors -----------------------------

    /// Constructs a new `GeometricSequence`.
    pub fn new(start: u64, factor: f64) -> Self {
        GeometricSequence { current: start as f64, factor: factor }
    }
}

impl Iterator for GeometricSequence {
    type Item = u64;

    fn next(&mut self) -> Option<Self::Item> {
        let start = self.current as u64;
        while self.current as u64 == start { self.current *= self.factor; }
        Some(start)
    }
}

// Options _______________________________________

/// Micro-benchmarking options.
#[derive(Copy, Clone, Debug)]
pub struct Options {
    factor: f64,
    maximum: u64,
}

impl Default for Options {
    fn default() -> Options {
        Options { factor: 1.01, maximum: 5_000_000_000 }
    }
}

impl Options {
    //- Consumers --------------------------------

    /// Sets the geometric growth factor.
    ///
    /// **Default:** `1.01`
    pub fn factor(mut self, factor: f64) -> Self {
        self.factor = factor;
        self
    }

    /// Sets the maximum amount of time a micro-benchmark will run for.
    ///
    /// **Default:** `Duration::new(5, 0)`
    pub fn maximum(mut self, maximum: Duration) -> Self {
        self.maximum = (maximum.as_secs() * 1_000_000_000) + maximum.subsec_nanos() as u64;
        self
    }
}

// Stopwatch _____________________________________

/// A high-precision stopwatch.
#[derive(Clone, Copy, Debug)]
pub struct Stopwatch {
    start: u64,
}

impl Stopwatch {
    //- Constructors -----------------------------

    /// Constructs a new `Stopwatch`.
    pub fn new() -> Self {
        Stopwatch { start: time::precise_time_ns() }
    }

    //- Accessors --------------------------------

    /// Returns the elapsed nanoseconds since this stopwatch was constructed or reset.
    pub fn elapsed(&self) -> u64 {
        time::precise_time_ns() - self.start
    }

    //- Mutators ---------------------------------

    /// Resets this stopwatch.
    pub fn reset(&mut self) {
        self.start = time::precise_time_ns();
    }
}

//================================================
// Functions
//================================================

/// A function that prevents the optimizer from eliminating the supplied value.
pub fn retain<T>(value: T) -> T {
    test::black_box(value)
}
<|endoftext|>


<commit_before>//! An implementation of random number generator based on `rdrand` instruction.
//!
//! `rdrand` is claimed to be a cryptographically secure PRNG. It is much
//! faster than `OsRng` (and slower than `StdRng`), but is only supported on
//! more recent Intel processors.
//!
//! The generator provided by this crate is a viable replacement to any
//! [std::rand](http://doc.rust-lang.org/std/rand/index.html) generator,
//! however, since nobody has audited Intel hardware yet, the usual disclaimers
//! apply.

#![feature(asm)]
use std::rand::Rng;
use std::result::Result;

struct PrivateInner;
pub struct RdRand(PrivateInner);

#[deriving(Copy)]
#[stable]
pub enum Error {
    /// The processor does not support the `rdrand` instruction.
    UnsupportedProcessor
}

/// Check whether RDRAND instruction is supported
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn is_supported() -> bool {
    const FLAG : u32 = 1 << 30;
    let (mut b, mut c, mut d) : (u32, u32, u32);
    unsafe {
        asm!("
             mov eax, 0;
             cpuid;
             mov $0, ebx;
             mov $1, ecx;
             mov $2, edx;
            "
            : "=r"(b), "=r"(c), "=r"(d)
            :
            : "eax", "ebx", "ecx", "edx"
            : "intel");
    }
    // Genuine Intel
    if b != 0x756E6547 || d != 0x49656e69 || c != 0x6C65746E {
        return false;
    }
    // 30th bit of 1st cpuid function and 0th subfunction is set
    unsafe {
        asm!("
             mov eax, 1;
             mov ecx, 0;
             cpuid;
             mov $0, ecx;
            "
            : "=r"(c)
            :
            : "eax", "ebx", "ecx", "edx"
            : "intel");
    }
    return c & FLAG == FLAG
}

impl RdRand {
    /// Build a generator object. The function will only succeed if `rdrand`
    /// instruction can be successfully used.
    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
    pub fn new() -> Result<RdRand, Error> {
        if is_supported() {
            return Ok(RdRand(PrivateInner));
        } else {
            return Err(Error::UnsupportedProcessor);
        }
    }

    #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
    pub fn new() -> Result<RdRand, Error> {
        Err(Error::UnsupportedProcessor)
    }

    /// Generate a u16 value.
    pub fn next_u16(&mut self) -> u16 {
        let mut var;
        unsafe {
            asm!("rdrand $0" : "=r"(var));
        }
        var
    }
}

impl Rng for RdRand {
    fn next_u32(&mut self) -> u32 {
        let mut var;
        unsafe {
            asm!("rdrand $0" : "=r"(var));
        }
        var
    }

    fn next_u64(&mut self) -> u64 {
        let mut var;
        unsafe {
            asm!("rdrand $0" : "=r"(var));
        }
        var
    }
}
<commit_msg>Add license text<commit_after>// Copyright © 2014, Simonas Kazlauskas <git@kazlauskas.me>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

//! An implementation of random number generator based on `rdrand` instruction.
//!
//! `rdrand` is claimed to be a cryptographically secure PRNG. It is much faster than `OsRng` (and
//! slower than `StdRng`), but is only supported on more recent Intel processors.
//!
//! The generator provided by this crate is a viable replacement to any
//! [std::rand](http://doc.rust-lang.org/std/rand/index.html) generator, however, since nobody has
//! audited Intel hardware yet, the usual disclaimers apply.

#![feature(asm)]
use std::rand::Rng;
use std::result::Result;

struct PrivateInner;
pub struct RdRand(PrivateInner);

#[deriving(Copy)]
#[stable]
pub enum Error {
    /// The processor does not support the `rdrand` instruction.
    UnsupportedProcessor
}

/// Check whether RDRAND instruction is supported
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn is_supported() -> bool {
    const FLAG : u32 = 1 << 30;
    let (mut b, mut c, mut d) : (u32, u32, u32);
    unsafe {
        asm!("
             mov eax, 0;
             cpuid;
             mov $0, ebx;
             mov $1, ecx;
             mov $2, edx;
            "
            : "=r"(b), "=r"(c), "=r"(d)
            :
            : "eax", "ebx", "ecx", "edx"
            : "intel");
    }
    // Genuine Intel
    if b != 0x756E6547 || d != 0x49656e69 || c != 0x6C65746E {
        return false;
    }
    // 30th bit of 1st cpuid function and 0th subfunction is set
    unsafe {
        asm!("
             mov eax, 1;
             mov ecx, 0;
             cpuid;
             mov $0, ecx;
            "
            : "=r"(c)
            :
            : "eax", "ebx", "ecx", "edx"
            : "intel");
    }
    return c & FLAG == FLAG
}

impl RdRand {
    /// Build a generator object. The function will only succeed if `rdrand` instruction can be
    /// successfully used.
    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
    pub fn new() -> Result<RdRand, Error> {
        if is_supported() {
            return Ok(RdRand(PrivateInner));
        } else {
            return Err(Error::UnsupportedProcessor);
        }
    }

    #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
    pub fn new() -> Result<RdRand, Error> {
        Err(Error::UnsupportedProcessor)
    }

    /// Generate a u16 value.
    pub fn next_u16(&mut self) -> u16 {
        let mut var;
        unsafe {
            asm!("rdrand $0" : "=r"(var));
        }
        var
    }
}

impl Rng for RdRand {
    fn next_u32(&mut self) -> u32 {
        let mut var;
        unsafe {
            asm!("rdrand $0" : "=r"(var));
        }
        var
    }

    fn next_u64(&mut self) -> u64 {
        let mut var;
        unsafe {
            asm!("rdrand $0" : "=r"(var));
        }
        var
    }
}
<|endoftext|>


<commit_before>//! Wrapper types to enable optimized handling of `&[u8]` and `Vec<u8>`.
//!
//! Without specialization, Rust forces Serde to treat `&[u8]` just like any
//! other slice and `Vec<u8>` just like any other vector. In reality this
//! particular slice and vector can often be serialized and deserialized in a
//! more efficient, compact representation in many formats.
//!
//! When working with such a format, you can opt into specialized handling of
//! `&[u8]` by wrapping it in `serde_bytes::Bytes` and `Vec<u8>` by wrapping it
//! in `serde_bytes::ByteBuf`.
//!
//! This crate supports the Serde `with` attribute to enable efficient handling
//! of `&[u8]` and `Vec<u8>` in structs without needing a wrapper type.
//!
//! ```rust
//! #[macro_use]
//! extern crate serde_derive;
//!
//! extern crate serde;
//! extern crate serde_bytes;
//!
//! #[derive(Serialize)]
//! struct Efficient<'a> {
//!     #[serde(with = "serde_bytes")]
//!     bytes: &'a [u8],
//!
//!     #[serde(with = "serde_bytes")]
//!     byte_buf: Vec<u8>,
//! }
//!
//! #[derive(Serialize, Deserialize)]
//! struct Packet {
//!     #[serde(with = "serde_bytes")]
//!     payload: Vec<u8>,
//! }
//! #
//! # fn main() {}
//! ```

#![doc(html_root_url = "https://docs.rs/serde_bytes/0.10.3")]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![deny(missing_docs)]

#[cfg(feature = "std")]
use std::{fmt, ops};

#[cfg(not(feature = "std"))]
use core::{fmt, ops};

use self::fmt::Debug;

#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::Vec;

#[macro_use]
extern crate serde;
use serde::ser::{Serialize, Serializer};
use serde::de::{Deserialize, Deserializer, Visitor, Error};

#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::bytebuf::ByteBuf;

mod value;

//////////////////////////////////////////////////////////////////////////////

/// Serde `serialize_with` function to serialize bytes efficiently.
///
/// This function can be used with either of the following Serde attributes:
///
/// - `#[serde(with = "serde_bytes")]`
/// - `#[serde(serialize_with = "serde_bytes::serialize")]`
///
/// ```rust
/// #[macro_use]
/// extern crate serde_derive;
///
/// extern crate serde;
/// extern crate serde_bytes;
///
/// #[derive(Serialize)]
/// struct Efficient<'a> {
///     #[serde(with = "serde_bytes")]
///     bytes: &'a [u8],
///
///     #[serde(with = "serde_bytes")]
///     byte_buf: Vec<u8>,
/// }
/// #
/// # fn main() {}
/// ```
pub fn serialize<T, S>(bytes: &T, serializer: S) -> Result<S::Ok, S::Error>
    where T: AsRef<[u8]>,
          S: Serializer
{
    serializer.serialize_bytes(bytes.as_ref())
}

/// Serde `deserialize_with` function to deserialize bytes efficiently.
///
/// This function can be used with either of the following Serde attributes:
///
/// - `#[serde(with = "serde_bytes")]`
/// - `#[serde(deserialize_with = "serde_bytes::deserialize")]`
///
/// ```rust
/// #[macro_use]
/// extern crate serde_derive;
///
/// extern crate serde;
/// extern crate serde_bytes;
///
/// #[derive(Deserialize)]
/// struct Packet {
///     #[serde(with = "serde_bytes")]
///     payload: Vec<u8>,
/// }
/// #
/// # fn main() {}
/// ```
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
    where T: From<Vec<u8>>,
          D: Deserializer<'de>
{
    ByteBuf::deserialize(deserializer).map(|buf| Into::<Vec<u8>>::into(buf).into())
}

//////////////////////////////////////////////////////////////////////////////

/// Wrapper around `&[u8]` to serialize and deserialize efficiently.
///
/// ```rust
/// extern crate bincode;
/// extern crate serde_bytes;
///
/// use std::collections::HashMap;
/// use std::io;
///
/// use serde_bytes::Bytes;
///
/// fn print_encoded_cache() -> Result<(), bincode::Error> {
///     let mut cache = HashMap::new();
///     cache.insert(3, Bytes::new(b"three"));
///     cache.insert(2, Bytes::new(b"two"));
///     cache.insert(1, Bytes::new(b"one"));
///
///     bincode::serialize_into(&mut io::stdout(), &cache, bincode::Infinite)
/// }
/// #
/// # fn main() {
/// #     print_encoded_cache().unwrap();
/// # }
/// ```
#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct Bytes<'a> {
    bytes: &'a [u8],
}

impl<'a> Bytes<'a> {
    /// Wrap an existing `&[u8]`.
    pub fn new(bytes: &'a [u8]) -> Self {
        Bytes { bytes: bytes }
    }
}

impl<'a> Debug for Bytes<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(self.bytes, f)
    }
}

impl<'a> From<&'a [u8]> for Bytes<'a> {
    fn from(bytes: &'a [u8]) -> Self {
        Bytes::new(bytes)
    }
}

impl<'a> From<Bytes<'a>> for &'a [u8] {
    fn from(wrapper: Bytes<'a>) -> &'a [u8] {
        wrapper.bytes
    }
}

impl<'a> ops::Deref for Bytes<'a> {
    type Target = [u8];

    fn deref(&self) -> &[u8] {
        self.bytes
    }
}

impl<'a> Serialize for Bytes<'a> {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        serializer.serialize_bytes(self.bytes)
    }
}

struct BytesVisitor;

impl<'de> Visitor<'de> for BytesVisitor {
    type Value = Bytes<'de>;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("a borrowed byte array")
    }

    #[inline]
    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Bytes<'de>, E>
        where E: Error
    {
        Ok(Bytes::from(v))
    }

    #[inline]
    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Bytes<'de>, E>
        where E: Error
    {
        Ok(Bytes::from(v.as_bytes()))
    }
}

impl<'a, 'de: 'a> Deserialize<'de> for Bytes<'a> {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Bytes<'a>, D::Error>
        where D: Deserializer<'de>
    {
        deserializer.deserialize_bytes(BytesVisitor)
    }
}

//////////////////////////////////////////////////////////////////////////////

#[cfg(any(feature = "std", feature = "alloc"))]
mod bytebuf {
    #[cfg(feature = "std")]
    use std::{cmp, fmt, ops};

    #[cfg(not(feature = "std"))]
    use core::{cmp, fmt, ops};

    use self::fmt::Debug;

    #[cfg(feature = "alloc")]
    use alloc::{String, Vec};

    use serde::ser::{Serialize, Serializer};
    use serde::de::{Deserialize, Deserializer, Visitor, SeqAccess, Error};

    /// Wrapper around `Vec<u8>` to serialize and deserialize efficiently.
    ///
    /// ```rust
    /// extern crate bincode;
    /// extern crate serde_bytes;
    ///
    /// use std::collections::HashMap;
    /// use std::io;
    ///
    /// use serde_bytes::ByteBuf;
    ///
    /// fn deserialize_bytebufs() -> Result<(), bincode::Error> {
    ///     let example_data = [
    ///         2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 116,
    ///         119, 111, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 111, 110, 101];
    ///
    ///     let map: HashMap<u32, ByteBuf> =
    ///         bincode::deserialize_from(&mut &example_data[..], bincode::Infinite)?;
    ///
    ///     println!("{:?}", map);
    ///
    ///     Ok(())
    /// }
    /// #
    /// # fn main() {
    /// #     deserialize_bytebufs().unwrap();
    /// # }
    /// ```
    #[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
    pub struct ByteBuf {
        bytes: Vec<u8>,
    }

    impl ByteBuf {
        /// Construct a new, empty `ByteBuf`.
        pub fn new() -> Self {
            ByteBuf::from(Vec::new())
        }

        /// Construct a new, empty `ByteBuf` with the specified capacity.
        pub fn with_capacity(cap: usize) -> Self {
            ByteBuf::from(Vec::with_capacity(cap))
        }

        /// Wrap existing bytes in a `ByteBuf`.
        pub fn from<T: Into<Vec<u8>>>(bytes: T) -> Self {
            ByteBuf { bytes: bytes.into() }
        }
    }

    impl Debug for ByteBuf {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            Debug::fmt(&self.bytes, f)
        }
    }

    impl From<ByteBuf> for Vec<u8> {
        fn from(wrapper: ByteBuf) -> Vec<u8> {
            wrapper.bytes
        }
    }

    impl From<Vec<u8>> for ByteBuf {
        fn from(bytes: Vec<u8>) -> Self {
            ByteBuf::from(bytes)
        }
    }

    impl AsRef<Vec<u8>> for ByteBuf {
        fn as_ref(&self) -> &Vec<u8> {
            &self.bytes
        }
    }

    impl AsRef<[u8]> for ByteBuf {
        fn as_ref(&self) -> &[u8] {
            &self.bytes
        }
    }

    impl AsMut<Vec<u8>> for ByteBuf {
        fn as_mut(&mut self) -> &mut Vec<u8> {
            &mut self.bytes
        }
    }

    impl AsMut<[u8]> for ByteBuf {
        fn as_mut(&mut self) -> &mut [u8] {
            &mut self.bytes
        }
    }

    impl ops::Deref for ByteBuf {
        type Target = [u8];

        fn deref(&self) -> &[u8] {
            &self.bytes[..]
        }
    }

    impl ops::DerefMut for ByteBuf {
        fn deref_mut(&mut self) -> &mut [u8] {
            &mut self.bytes[..]
        }
    }

    impl Serialize for ByteBuf {
        #[inline]
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
            where S: Serializer
        {
            serializer.serialize_bytes(&self.bytes)
        }
    }

    struct ByteBufVisitor;

    impl<'de> Visitor<'de> for ByteBufVisitor {
        type Value = ByteBuf;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("byte array")
        }

        #[inline]
        fn visit_seq<V>(self, mut visitor: V) -> Result<ByteBuf, V::Error>
            where V: SeqAccess<'de>
        {
            let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
            let mut values = Vec::with_capacity(len);

            while let Some(value) = try!(visitor.next_element()) {
                values.push(value);
            }

            Ok(ByteBuf::from(values))
        }

        #[inline]
        fn visit_bytes<E>(self, v: &[u8]) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_str<E>(self, v: &str) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_string<E>(self, v: String) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }
    }

    impl<'de> Deserialize<'de> for ByteBuf {
        #[inline]
        fn deserialize<D>(deserializer: D) -> Result<ByteBuf, D::Error>
            where D: Deserializer<'de>
        {
            deserializer.deserialize_byte_buf(ByteBufVisitor)
        }
    }
}
<commit_msg>Allow T: ?Sized in serialize<commit_after>//! Wrapper types to enable optimized handling of `&[u8]` and `Vec<u8>`.
//!
//! Without specialization, Rust forces Serde to treat `&[u8]` just like any
//! other slice and `Vec<u8>` just like any other vector. In reality this
//! particular slice and vector can often be serialized and deserialized in a
//! more efficient, compact representation in many formats.
//!
//! When working with such a format, you can opt into specialized handling of
//! `&[u8]` by wrapping it in `serde_bytes::Bytes` and `Vec<u8>` by wrapping it
//! in `serde_bytes::ByteBuf`.
//!
//! This crate supports the Serde `with` attribute to enable efficient handling
//! of `&[u8]` and `Vec<u8>` in structs without needing a wrapper type.
//!
//! ```rust
//! #[macro_use]
//! extern crate serde_derive;
//!
//! extern crate serde;
//! extern crate serde_bytes;
//!
//! #[derive(Serialize)]
//! struct Efficient<'a> {
//!     #[serde(with = "serde_bytes")]
//!     bytes: &'a [u8],
//!
//!     #[serde(with = "serde_bytes")]
//!     byte_buf: Vec<u8>,
//! }
//!
//! #[derive(Serialize, Deserialize)]
//! struct Packet {
//!     #[serde(with = "serde_bytes")]
//!     payload: Vec<u8>,
//! }
//! #
//! # fn main() {}
//! ```

#![doc(html_root_url = "https://docs.rs/serde_bytes/0.10.3")]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![deny(missing_docs)]

#[cfg(feature = "std")]
use std::{fmt, ops};

#[cfg(not(feature = "std"))]
use core::{fmt, ops};

use self::fmt::Debug;

#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::Vec;

#[macro_use]
extern crate serde;
use serde::ser::{Serialize, Serializer};
use serde::de::{Deserialize, Deserializer, Visitor, Error};

#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::bytebuf::ByteBuf;

mod value;

//////////////////////////////////////////////////////////////////////////////

/// Serde `serialize_with` function to serialize bytes efficiently.
///
/// This function can be used with either of the following Serde attributes:
///
/// - `#[serde(with = "serde_bytes")]`
/// - `#[serde(serialize_with = "serde_bytes::serialize")]`
///
/// ```rust
/// #[macro_use]
/// extern crate serde_derive;
///
/// extern crate serde;
/// extern crate serde_bytes;
///
/// #[derive(Serialize)]
/// struct Efficient<'a> {
///     #[serde(with = "serde_bytes")]
///     bytes: &'a [u8],
///
///     #[serde(with = "serde_bytes")]
///     byte_buf: Vec<u8>,
/// }
/// #
/// # fn main() {}
/// ```
pub fn serialize<T, S>(bytes: &T, serializer: S) -> Result<S::Ok, S::Error>
    where T: ?Sized + AsRef<[u8]>,
          S: Serializer
{
    serializer.serialize_bytes(bytes.as_ref())
}

/// Serde `deserialize_with` function to deserialize bytes efficiently.
///
/// This function can be used with either of the following Serde attributes:
///
/// - `#[serde(with = "serde_bytes")]`
/// - `#[serde(deserialize_with = "serde_bytes::deserialize")]`
///
/// ```rust
/// #[macro_use]
/// extern crate serde_derive;
///
/// extern crate serde;
/// extern crate serde_bytes;
///
/// #[derive(Deserialize)]
/// struct Packet {
///     #[serde(with = "serde_bytes")]
///     payload: Vec<u8>,
/// }
/// #
/// # fn main() {}
/// ```
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
    where T: From<Vec<u8>>,
          D: Deserializer<'de>
{
    ByteBuf::deserialize(deserializer).map(|buf| Into::<Vec<u8>>::into(buf).into())
}

//////////////////////////////////////////////////////////////////////////////

/// Wrapper around `&[u8]` to serialize and deserialize efficiently.
///
/// ```rust
/// extern crate bincode;
/// extern crate serde_bytes;
///
/// use std::collections::HashMap;
/// use std::io;
///
/// use serde_bytes::Bytes;
///
/// fn print_encoded_cache() -> Result<(), bincode::Error> {
///     let mut cache = HashMap::new();
///     cache.insert(3, Bytes::new(b"three"));
///     cache.insert(2, Bytes::new(b"two"));
///     cache.insert(1, Bytes::new(b"one"));
///
///     bincode::serialize_into(&mut io::stdout(), &cache, bincode::Infinite)
/// }
/// #
/// # fn main() {
/// #     print_encoded_cache().unwrap();
/// # }
/// ```
#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct Bytes<'a> {
    bytes: &'a [u8],
}

impl<'a> Bytes<'a> {
    /// Wrap an existing `&[u8]`.
    pub fn new(bytes: &'a [u8]) -> Self {
        Bytes { bytes: bytes }
    }
}

impl<'a> Debug for Bytes<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(self.bytes, f)
    }
}

impl<'a> From<&'a [u8]> for Bytes<'a> {
    fn from(bytes: &'a [u8]) -> Self {
        Bytes::new(bytes)
    }
}

impl<'a> From<Bytes<'a>> for &'a [u8] {
    fn from(wrapper: Bytes<'a>) -> &'a [u8] {
        wrapper.bytes
    }
}

impl<'a> ops::Deref for Bytes<'a> {
    type Target = [u8];

    fn deref(&self) -> &[u8] {
        self.bytes
    }
}

impl<'a> Serialize for Bytes<'a> {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        serializer.serialize_bytes(self.bytes)
    }
}

struct BytesVisitor;

impl<'de> Visitor<'de> for BytesVisitor {
    type Value = Bytes<'de>;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("a borrowed byte array")
    }

    #[inline]
    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Bytes<'de>, E>
        where E: Error
    {
        Ok(Bytes::from(v))
    }

    #[inline]
    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Bytes<'de>, E>
        where E: Error
    {
        Ok(Bytes::from(v.as_bytes()))
    }
}

impl<'a, 'de: 'a> Deserialize<'de> for Bytes<'a> {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Bytes<'a>, D::Error>
        where D: Deserializer<'de>
    {
        deserializer.deserialize_bytes(BytesVisitor)
    }
}

//////////////////////////////////////////////////////////////////////////////

#[cfg(any(feature = "std", feature = "alloc"))]
mod bytebuf {
    #[cfg(feature = "std")]
    use std::{cmp, fmt, ops};

    #[cfg(not(feature = "std"))]
    use core::{cmp, fmt, ops};

    use self::fmt::Debug;

    #[cfg(feature = "alloc")]
    use alloc::{String, Vec};

    use serde::ser::{Serialize, Serializer};
    use serde::de::{Deserialize, Deserializer, Visitor, SeqAccess, Error};

    /// Wrapper around `Vec<u8>` to serialize and deserialize efficiently.
    ///
    /// ```rust
    /// extern crate bincode;
    /// extern crate serde_bytes;
    ///
    /// use std::collections::HashMap;
    /// use std::io;
    ///
    /// use serde_bytes::ByteBuf;
    ///
    /// fn deserialize_bytebufs() -> Result<(), bincode::Error> {
    ///     let example_data = [
    ///         2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 116,
    ///         119, 111, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 111, 110, 101];
    ///
    ///     let map: HashMap<u32, ByteBuf> =
    ///         bincode::deserialize_from(&mut &example_data[..], bincode::Infinite)?;
    ///
    ///     println!("{:?}", map);
    ///
    ///     Ok(())
    /// }
    /// #
    /// # fn main() {
    /// #     deserialize_bytebufs().unwrap();
    /// # }
    /// ```
    #[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
    pub struct ByteBuf {
        bytes: Vec<u8>,
    }

    impl ByteBuf {
        /// Construct a new, empty `ByteBuf`.
        pub fn new() -> Self {
            ByteBuf::from(Vec::new())
        }

        /// Construct a new, empty `ByteBuf` with the specified capacity.
        pub fn with_capacity(cap: usize) -> Self {
            ByteBuf::from(Vec::with_capacity(cap))
        }

        /// Wrap existing bytes in a `ByteBuf`.
        pub fn from<T: Into<Vec<u8>>>(bytes: T) -> Self {
            ByteBuf { bytes: bytes.into() }
        }
    }

    impl Debug for ByteBuf {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            Debug::fmt(&self.bytes, f)
        }
    }

    impl From<ByteBuf> for Vec<u8> {
        fn from(wrapper: ByteBuf) -> Vec<u8> {
            wrapper.bytes
        }
    }

    impl From<Vec<u8>> for ByteBuf {
        fn from(bytes: Vec<u8>) -> Self {
            ByteBuf::from(bytes)
        }
    }

    impl AsRef<Vec<u8>> for ByteBuf {
        fn as_ref(&self) -> &Vec<u8> {
            &self.bytes
        }
    }

    impl AsRef<[u8]> for ByteBuf {
        fn as_ref(&self) -> &[u8] {
            &self.bytes
        }
    }

    impl AsMut<Vec<u8>> for ByteBuf {
        fn as_mut(&mut self) -> &mut Vec<u8> {
            &mut self.bytes
        }
    }

    impl AsMut<[u8]> for ByteBuf {
        fn as_mut(&mut self) -> &mut [u8] {
            &mut self.bytes
        }
    }

    impl ops::Deref for ByteBuf {
        type Target = [u8];

        fn deref(&self) -> &[u8] {
            &self.bytes[..]
        }
    }

    impl ops::DerefMut for ByteBuf {
        fn deref_mut(&mut self) -> &mut [u8] {
            &mut self.bytes[..]
        }
    }

    impl Serialize for ByteBuf {
        #[inline]
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
            where S: Serializer
        {
            serializer.serialize_bytes(&self.bytes)
        }
    }

    struct ByteBufVisitor;

    impl<'de> Visitor<'de> for ByteBufVisitor {
        type Value = ByteBuf;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("byte array")
        }

        #[inline]
        fn visit_seq<V>(self, mut visitor: V) -> Result<ByteBuf, V::Error>
            where V: SeqAccess<'de>
        {
            let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
            let mut values = Vec::with_capacity(len);

            while let Some(value) = try!(visitor.next_element()) {
                values.push(value);
            }

            Ok(ByteBuf::from(values))
        }

        #[inline]
        fn visit_bytes<E>(self, v: &[u8]) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_str<E>(self, v: &str) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }

        #[inline]
        fn visit_string<E>(self, v: String) -> Result<ByteBuf, E>
            where E: Error
        {
            Ok(ByteBuf::from(v))
        }
    }

    impl<'de> Deserialize<'de> for ByteBuf {
        #[inline]
        fn deserialize<D>(deserializer: D) -> Result<ByteBuf, D::Error>
            where D: Deserializer<'de>
        {
            deserializer.deserialize_byte_buf(ByteBufVisitor)
        }
    }
}
<|endoftext|>


<commit_before>#![crate_name = "neovim"]
#![crate_type = "lib"]
#![crate_type = "rlib"]

extern crate libc;

#[cfg(target_os="macos")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    #[link(name = "iconv")]
    extern{}
}

#[doc(hidden)]
#[cfg(target_os="linux")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

mod ffi {
    use libc::{c_char, c_int};

    extern "C" {
        pub fn nvim_main (argc: c_int, argv: *const *const c_char) -> c_int;
    }
}

pub fn nvim_main() -> i32 {
    unsafe {
        let args = ["nvim".to_c_str().as_ptr()];
        ffi::nvim_main(args.len() as i32, args.as_ptr())
    }
}
<commit_msg>Add Channel<commit_after>#![crate_name = "neovim"]
#![crate_type = "lib"]
#![crate_type = "rlib"]

extern crate libc;

#[cfg(target_os="macos")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    #[link(name = "iconv")]
    extern{}
}

#[doc(hidden)]
#[cfg(target_os="linux")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

mod ffi {
    pub use libc::{c_char, c_int, uint64_t};

    extern "C" {
        pub fn nvim_main (argc: c_int, argv: *const *const c_char) -> c_int;
        pub fn channel_from_fds (read_fd: c_int, write_fd: c_int) -> uint64_t;
        pub fn channel_subscribe (id: uint64_t, event: *const c_char);
    }
}

pub fn nvim_main() -> i32 {
    unsafe {
        let args = ["nvim".to_c_str().as_ptr()];
        ffi::nvim_main(args.len() as i32, args.as_ptr())
    }
}

pub struct Channel {
    id: ffi::uint64_t
}

impl Channel {
    pub fn new(read_fd: i32, write_fd: i32) -> Channel {
        Channel {
            id: unsafe { ffi::channel_from_fds(read_fd, write_fd) }
        }
    }

    pub fn subscribe(&mut self, event: &str) {
        unsafe { ffi::channel_subscribe(self.id, event.to_c_str().as_ptr()) }
    }
}
<|endoftext|>


<commit_before>use std::num;
use std::str;
use std::fmt;
use std::io;
use std::io::Read;
use std::io::Write;

const MAX_PARAMS_SIZE: usize = 1024;
const FILE_MAGICK: &'static [u8] = b"YUV4MPEG2 ";
const FRAME_MAGICK: &'static [u8] = b"FRAME";
const TERMINATOR: u8 = 0x0A;
const SEPARATOR: u8 = b' ';

/// Both encoding and decoding errors.
#[derive(Debug)]
pub enum Error {
    /// End of the file. Technically not an error, but it's easier to process
    /// that way.
    EOF,
    // TODO(Kagami): Better granularity of parse errors.
    ParseError,
    IoError(io::Error),
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error { Error::IoError(err) }
}

impl From<num::ParseIntError> for Error {
    fn from(_: num::ParseIntError) -> Error { Error::ParseError }
}

impl From<str::Utf8Error> for Error {
    fn from(_: str::Utf8Error) -> Error { Error::ParseError }
}

trait EnhancedRead {
    fn read_until(&mut self, ch: u8, buf: &mut [u8]) -> Result<usize, Error>;
    // While Read::read_exact is unstable.
    fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>;
}

impl<R: Read> EnhancedRead for R {
    // Current implementation does one `read` call per byte. This might be a
    // bit slow for long headers but it simplifies things: we don't need to
    // check whether start of the next frame is already read and so on.
    fn read_until(&mut self, ch: u8, buf: &mut [u8]) -> Result<usize, Error> {
        let mut collected = 0;
        while collected < buf.len() {
            let chunk_size = try!(self.read(&mut buf[collected..collected+1]));
            if chunk_size == 0 {
                return Err(Error::EOF);
            }
            if buf[collected] == ch {
                return Ok(collected);
            }
            collected += chunk_size;
        }
        Err(Error::ParseError)
    }

    fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error> {
        let mut collected = 0;
        while collected < buf.len() {
            let chunk_size = try!(self.read(&mut buf[collected..]));
            if chunk_size == 0 {
                return Err(Error::EOF);
            }
            collected += chunk_size;
        }
        Ok(())
    }
}

fn parse_bytes(buf: &[u8]) -> Result<usize, Error> {
    // A bit kludgy but seems like there is no other way.
    Ok(try!(try!(str::from_utf8(buf)).parse()))
}

/// **NOTE:** Only 8-bit formats are currently supported.
///
/// > yuv4mpeg can only handle yuv444p, yuv422p, yuv420p, yuv411p and gray8
/// pixel formats. And using 'strict -1' also yuv444p9, yuv422p9, yuv420p9,
/// yuv444p10, yuv422p10, yuv420p10, yuv444p12, yuv422p12, yuv420p12,
/// yuv444p14, yuv422p14, yuv420p14, yuv444p16, yuv422p16, yuv420p16 and gray16
/// pixel formats.
///
/// (c) ffmpeg.
#[derive(Debug, Clone, Copy)]
pub enum Colorspace {
    Cmono,
    C420,
    C422,
    C444,
    C420jpeg,
    C420paldv,
    /// Found in some files.
    C420mpeg2,
}

pub struct Decoder<'d, R: Read + 'd> {
    reader: &'d mut R,
    params_buf: Vec<u8>,
    frame_buf: Vec<u8>,
    raw_params: Vec<u8>,
    width: usize,
    height: usize,
    colorspace: Option<Colorspace>,
    y_len: usize,
    u_len: usize,
}

impl<'d, R: Read> fmt::Debug for Decoder<'d, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "y4m::Decoder<w={}, h={}>", self.width, self.height)
    }
}

impl<'d, R: Read> Decoder<'d, R> {
    pub fn new(reader: &mut R) -> Result<Decoder<R>, Error> {
        let mut params_buf = vec![0;MAX_PARAMS_SIZE];
        let end_params_pos = try!(reader.read_until(TERMINATOR, &mut params_buf));
        if end_params_pos < FILE_MAGICK.len() || !params_buf.starts_with(FILE_MAGICK) {
            return Err(Error::ParseError);
        }
        let raw_params = (&params_buf[FILE_MAGICK.len()..end_params_pos]).to_owned();
        let mut width = 0;
        let mut height = 0;
        let mut csp = None;
        // We shouldn't convert it to string because encoding is unspecified.
        for param in raw_params.split(|&b| b == SEPARATOR) {
            if param.len() < 1 { continue }
            let (name, value) = (param[0], &param[1..]);
            // TODO(Kagami): frame rate, interlacing, pixel aspect, comment.
            match name {
                b'W' => { width = try!(parse_bytes(value)) },
                b'H' => { height = try!(parse_bytes(value)) },
                b'C' => {
                    csp = match value {
                        b"mono" => Some(Colorspace::Cmono),
                        b"420" => Some(Colorspace::C420),
                        b"422" => Some(Colorspace::C422),
                        b"444" => Some(Colorspace::C444),
                        b"420jpeg" => Some(Colorspace::C420jpeg),
                        b"420paldv" => Some(Colorspace::C420paldv),
                        b"420mpeg2" => Some(Colorspace::C420mpeg2),
                        _ => None,
                    };
                },
                _ => {},
            }
        }
        if width == 0 || height == 0 { return Err(Error::ParseError) }
        let (y_len, u_len, v_len) = Self::get_plane_sizes(width, height, &csp);
        let frame_size = y_len + u_len + v_len;
        let frame_buf = vec![0;frame_size];
        Ok(Decoder {
            reader: reader,
            params_buf: params_buf,
            frame_buf: frame_buf,
            raw_params: raw_params,
            width: width,
            height: height,
            colorspace: csp,
            y_len: y_len,
            u_len: u_len,
        })
    }

    fn get_plane_sizes(
        width: usize, height: usize, colorspace: &Option<Colorspace>,
    ) -> (usize, usize, usize) {
        let pixels = width * height;
        let c420_sizes = (pixels, pixels/4, pixels/4);
        match *colorspace {
            Some(Colorspace::Cmono) => (pixels, 0, 0),
            Some(Colorspace::C420) => c420_sizes,
            Some(Colorspace::C422) => (pixels, pixels/2, pixels/2),
            Some(Colorspace::C444) => (pixels, pixels, pixels),
            Some(Colorspace::C420jpeg) => c420_sizes,
            Some(Colorspace::C420paldv) => c420_sizes,
            Some(Colorspace::C420mpeg2) => c420_sizes,
            None => c420_sizes,
        }
    }

    /// Iterate over frames, without extra heap allocations. End of input is
    /// indicated by `Error::EOF`.
    pub fn read_frame(&mut self) -> Result<Frame, Error> {
        let end_params_pos = try!(self.reader.read_until(TERMINATOR, &mut self.params_buf));
        if end_params_pos < FRAME_MAGICK.len() || !self.params_buf.starts_with(FRAME_MAGICK) {
            return Err(Error::ParseError);
        }
        // We don't parse frame params currently but user has access to them.
        let start_params_pos = FRAME_MAGICK.len();
        let raw_params = if end_params_pos - start_params_pos > 0 {
            // Check for extra space.
            if self.params_buf[start_params_pos] != SEPARATOR {
                return Err(Error::ParseError);
            }
            Some((&self.params_buf[start_params_pos+1..end_params_pos]).to_owned())
        } else {
            None
        };
        try!(self.reader.read_exact(&mut self.frame_buf));
        Ok(Frame::new([
            &self.frame_buf[0..self.y_len],
            &self.frame_buf[self.y_len..self.y_len+self.u_len],
            &self.frame_buf[self.y_len+self.u_len..],
        ], raw_params))
    }

    #[inline]
    pub fn get_width(&self) -> usize { self.width }
    #[inline]
    pub fn get_height(&self) -> usize { self.height }
    /// Return file colorspace.
    ///
    /// **NOTE:** normally all .y4m should have colorspace param, but there are
    /// files encoded without that tag and it's unclear what should we do in
    /// that case. Currently C420 is implied by default as per ffmpeg behavior.
    #[inline]
    pub fn get_colorspace(&self) -> Option<Colorspace> { self.colorspace }
    #[inline]
    pub fn get_raw_params(&self) -> &[u8] { &self.raw_params }
}

#[derive(Debug)]
pub struct Frame<'f> {
    planes: [&'f [u8];3],
    raw_params: Option<Vec<u8>>,
}

impl<'f> Frame<'f> {
    /// Create a new frame with optional parameters.
    /// No heap allocations are made.
    pub fn new(planes: [&'f [u8];3], raw_params: Option<Vec<u8>>) -> Frame<'f> {
        Frame {planes: planes, raw_params: raw_params}
    }

    #[inline]
    pub fn get_y_plane(&self) -> &[u8] { self.planes[0] }
    #[inline]
    pub fn get_u_plane(&self) -> &[u8] { self.planes[1] }
    #[inline]
    pub fn get_v_plane(&self) -> &[u8] { self.planes[2] }
    #[inline]
    pub fn get_raw_params(&self) -> Option<&[u8]> { self.raw_params.as_ref().map(|v| &v[..]) }
}

/// Encoder builder. Allows to set y4m file parameters using builder pattern.
// TODO(Kagami): Accept all known tags and raw params.
#[derive(Debug)]
pub struct EncoderBuilder {
    width: usize,
    height: usize,
    colorspace: Option<Colorspace>,
}

impl EncoderBuilder {
    /// Create a new encoder builder.
    pub fn new(width: usize, height: usize) -> EncoderBuilder {
        EncoderBuilder {
            width: width,
            height: height,
            colorspace: None,
        }
    }

    /// Specify file colorspace.
    pub fn with_colorspace(mut self, colorspace: Colorspace) -> Self {
        self.colorspace = Some(colorspace);
        self
    }

    /// Write header to the stream and create encoder instance.
    pub fn write_header<W: Write>(self, writer: &mut W) -> Result<Encoder<W>, Error> {
        // XXX(Kagami): Beware that FILE_MAGICK already contains space.
        try!(writer.write_all(FILE_MAGICK));
        try!(write!(writer, "W{} H{}", self.width, self.height));
        match self.colorspace {
            Some(csp) => try!(write!(writer, " {:?}", csp)),
            _ => {},
        }
        try!(writer.write_all(&[TERMINATOR]));
        Ok(Encoder {
            writer: writer,
        })
    }
}

pub struct Encoder<'e, W: Write + 'e> {
    writer: &'e mut W,
}

impl<'e, W: Write> fmt::Debug for Encoder<'e, W> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "y4m::Encoder")
    }
}

impl<'e, W: Write> Encoder<'e, W> {
    /// Write next frame to the stream.
    pub fn write_frame(&mut self, frame: &Frame) -> Result<(), Error> {
        try!(self.writer.write_all(FRAME_MAGICK));
        match frame.get_raw_params() {
            Some(params) => {
                try!(self.writer.write_all(&[SEPARATOR]));
                try!(self.writer.write_all(params));
            },
            _ => {},
        }
        try!(self.writer.write_all(&[TERMINATOR]));
        try!(self.writer.write_all(frame.get_y_plane()));
        try!(self.writer.write_all(frame.get_u_plane()));
        try!(self.writer.write_all(frame.get_v_plane()));
        Ok(())
    }
}

/// Create a new decoder instance. Alias for `Decoder::new`.
pub fn decode<R: Read>(reader: &mut R) -> Result<Decoder<R>, Error> {
    Decoder::new(reader)
}

/// Create a new encoder builder. Alias for `EncoderBuilder::new`.
pub fn encode(width: usize, height: usize) -> EncoderBuilder {
    EncoderBuilder::new(width, height)
}
<commit_msg>Check plane sizes in write_frame<commit_after>use std::num;
use std::str;
use std::fmt;
use std::io;
use std::io::Read;
use std::io::Write;

const MAX_PARAMS_SIZE: usize = 1024;
const FILE_MAGICK: &'static [u8] = b"YUV4MPEG2 ";
const FRAME_MAGICK: &'static [u8] = b"FRAME";
const TERMINATOR: u8 = 0x0A;
const SEPARATOR: u8 = b' ';

/// Both encoding and decoding errors.
#[derive(Debug)]
pub enum Error {
    /// End of the file. Technically not an error, but it's easier to process
    /// that way.
    EOF,
    /// Bad input parameters provided.
    BadInput,
    /// Error while parsing the file/frame header.
    // TODO(Kagami): Better granularity of parse errors.
    ParseError,
    /// Error while reading/writing the file.
    IoError(io::Error),
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error { Error::IoError(err) }
}

impl From<num::ParseIntError> for Error {
    fn from(_: num::ParseIntError) -> Error { Error::ParseError }
}

impl From<str::Utf8Error> for Error {
    fn from(_: str::Utf8Error) -> Error { Error::ParseError }
}

trait EnhancedRead {
    fn read_until(&mut self, ch: u8, buf: &mut [u8]) -> Result<usize, Error>;
    // While Read::read_exact is unstable.
    fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>;
}

impl<R: Read> EnhancedRead for R {
    // Current implementation does one `read` call per byte. This might be a
    // bit slow for long headers but it simplifies things: we don't need to
    // check whether start of the next frame is already read and so on.
    fn read_until(&mut self, ch: u8, buf: &mut [u8]) -> Result<usize, Error> {
        let mut collected = 0;
        while collected < buf.len() {
            let chunk_size = try!(self.read(&mut buf[collected..collected+1]));
            if chunk_size == 0 {
                return Err(Error::EOF);
            }
            if buf[collected] == ch {
                return Ok(collected);
            }
            collected += chunk_size;
        }
        Err(Error::ParseError)
    }

    fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error> {
        let mut collected = 0;
        while collected < buf.len() {
            let chunk_size = try!(self.read(&mut buf[collected..]));
            if chunk_size == 0 {
                return Err(Error::EOF);
            }
            collected += chunk_size;
        }
        Ok(())
    }
}

fn parse_bytes(buf: &[u8]) -> Result<usize, Error> {
    // A bit kludgy but seems like there is no other way.
    Ok(try!(try!(str::from_utf8(buf)).parse()))
}

/// Simple Ratio structure since it's not available in stdlib.
#[derive(Debug, Clone, Copy)]
pub struct Ratio {
    num: usize,
    den: usize,
}

impl Ratio {
    pub fn new(num: usize, den: usize) -> Ratio {
        Ratio {num: num, den: den}
    }
}

/// **NOTE:** Only 8-bit formats are currently supported.
///
/// > yuv4mpeg can only handle yuv444p, yuv422p, yuv420p, yuv411p and gray8
/// pixel formats. And using 'strict -1' also yuv444p9, yuv422p9, yuv420p9,
/// yuv444p10, yuv422p10, yuv420p10, yuv444p12, yuv422p12, yuv420p12,
/// yuv444p14, yuv422p14, yuv420p14, yuv444p16, yuv422p16, yuv420p16 and gray16
/// pixel formats.
///
/// (c) ffmpeg.
#[derive(Debug, Clone, Copy)]
pub enum Colorspace {
    Cmono,
    C420,
    C422,
    C444,
    C420jpeg,
    C420paldv,
    /// Found in some files.
    C420mpeg2,
}

fn get_plane_sizes(
    width: usize, height: usize, colorspace: Option<Colorspace>,
) -> (usize, usize, usize) {
    let pixels = width * height;
    let c420_sizes = (pixels, pixels/4, pixels/4);
    match colorspace {
        Some(Colorspace::Cmono) => (pixels, 0, 0),
        Some(Colorspace::C420) => c420_sizes,
        Some(Colorspace::C422) => (pixels, pixels/2, pixels/2),
        Some(Colorspace::C444) => (pixels, pixels, pixels),
        Some(Colorspace::C420jpeg) => c420_sizes,
        Some(Colorspace::C420paldv) => c420_sizes,
        Some(Colorspace::C420mpeg2) => c420_sizes,
        None => c420_sizes,
    }
}

pub struct Decoder<'d, R: Read + 'd> {
    reader: &'d mut R,
    params_buf: Vec<u8>,
    frame_buf: Vec<u8>,
    raw_params: Vec<u8>,
    width: usize,
    height: usize,
    framerate: Ratio,
    colorspace: Option<Colorspace>,
    y_len: usize,
    u_len: usize,
}

impl<'d, R: Read> fmt::Debug for Decoder<'d, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "y4m::Decoder<w={}, h={}>", self.width, self.height)
    }
}

impl<'d, R: Read> Decoder<'d, R> {
    pub fn new(reader: &mut R) -> Result<Decoder<R>, Error> {
        let mut params_buf = vec![0;MAX_PARAMS_SIZE];
        let end_params_pos = try!(reader.read_until(TERMINATOR, &mut params_buf));
        if end_params_pos < FILE_MAGICK.len() || !params_buf.starts_with(FILE_MAGICK) {
            return Err(Error::ParseError);
        }
        let raw_params = (&params_buf[FILE_MAGICK.len()..end_params_pos]).to_owned();
        let mut width = 0;
        let mut height = 0;
        let mut fps = Ratio::new(0, 0);
        let mut csp = None;
        // We shouldn't convert it to string because encoding is unspecified.
        for param in raw_params.split(|&b| b == SEPARATOR) {
            if param.len() < 1 { continue }
            let (name, value) = (param[0], &param[1..]);
            // TODO(Kagami): frame rate, interlacing, pixel aspect, comment.
            match name {
                b'W' => { width = try!(parse_bytes(value)) },
                b'H' => { height = try!(parse_bytes(value)) },
                b'F' => {

                },
                b'C' => {
                    csp = match value {
                        b"mono" => Some(Colorspace::Cmono),
                        b"420" => Some(Colorspace::C420),
                        b"422" => Some(Colorspace::C422),
                        b"444" => Some(Colorspace::C444),
                        b"420jpeg" => Some(Colorspace::C420jpeg),
                        b"420paldv" => Some(Colorspace::C420paldv),
                        b"420mpeg2" => Some(Colorspace::C420mpeg2),
                        _ => None,
                    };
                },
                _ => {},
            }
        }
        if width == 0 || height == 0 { return Err(Error::ParseError) }
        let (y_len, u_len, v_len) = get_plane_sizes(width, height, csp);
        let frame_size = y_len + u_len + v_len;
        let frame_buf = vec![0;frame_size];
        Ok(Decoder {
            reader: reader,
            params_buf: params_buf,
            frame_buf: frame_buf,
            raw_params: raw_params,
            width: width,
            height: height,
            framerate: fps,
            colorspace: csp,
            y_len: y_len,
            u_len: u_len,
        })
    }

    /// Iterate over frames, without extra heap allocations. End of input is
    /// indicated by `Error::EOF`.
    pub fn read_frame(&mut self) -> Result<Frame, Error> {
        let end_params_pos = try!(self.reader.read_until(TERMINATOR, &mut self.params_buf));
        if end_params_pos < FRAME_MAGICK.len() || !self.params_buf.starts_with(FRAME_MAGICK) {
            return Err(Error::ParseError);
        }
        // We don't parse frame params currently but user has access to them.
        let start_params_pos = FRAME_MAGICK.len();
        let raw_params = if end_params_pos - start_params_pos > 0 {
            // Check for extra space.
            if self.params_buf[start_params_pos] != SEPARATOR {
                return Err(Error::ParseError);
            }
            Some((&self.params_buf[start_params_pos+1..end_params_pos]).to_owned())
        } else {
            None
        };
        try!(self.reader.read_exact(&mut self.frame_buf));
        Ok(Frame::new([
            &self.frame_buf[0..self.y_len],
            &self.frame_buf[self.y_len..self.y_len+self.u_len],
            &self.frame_buf[self.y_len+self.u_len..],
        ], raw_params))
    }

    #[inline]
    pub fn get_width(&self) -> usize { self.width }
    #[inline]
    pub fn get_height(&self) -> usize { self.height }
    #[inline]
    pub fn get_framerate(&self) -> Ratio { self.framerate }
    /// Return file colorspace.
    ///
    /// **NOTE:** normally all .y4m should have colorspace param, but there are
    /// files encoded without that tag and it's unclear what should we do in
    /// that case. Currently C420 is implied by default as per ffmpeg behavior.
    #[inline]
    pub fn get_colorspace(&self) -> Option<Colorspace> { self.colorspace }
    #[inline]
    pub fn get_raw_params(&self) -> &[u8] { &self.raw_params }
}

#[derive(Debug)]
pub struct Frame<'f> {
    planes: [&'f [u8];3],
    raw_params: Option<Vec<u8>>,
}

impl<'f> Frame<'f> {
    /// Create a new frame with optional parameters.
    /// No heap allocations are made.
    pub fn new(planes: [&'f [u8];3], raw_params: Option<Vec<u8>>) -> Frame<'f> {
        Frame {planes: planes, raw_params: raw_params}
    }

    #[inline]
    pub fn get_y_plane(&self) -> &[u8] { self.planes[0] }
    #[inline]
    pub fn get_u_plane(&self) -> &[u8] { self.planes[1] }
    #[inline]
    pub fn get_v_plane(&self) -> &[u8] { self.planes[2] }
    #[inline]
    pub fn get_raw_params(&self) -> Option<&[u8]> { self.raw_params.as_ref().map(|v| &v[..]) }
}

/// Encoder builder. Allows to set y4m file parameters using builder pattern.
// TODO(Kagami): Accept all known tags and raw params.
#[derive(Debug)]
pub struct EncoderBuilder {
    width: usize,
    height: usize,
    colorspace: Option<Colorspace>,
}

impl EncoderBuilder {
    /// Create a new encoder builder.
    pub fn new(width: usize, height: usize) -> EncoderBuilder {
        EncoderBuilder {
            width: width,
            height: height,
            colorspace: None,
        }
    }

    /// Specify file colorspace.
    pub fn with_colorspace(mut self, colorspace: Colorspace) -> Self {
        self.colorspace = Some(colorspace);
        self
    }

    /// Write header to the stream and create encoder instance.
    pub fn write_header<W: Write>(self, writer: &mut W) -> Result<Encoder<W>, Error> {
        // XXX(Kagami): Beware that FILE_MAGICK already contains space.
        try!(writer.write_all(FILE_MAGICK));
        try!(write!(writer, "W{} H{}", self.width, self.height));
        match self.colorspace {
            Some(csp) => try!(write!(writer, " {:?}", csp)),
            _ => {},
        }
        try!(writer.write_all(&[TERMINATOR]));
        let (y_len, u_len, v_len) = get_plane_sizes(self.width, self.height, self.colorspace);
        Ok(Encoder {
            writer: writer,
            y_len: y_len,
            u_len: u_len,
            v_len: v_len,
        })
    }
}

pub struct Encoder<'e, W: Write + 'e> {
    writer: &'e mut W,
    y_len: usize,
    u_len: usize,
    v_len: usize,
}

impl<'e, W: Write> fmt::Debug for Encoder<'e, W> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "y4m::Encoder")
    }
}

impl<'e, W: Write> Encoder<'e, W> {
    /// Write next frame to the stream.
    pub fn write_frame(&mut self, frame: &Frame) -> Result<(), Error> {
        if frame.get_y_plane().len() != self.y_len
            ||  frame.get_u_plane().len() != self.u_len
            ||  frame.get_v_plane().len() != self.v_len {
            return Err(Error::BadInput);
        }
        try!(self.writer.write_all(FRAME_MAGICK));
        match frame.get_raw_params() {
            Some(params) => {
                try!(self.writer.write_all(&[SEPARATOR]));
                try!(self.writer.write_all(params));
            },
            _ => {},
        }
        try!(self.writer.write_all(&[TERMINATOR]));
        try!(self.writer.write_all(frame.get_y_plane()));
        try!(self.writer.write_all(frame.get_u_plane()));
        try!(self.writer.write_all(frame.get_v_plane()));
        Ok(())
    }
}

/// Create a new decoder instance. Alias for `Decoder::new`.
pub fn decode<R: Read>(reader: &mut R) -> Result<Decoder<R>, Error> {
    Decoder::new(reader)
}

/// Create a new encoder builder. Alias for `EncoderBuilder::new`.
pub fn encode(width: usize, height: usize) -> EncoderBuilder {
    EncoderBuilder::new(width, height)
}
<|endoftext|>