<commit_before>extern crate std;

use super::libglfw3;
use libc::{ c_int, c_char };
use std::comm::{ Sender, Receiver, Empty, Disconnected };
use std::mem::transmute;
use std::ptr::null;
use std::rc::Rc;
use std::string::String;
use std::sync::{ Arc, Future, Mutex };
use super::super::WindowEvent;
use sync::one::{ Once, ONCE_INIT };
use threaded_executer::CommandsThread;

pub struct Window {
    handle : *const libglfw3::GLFWwindow,
    commands : CommandsThread,
    eventsSender : Box<Sender<WindowEvent>>,
    eventsReceiver : Receiver<WindowEvent>
}

static mut GLFWInitialized: Once = ONCE_INIT;

impl Drop for Window {
    fn drop(&mut self) {
        unsafe {
            libglfw3::glfwDestroyWindow(self.handle);
        }
    }
}

extern fn errorCallback(errorCode: c_int, description: *const c_char) {
    fail!("error from glfw: {} (code {})", unsafe { std::c_str::CString::new(description, false).as_str().unwrap() }, errorCode);
}

extern fn keyCallback(window: *const libglfw3::GLFWwindow, key: c_int, scancode: c_int, action: c_int, mods: c_int) {
    let sender : &Sender<WindowEvent> = unsafe { transmute(libglfw3::glfwGetWindowUserPointer(window)) };

    let inputKey = match key {
        libglfw3::KEY_SPACE => ::input::Space,
        libglfw3::KEY_APOSTROPHE => ::input::Apostrophe,
        libglfw3::KEY_COMMA => ::input::Comma,
        libglfw3::KEY_MINUS => ::input::Minus,
        libglfw3::KEY_PERIOD => ::input::Period,
        libglfw3::KEY_SLASH => ::input::Slash,
        libglfw3::KEY_0 => ::input::Key0,
        libglfw3::KEY_1 => ::input::Key1,
        libglfw3::KEY_2 => ::input::Key2,
        libglfw3::KEY_3 => ::input::Key3,
        libglfw3::KEY_4 => ::input::Key4,
        libglfw3::KEY_5 => ::input::Key5,
        libglfw3::KEY_6 => ::input::Key6,
        libglfw3::KEY_7 => ::input::Key7,
        libglfw3::KEY_8 => ::input::Key8,
        libglfw3::KEY_9 => ::input::Key9,
        libglfw3::KEY_SEMICOLON => ::input::Semicolon,
        //libglfw3::KEY_EQUAL => ::input::Equal,
        libglfw3::KEY_A => ::input::A,
        libglfw3::KEY_B => ::input::B,
        libglfw3::KEY_C => ::input::C,
        libglfw3::KEY_D => ::input::D,
        libglfw3::KEY_E => ::input::E,
        libglfw3::KEY_F => ::input::F,
        libglfw3::KEY_G => ::input::G,
        libglfw3::KEY_H => ::input::H,
        libglfw3::KEY_I => ::input::I,
        libglfw3::KEY_J => ::input::J,
        libglfw3::KEY_K => ::input::K,
        libglfw3::KEY_L => ::input::L,
        libglfw3::KEY_M => ::input::M,
        libglfw3::KEY_N => ::input::N,
        libglfw3::KEY_O => ::input::O,
        libglfw3::KEY_P => ::input::P,
        libglfw3::KEY_Q => ::input::Q,
        libglfw3::KEY_R => ::input::R,
        libglfw3::KEY_S => ::input::S,
        libglfw3::KEY_T => ::input::T,
        libglfw3::KEY_U => ::input::U,
        libglfw3::KEY_V => ::input::V,
        libglfw3::KEY_W => ::input::W,
        libglfw3::KEY_X => ::input::X,
        libglfw3::KEY_Y => ::input::Y,
        libglfw3::KEY_Z => ::input::Z,
        //libglfw3::KEY_LEFT_BRACKET => ::input::LeftBracket,
        libglfw3::KEY_BACKSLASH => ::input::Backslash,
        //libglfw3::KEY_RIGHT_BRACKET => ::input::RightBracket,
        libglfw3::KEY_GRAVE_ACCENT => ::input::Grave,
        //libglfw3::KEY_WORLD_1 => ::input::World1,
        //libglfw3::KEY_WORLD_2 => ::input::World2,
        libglfw3::KEY_ESCAPE => ::input::Escape,
        libglfw3::KEY_ENTER => ::input::Return,
        libglfw3::KEY_TAB => ::input::Tab,
        libglfw3::KEY_BACKSPACE => ::input::Back,
        libglfw3::KEY_INSERT => ::input::Insert,
        libglfw3::KEY_DELETE => ::input::Delete,
        libglfw3::KEY_RIGHT => ::input::Right,
        libglfw3::KEY_LEFT => ::input::Left,
        libglfw3::KEY_DOWN => ::input::Down,
        libglfw3::KEY_UP => ::input::Up,
        /*libglfw3::KEY_PAGE_UP => ::input::PageUp,
        libglfw3::KEY_PAGE_DOWN => ::input::PageDown,*/
        libglfw3::KEY_HOME => ::input::Home,
        libglfw3::KEY_END => ::input::End,
        //libglfw3::KEY_CAPS_LOCK => ::input::CapsLock,
        //libglfw3::KEY_SCROLL_LOCK => ::input::ScrollLock,
        //libglfw3::KEY_NUM_LOCK => ::input::NumLock,
        //libglfw3::KEY_PRINT_SCREEN => ::input::PrintScreen,
        libglfw3::KEY_PAUSE => ::input::Pause,
        libglfw3::KEY_F1 => ::input::F1,
        libglfw3::KEY_F2 => ::input::F2,
        libglfw3::KEY_F3 => ::input::F3,
        libglfw3::KEY_F4 => ::input::F4,
        libglfw3::KEY_F5 => ::input::F5,
        libglfw3::KEY_F6 => ::input::F6,
        libglfw3::KEY_F7 => ::input::F7,
        libglfw3::KEY_F8 => ::input::F8,
        libglfw3::KEY_F9 => ::input::F9,
        libglfw3::KEY_F10 => ::input::F10,
        libglfw3::KEY_F11 => ::input::F11,
        libglfw3::KEY_F12 => ::input::F12,
        libglfw3::KEY_F13 => ::input::F13,
        libglfw3::KEY_F14 => ::input::F14,
        libglfw3::KEY_F15 => ::input::F15,
        /*libglfw3::KEY_F16 => ::input::F16,
        libglfw3::KEY_F17 => ::input::F17,
        libglfw3::KEY_F18 => ::input::F18,
        libglfw3::KEY_F19 => ::input::F19,
        libglfw3::KEY_F20 => ::input::F20,
        libglfw3::KEY_F21 => ::input::F21,
        libglfw3::KEY_F22 => ::input::F22,
        libglfw3::KEY_F23 => ::input::F23,
        libglfw3::KEY_F24 => ::input::F24,
        libglfw3::KEY_F25 => ::input::F25,*/
        libglfw3::KEY_KP_0 => ::input::Numpad0,
        libglfw3::KEY_KP_1 => ::input::Numpad1,
        libglfw3::KEY_KP_2 => ::input::Numpad2,
        libglfw3::KEY_KP_3 => ::input::Numpad3,
        libglfw3::KEY_KP_4 => ::input::Numpad4,
        libglfw3::KEY_KP_5 => ::input::Numpad5,
        libglfw3::KEY_KP_6 => ::input::Numpad6,
        libglfw3::KEY_KP_7 => ::input::Numpad7,
        libglfw3::KEY_KP_8 => ::input::Numpad8,
        libglfw3::KEY_KP_9 => ::input::Numpad9,
        /*libglfw3::KEY_KP_DECIMAL => ::input::NumpadDecimal,
        libglfw3::KEY_KP_DIVIDE => ::input::NumpadDivide,
        libglfw3::KEY_KP_MULTIPLY => ::input::NumpadMultiply,
        libglfw3::KEY_KP_SUBTRACT => ::input::NumpadSubtract,
        libglfw3::KEY_KP_ADD => ::input::NumpadAdd,*/
        libglfw3::KEY_KP_ENTER => ::input::NumpadEnter,
        //libglfw3::KEY_KP_EQUAL => ::input::NumpadEqual,
        libglfw3::KEY_LEFT_SHIFT => ::input::LShift,
        libglfw3::KEY_LEFT_CONTROL => ::input::LControl,
        //libglfw3::KEY_LEFT_ALT => ::input::LAlt,
        //libglfw3::KEY_LEFT_SUPER => ::input::LeftSuper,
        libglfw3::KEY_RIGHT_SHIFT => ::input::RShift,
        libglfw3::KEY_RIGHT_CONTROL => ::input::RControl,
        //libglfw3::KEY_RIGHT_ALT => ::input::AltGr,
        //libglfw3::KEY_RIGHT_SUPER => ::input::RSuper,
        //libglfw3::KEY_MENU => ::input::Menu,
        _ => return
    };

    sender.send(super::super::Input(match action {
        libglfw3::PRESS => ::input::Pressed(inputKey),
        libglfw3::RELEASE => ::input::Released(inputKey),
        //GLFW_REPEAT => ,
        _ => return
    }));
}

extern fn posCallback(window: *const libglfw3::GLFWwindow, x: c_int, y: c_int) {
    let sender : &Sender<WindowEvent> = unsafe { transmute(libglfw3::glfwGetWindowUserPointer(window)) };
    sender.send(super::super::Moved(x as uint, y as uint));
}

extern fn sizeCallback(window: *const libglfw3::GLFWwindow, w: c_int, h: c_int) {
    let sender : &Sender<WindowEvent> = unsafe { transmute(libglfw3::glfwGetWindowUserPointer(window)) };
    sender.send(super::super::Resized(w as uint, h as uint));
}

extern fn closeCallback(window: *const libglfw3::GLFWwindow) {
    let sender : &Sender<WindowEvent> = unsafe { transmute(libglfw3::glfwGetWindowUserPointer(window)) };
    sender.send(super::super::Closed);
}

extern fn cursorPosCallback(window: *const libglfw3::GLFWwindow, x: ::libc::c_double, y: ::libc::c_double) {
    let mut width: c_int = unsafe { ::std::mem::uninitialized() };
    let mut height: c_int = unsafe { ::std::mem::uninitialized() };
    unsafe { libglfw3::glfwGetWindowSize(window, &mut width, &mut height) };

    let sender : &Sender<WindowEvent> = unsafe { transmute(libglfw3::glfwGetWindowUserPointer(window)) };
    let x = (2.0 * x / (width as f64)) - 1.0;
    let y = (2.0 * (1.0 - (y / (height as f64)))) - 1.0;
    sender.send(super::super::Input(::input::MouseMoved(x as f64, y as f64)));
}

impl Window {
    pub fn new(width: uint, height: uint, title: &str) -> Window {
        unsafe {
            GLFWInitialized.doit(|| {
                if libglfw3::glfwInit() == 0 {
                    fail!("glfwInit failed");
                }
                std::rt::at_exit(proc() {
                    libglfw3::glfwTerminate();
                });
                libglfw3::glfwSetErrorCallback(Some(errorCallback));
            })
        }

        let commands = CommandsThread::new();
        let sharedTitle = String::from_str(title);

        let (tx, rx) = channel();
        let txBox = box tx;

        let mut handle = unsafe {
            let txRef: &Sender<WindowEvent> = txBox;
            let txPtr: *const Sender<WindowEvent> = transmute(txRef);

            commands.exec(proc() {
                let handle = sharedTitle.with_c_str(|title| {
                    libglfw3::glfwCreateWindow(width as c_int, height as c_int, title, null(), null())
                });

                if handle.is_null() {
                    fail!("glfwCreateWindow failed");
                }

                libglfw3::glfwSetWindowUserPointer(handle, transmute(txPtr));

                libglfw3::glfwSetKeyCallback(handle, Some(keyCallback));
                libglfw3::glfwSetWindowPosCallback(handle, Some(posCallback));
                libglfw3::glfwSetWindowSizeCallback(handle, Some(sizeCallback));
                libglfw3::glfwSetWindowCloseCallback(handle, Some(closeCallback));
                libglfw3::glfwSetCursorPosCallback(handle, Some(cursorPosCallback));

                handle
            })
        }.get();

        Window {
            handle: handle,
            commands: commands,
            eventsSender: txBox,
            eventsReceiver: rx
        }
    }

    pub fn exec<T:Send>(&self, f: proc(): Send -> T) -> Future<T> {
        self.commands.exec(f)
    }

    pub fn swap_buffers(&self) {
        let handle = self.handle;
        self.commands.exec(proc() {
            unsafe { libglfw3::glfwSwapBuffers(handle) }
        });
    }

    pub fn recv(&self) -> Option<WindowEvent> {
        self.commands.exec(proc() {
            unsafe { libglfw3::glfwPollEvents(); }
        }).get();

        match self.eventsReceiver.try_recv() {
            Ok(val) => Some(val),
            Err(Empty) => None,
            Err(Disconnected) => fail!()
        }
    }

    pub fn make_context_current(&self) {
        let handle = self.handle;
        self.commands.exec(proc() {
            unsafe { libglfw3::glfwMakeContextCurrent(handle) }
        }).get();
    }

    pub fn get_cursor_pos(&self)
        -> (f64, f64)
    {
        let mut x: ::libc::c_double = unsafe { ::std::mem::uninitialized() };
        let mut y: ::libc::c_double = unsafe { ::std::mem::uninitialized() };
        unsafe { libglfw3::glfwGetCursorPos(self.handle, &mut x, &mut y) };
        (x as f64, y as f64)
    }
}
<commit_msg>Update to rust<commit_after>extern crate std;

use super::libglfw3;
use libc::{ c_int, c_char };
use std::comm::{ Sender, Receiver, Empty, Disconnected };
use std::mem::transmute;
use std::ptr::null;
use std::rc::Rc;
use std::string::String;
use std::sync::{ Arc, Future, Mutex };
use super::super::WindowEvent;
use sync::one::{ Once, ONCE_INIT };
use threaded_executer::CommandsThread;

pub struct Window {
    handle : *const libglfw3::GLFWwindow,
    commands : CommandsThread,
    eventsSender : Box<Sender<WindowEvent>>,
    eventsReceiver : Receiver<WindowEvent>
}

static mut GLFWInitialized: Once = ONCE_INIT;

impl Drop for Window {
    fn drop(&mut self) {
        unsafe {
            libglfw3::glfwDestroyWindow(self.handle);
        }
    }
}

extern fn errorCallback(errorCode: c_int, description: *const c_char) {
    fail!("error from glfw: {} (code {})", unsafe { std::c_str::CString::new(description, false).as_str().unwrap() }, errorCode);
}

extern fn keyCallback(window: *const libglfw3::GLFWwindow, key: c_int, scancode: c_int, action: c_int, mods: c_int) {
    let sender : &Sender<WindowEvent> = unsafe { transmute(libglfw3::glfwGetWindowUserPointer(window)) };

    let inputKey = match key {
        libglfw3::KEY_SPACE => ::input::Space,
        libglfw3::KEY_APOSTROPHE => ::input::Apostrophe,
        libglfw3::KEY_COMMA => ::input::Comma,
        libglfw3::KEY_MINUS => ::input::Minus,
        libglfw3::KEY_PERIOD => ::input::Period,
        libglfw3::KEY_SLASH => ::input::Slash,
        libglfw3::KEY_0 => ::input::Key0,
        libglfw3::KEY_1 => ::input::Key1,
        libglfw3::KEY_2 => ::input::Key2,
        libglfw3::KEY_3 => ::input::Key3,
        libglfw3::KEY_4 => ::input::Key4,
        libglfw3::KEY_5 => ::input::Key5,
        libglfw3::KEY_6 => ::input::Key6,
        libglfw3::KEY_7 => ::input::Key7,
        libglfw3::KEY_8 => ::input::Key8,
        libglfw3::KEY_9 => ::input::Key9,
        libglfw3::KEY_SEMICOLON => ::input::Semicolon,
        //libglfw3::KEY_EQUAL => ::input::Equal,
        libglfw3::KEY_A => ::input::A,
        libglfw3::KEY_B => ::input::B,
        libglfw3::KEY_C => ::input::C,
        libglfw3::KEY_D => ::input::D,
        libglfw3::KEY_E => ::input::E,
        libglfw3::KEY_F => ::input::F,
        libglfw3::KEY_G => ::input::G,
        libglfw3::KEY_H => ::input::H,
        libglfw3::KEY_I => ::input::I,
        libglfw3::KEY_J => ::input::J,
        libglfw3::KEY_K => ::input::K,
        libglfw3::KEY_L => ::input::L,
        libglfw3::KEY_M => ::input::M,
        libglfw3::KEY_N => ::input::N,
        libglfw3::KEY_O => ::input::O,
        libglfw3::KEY_P => ::input::P,
        libglfw3::KEY_Q => ::input::Q,
        libglfw3::KEY_R => ::input::R,
        libglfw3::KEY_S => ::input::S,
        libglfw3::KEY_T => ::input::T,
        libglfw3::KEY_U => ::input::U,
        libglfw3::KEY_V => ::input::V,
        libglfw3::KEY_W => ::input::W,
        libglfw3::KEY_X => ::input::X,
        libglfw3::KEY_Y => ::input::Y,
        libglfw3::KEY_Z => ::input::Z,
        //libglfw3::KEY_LEFT_BRACKET => ::input::LeftBracket,
        libglfw3::KEY_BACKSLASH => ::input::Backslash,
        //libglfw3::KEY_RIGHT_BRACKET => ::input::RightBracket,
        libglfw3::KEY_GRAVE_ACCENT => ::input::Grave,
        //libglfw3::KEY_WORLD_1 => ::input::World1,
        //libglfw3::KEY_WORLD_2 => ::input::World2,
        libglfw3::KEY_ESCAPE => ::input::Escape,
        libglfw3::KEY_ENTER => ::input::Return,
        libglfw3::KEY_TAB => ::input::Tab,
        libglfw3::KEY_BACKSPACE => ::input::Back,
        libglfw3::KEY_INSERT => ::input::Insert,
        libglfw3::KEY_DELETE => ::input::Delete,
        libglfw3::KEY_RIGHT => ::input::Right,
        libglfw3::KEY_LEFT => ::input::Left,
        libglfw3::KEY_DOWN => ::input::Down,
        libglfw3::KEY_UP => ::input::Up,
        /*libglfw3::KEY_PAGE_UP => ::input::PageUp,
        libglfw3::KEY_PAGE_DOWN => ::input::PageDown,*/
        libglfw3::KEY_HOME => ::input::Home,
        libglfw3::KEY_END => ::input::End,
        //libglfw3::KEY_CAPS_LOCK => ::input::CapsLock,
        //libglfw3::KEY_SCROLL_LOCK => ::input::ScrollLock,
        //libglfw3::KEY_NUM_LOCK => ::input::NumLock,
        //libglfw3::KEY_PRINT_SCREEN => ::input::PrintScreen,
        libglfw3::KEY_PAUSE => ::input::Pause,
        libglfw3::KEY_F1 => ::input::F1,
        libglfw3::KEY_F2 => ::input::F2,
        libglfw3::KEY_F3 => ::input::F3,
        libglfw3::KEY_F4 => ::input::F4,
        libglfw3::KEY_F5 => ::input::F5,
        libglfw3::KEY_F6 => ::input::F6,
        libglfw3::KEY_F7 => ::input::F7,
        libglfw3::KEY_F8 => ::input::F8,
        libglfw3::KEY_F9 => ::input::F9,
        libglfw3::KEY_F10 => ::input::F10,
        libglfw3::KEY_F11 => ::input::F11,
        libglfw3::KEY_F12 => ::input::F12,
        libglfw3::KEY_F13 => ::input::F13,
        libglfw3::KEY_F14 => ::input::F14,
        libglfw3::KEY_F15 => ::input::F15,
        /*libglfw3::KEY_F16 => ::input::F16,
        libglfw3::KEY_F17 => ::input::F17,
        libglfw3::KEY_F18 => ::input::F18,
        libglfw3::KEY_F19 => ::input::F19,
        libglfw3::KEY_F20 => ::input::F20,
        libglfw3::KEY_F21 => ::input::F21,
        libglfw3::KEY_F22 => ::input::F22,
        libglfw3::KEY_F23 => ::input::F23,
        libglfw3::KEY_F24 => ::input::F24,
        libglfw3::KEY_F25 => ::input::F25,*/
        libglfw3::KEY_KP_0 => ::input::Numpad0,
        libglfw3::KEY_KP_1 => ::input::Numpad1,
        libglfw3::KEY_KP_2 => ::input::Numpad2,
        libglfw3::KEY_KP_3 => ::input::Numpad3,
        libglfw3::KEY_KP_4 => ::input::Numpad4,
        libglfw3::KEY_KP_5 => ::input::Numpad5,
        libglfw3::KEY_KP_6 => ::input::Numpad6,
        libglfw3::KEY_KP_7 => ::input::Numpad7,
        libglfw3::KEY_KP_8 => ::input::Numpad8,
        libglfw3::KEY_KP_9 => ::input::Numpad9,
        /*libglfw3::KEY_KP_DECIMAL => ::input::NumpadDecimal,
        libglfw3::KEY_KP_DIVIDE => ::input::NumpadDivide,
        libglfw3::KEY_KP_MULTIPLY => ::input::NumpadMultiply,
        libglfw3::KEY_KP_SUBTRACT => ::input::NumpadSubtract,
        libglfw3::KEY_KP_ADD => ::input::NumpadAdd,*/
        libglfw3::KEY_KP_ENTER => ::input::NumpadEnter,
        //libglfw3::KEY_KP_EQUAL => ::input::NumpadEqual,
        libglfw3::KEY_LEFT_SHIFT => ::input::LShift,
        libglfw3::KEY_LEFT_CONTROL => ::input::LControl,
        //libglfw3::KEY_LEFT_ALT => ::input::LAlt,
        //libglfw3::KEY_LEFT_SUPER => ::input::LeftSuper,
        libglfw3::KEY_RIGHT_SHIFT => ::input::RShift,
        libglfw3::KEY_RIGHT_CONTROL => ::input::RControl,
        //libglfw3::KEY_RIGHT_ALT => ::input::AltGr,
        //libglfw3::KEY_RIGHT_SUPER => ::input::RSuper,
        //libglfw3::KEY_MENU => ::input::Menu,
        _ => return
    };

    sender.send(super::super::Input(match action {
        libglfw3::PRESS => ::input::Pressed(inputKey),
        libglfw3::RELEASE => ::input::Released(inputKey),
        //GLFW_REPEAT => ,
        _ => return
    }));
}

extern fn posCallback(window: *const libglfw3::GLFWwindow, x: c_int, y: c_int) {
    let sender : &Sender<WindowEvent> = unsafe { transmute(libglfw3::glfwGetWindowUserPointer(window)) };
    sender.send(super::super::Moved(x as uint, y as uint));
}

extern fn sizeCallback(window: *const libglfw3::GLFWwindow, w: c_int, h: c_int) {
    let sender : &Sender<WindowEvent> = unsafe { transmute(libglfw3::glfwGetWindowUserPointer(window)) };
    sender.send(super::super::Resized(w as uint, h as uint));
}

extern fn closeCallback(window: *const libglfw3::GLFWwindow) {
    let sender : &Sender<WindowEvent> = unsafe { transmute(libglfw3::glfwGetWindowUserPointer(window)) };
    sender.send(super::super::Closed);
}

extern fn cursorPosCallback(window: *const libglfw3::GLFWwindow, x: ::libc::c_double, y: ::libc::c_double) {
    let mut width: c_int = unsafe { ::std::mem::uninitialized() };
    let mut height: c_int = unsafe { ::std::mem::uninitialized() };
    unsafe { libglfw3::glfwGetWindowSize(window, &mut width, &mut height) };

    let sender : &Sender<WindowEvent> = unsafe { transmute(libglfw3::glfwGetWindowUserPointer(window)) };
    let x = (2.0 * x / (width as f64)) - 1.0;
    let y = (2.0 * (1.0 - (y / (height as f64)))) - 1.0;
    sender.send(super::super::Input(::input::MouseMoved(x as f64, y as f64)));
}

impl Window {
    pub fn new(width: uint, height: uint, title: &str) -> Window {
        unsafe {
            GLFWInitialized.doit(|| {
                if libglfw3::glfwInit() == 0 {
                    fail!("glfwInit failed");
                }
                std::rt::at_exit(proc() {
                    libglfw3::glfwTerminate();
                });
                libglfw3::glfwSetErrorCallback(Some(errorCallback));
            })
        }

        let commands = CommandsThread::new();
        let sharedTitle = String::from_str(title);

        let (tx, rx) = channel();
        let txBox = box tx;

        let mut handle = unsafe {
            let txRef: &Sender<WindowEvent> = &*txBox;
            let txPtr: *const Sender<WindowEvent> = transmute(txRef);

            commands.exec(proc() {
                let handle = sharedTitle.with_c_str(|title| {
                    libglfw3::glfwCreateWindow(width as c_int, height as c_int, title, null(), null())
                });

                if handle.is_null() {
                    fail!("glfwCreateWindow failed");
                }

                libglfw3::glfwSetWindowUserPointer(handle, transmute(txPtr));

                libglfw3::glfwSetKeyCallback(handle, Some(keyCallback));
                libglfw3::glfwSetWindowPosCallback(handle, Some(posCallback));
                libglfw3::glfwSetWindowSizeCallback(handle, Some(sizeCallback));
                libglfw3::glfwSetWindowCloseCallback(handle, Some(closeCallback));
                libglfw3::glfwSetCursorPosCallback(handle, Some(cursorPosCallback));

                handle
            })
        }.get();

        Window {
            handle: handle,
            commands: commands,
            eventsSender: txBox,
            eventsReceiver: rx
        }
    }

    pub fn exec<T:Send>(&self, f: proc(): Send -> T) -> Future<T> {
        self.commands.exec(f)
    }

    pub fn swap_buffers(&self) {
        let handle = self.handle;
        self.commands.exec(proc() {
            unsafe { libglfw3::glfwSwapBuffers(handle) }
        });
    }

    pub fn recv(&self) -> Option<WindowEvent> {
        self.commands.exec(proc() {
            unsafe { libglfw3::glfwPollEvents(); }
        }).get();

        match self.eventsReceiver.try_recv() {
            Ok(val) => Some(val),
            Err(Empty) => None,
            Err(Disconnected) => fail!()
        }
    }

    pub fn make_context_current(&self) {
        let handle = self.handle;
        self.commands.exec(proc() {
            unsafe { libglfw3::glfwMakeContextCurrent(handle) }
        }).get();
    }

    pub fn get_cursor_pos(&self)
        -> (f64, f64)
    {
        let mut x: ::libc::c_double = unsafe { ::std::mem::uninitialized() };
        let mut y: ::libc::c_double = unsafe { ::std::mem::uninitialized() };
        unsafe { libglfw3::glfwGetCursorPos(self.handle, &mut x, &mut y) };
        (x as f64, y as f64)
    }
}
<|endoftext|>


<commit_before><commit_msg>add implementation for bubble_sort in rust<commit_after>use std::uint::range;

fn main()  {
  let a: ~[int] = ~[2, 1, 3, 9, 5, 20, 13, 40, 4];
  assert!(bubble_sort(a) == ~[1,2,3,4,5,9,13,20,40]);
}

fn bubble_sort(vector: &[int]) -> ~[int] {
  let mut sorted: ~[int] = vector.to_owned();
  let length: uint = sorted.len() - 1;
  if length == 0 { return sorted; }

  let mut swapped = true;

  while swapped {
    swapped = false;
    for range(0, length) |i| {
      if sorted[i] > sorted[i+1] {
        sorted.swap(i, i+1);
        swapped = true;
      }
    }
  }

  sorted
}
<|endoftext|>


<commit_before><commit_msg>sync Sat Oct 26 14:40:50 CEST 2019<commit_after>use libc;
use std::io;

fn main() {
    match unsafe { libc::close(0) } {
        -1 => panic!("could not close"),
        _ => {
            let mut input = String::new();
            io::stdin()
                .read_line(&mut input)
                .expect("failed to read line");
            println!("stdin: {}", input.trim());
        }
    }
}
<|endoftext|>


<commit_before>/*
The first test case using pipes. The idea is to break this into
several stages for prototyping. Here's the plan:

1. Write an already-compiled protocol using existing ports and chans.

2. Take the already-compiled version and add the low-level
synchronization code instead. (That's what this file attempts to do)

3. Write a syntax extension to compile the protocols.

At some point, we'll need to add support for select.

*/

// Hopefully someday we'll move this into core.
mod pipes {
    import unsafe::{forget, reinterpret_cast};

    enum state {
        empty,
        full,
        blocked,
        terminated
    }

    type packet<T: send> = {
        mut state: state,
        mut blocked_task: option<task::task>,
        mut payload: option<T>
    };

    fn packet<T: send>() -> *packet<T> unsafe {
        let p: *packet<T> = unsafe::transmute(~{
            mut state: empty,
            mut blocked_task: none::<task::task>,
            mut payload: none::<T>
        });
        p
    }

    #[abi = "rust-intrinsic"]
    native mod rusti {
        fn atomic_xchng(&dst: int, src: int) -> int;
        fn atomic_xchng_acq(&dst: int, src: int) -> int;
        fn atomic_xchng_rel(&dst: int, src: int) -> int;
    }

    // We should consider moving this to core::unsafe, although I
    // suspect graydon would want us to use void pointers instead.
    unsafe fn uniquify<T>(x: *T) -> ~T {
        unsafe { unsafe::reinterpret_cast(x) }
    }

    fn swap_state_acq(&dst: state, src: state) -> state {
        unsafe {
            reinterpret_cast(rusti::atomic_xchng_acq(
                *(ptr::mut_addr_of(dst) as *mut int),
                src as int))
        }
    }

    fn swap_state_rel(&dst: state, src: state) -> state {
        unsafe {
            reinterpret_cast(rusti::atomic_xchng_rel(
                *(ptr::mut_addr_of(dst) as *mut int),
                src as int))
        }
    }

    fn send<T: send>(p: *packet<T>, -payload: T) {
        let p = unsafe { uniquify(p) };
        assert (*p).payload == none;
        (*p).payload <- some(payload);
        let old_state = swap_state_rel((*p).state, full);
        alt old_state {
          empty {
            // Yay, fastpath.

            // The receiver will eventually clean this up.
            unsafe { forget(p); }
          }
          full { fail "duplicate send" }
          blocked {
            // FIXME: once the target will actually block, tell the
            // scheduler to wake it up.

            // The receiver will eventually clean this up.
            unsafe { forget(p); }
          }
          terminated {
            // The receiver will never receive this. Rely on drop_glue
            // to clean everything up.
          }
        }
    }

    fn recv<T: send>(p: *packet<T>) -> option<T> {
        let p = unsafe { uniquify(p) };
        loop {
            let old_state = swap_state_acq((*p).state,
                                           blocked);
            alt old_state {
              empty | blocked { task::yield(); }
              full {
                let mut payload = none;
                payload <-> (*p).payload;
                ret some(option::unwrap(payload))
              }
              terminated {
                assert old_state == terminated;
                ret none;
              }
            }
        }
    }

    fn sender_terminate<T: send>(p: *packet<T>) {
        let p = unsafe { uniquify(p) };
        alt swap_state_rel((*p).state, terminated) {
          empty | blocked {
            // The receiver will eventually clean up.
            unsafe { forget(p) }
          }
          full {
            // This is impossible
            fail "you dun goofed"
          }
          terminated {
            // I have to clean up, use drop_glue
          }
        }
    }

    fn receiver_terminate<T: send>(p: *packet<T>) {
        let p = unsafe { uniquify(p) };
        alt swap_state_rel((*p).state, terminated) {
          empty {
            // the sender will clean up
            unsafe { forget(p) }
          }
          blocked {
            // this shouldn't happen.
            fail "terminating a blocked packet"
          }
          terminated | full {
            // I have to clean up, use drop_glue
          }
        }
    }
}

mod pingpong {
    enum ping = *pipes::packet<pong>;
    enum pong = *pipes::packet<ping>;

    fn init() -> (client::ping, server::ping) {
        let p = pipes::packet();
        let p = pingpong::ping(p);

        let client = client::ping(p);
        let server = server::ping(p);

        (client, server)
    }

    mod client {
        enum ping = pingpong::ping;
        enum pong = pingpong::pong;

        fn do_ping(-c: ping) -> pong {
            let packet = pipes::packet();
            let packet = pingpong::pong(packet);

            pipes::send(**c, copy packet);
            pong(packet)
        }

        fn do_pong(-c: pong) -> (ping, ()) {
            let packet = pipes::recv(**c);
            alt packet {
              none {
                fail "sender closed the connection"
              }
              some(new_packet) {
                (ping(new_packet), ())
              }
            }
        }
    }

    mod server {
        enum ping = pingpong::ping;
        enum pong = pingpong::pong;

        fn do_ping(-c: ping) -> (pong, ()) {
            let packet = pipes::recv(**c);
            alt packet {
              none { fail "sender closed the connection" }
              some(new_packet) {
                (pong(new_packet), ())
              }
            }
        }

        fn do_pong(-c: pong) -> ping {
            let packet = pipes::packet();
            let packet = pingpong::ping(packet);

            pipes::send(**c, copy packet);
            ping(packet)
        }
    }
}

fn client(-chan: pingpong::client::ping) {
    let chan = pingpong::client::do_ping(chan);
    log(error, "Sent ping");
    let (chan, _data) = pingpong::client::do_pong(chan);
    log(error, "Received pong");
    pipes::sender_terminate(**chan);
}

fn server(-chan: pingpong::server::ping) {
    let (chan, _data) = pingpong::server::do_ping(chan);
    log(error, "Received ping");
    let chan = pingpong::server::do_pong(chan);
    log(error, "Sent pong");
    pipes::receiver_terminate(**chan);
}

fn main() {
    let (client_, server_) = pingpong::init();
    let client_ = ~mut some(client_);
    let server_ = ~mut some(server_);

    task::spawn {|move client_|
        let mut client__ = none;
        *client_ <-> client__;
        client(option::unwrap(client__));
    };
    task::spawn {|move server_|
        let mut server_ˊ = none;
        *server_ <-> server_ˊ;
        server(option::unwrap(server_ˊ));
    };
}
<commit_msg>Progress towards pipes.<commit_after>/*
The first test case using pipes. The idea is to break this into
several stages for prototyping. Here's the plan:

1. Write an already-compiled protocol using existing ports and chans.

2. Take the already-compiled version and add the low-level
synchronization code instead. (That's what this file attempts to do)

3. Write a syntax extension to compile the protocols.

At some point, we'll need to add support for select.

*/

// Hopefully someday we'll move this into core.
mod pipes {
    import unsafe::{forget, reinterpret_cast};

    enum state {
        empty,
        full,
        blocked,
        terminated
    }

    type packet<T: send> = {
        mut state: state,
        mut blocked_task: option<task::task>,
        mut payload: option<T>
    };

    fn packet<T: send>() -> *packet<T> unsafe {
        let p: *packet<T> = unsafe::transmute(~{
            mut state: empty,
            mut blocked_task: none::<task::task>,
            mut payload: none::<T>
        });
        p
    }

    #[abi = "rust-intrinsic"]
    native mod rusti {
        fn atomic_xchng(&dst: int, src: int) -> int;
        fn atomic_xchng_acq(&dst: int, src: int) -> int;
        fn atomic_xchng_rel(&dst: int, src: int) -> int;
    }

    // We should consider moving this to core::unsafe, although I
    // suspect graydon would want us to use void pointers instead.
    unsafe fn uniquify<T>(x: *T) -> ~T {
        unsafe { unsafe::reinterpret_cast(x) }
    }

    fn swap_state_acq(&dst: state, src: state) -> state {
        unsafe {
            reinterpret_cast(rusti::atomic_xchng_acq(
                *(ptr::mut_addr_of(dst) as *mut int),
                src as int))
        }
    }

    fn swap_state_rel(&dst: state, src: state) -> state {
        unsafe {
            reinterpret_cast(rusti::atomic_xchng_rel(
                *(ptr::mut_addr_of(dst) as *mut int),
                src as int))
        }
    }

    fn send<T: send>(-p: send_packet<T>, -payload: T) {
        let p = p.unwrap();
        let p = unsafe { uniquify(p) };
        assert (*p).payload == none;
        (*p).payload <- some(payload);
        let old_state = swap_state_rel((*p).state, full);
        alt old_state {
          empty {
            // Yay, fastpath.

            // The receiver will eventually clean this up.
            unsafe { forget(p); }
          }
          full { fail "duplicate send" }
          blocked {
            // FIXME: once the target will actually block, tell the
            // scheduler to wake it up.

            // The receiver will eventually clean this up.
            unsafe { forget(p); }
          }
          terminated {
            // The receiver will never receive this. Rely on drop_glue
            // to clean everything up.
          }
        }
    }

    fn recv<T: send>(-p: recv_packet<T>) -> option<T> {
        let p = p.unwrap();
        let p = unsafe { uniquify(p) };
        loop {
            let old_state = swap_state_acq((*p).state,
                                           blocked);
            alt old_state {
              empty | blocked { task::yield(); }
              full {
                let mut payload = none;
                payload <-> (*p).payload;
                ret some(option::unwrap(payload))
              }
              terminated {
                assert old_state == terminated;
                ret none;
              }
            }
        }
    }

    fn sender_terminate<T: send>(p: *packet<T>) {
        let p = unsafe { uniquify(p) };
        alt swap_state_rel((*p).state, terminated) {
          empty | blocked {
            // The receiver will eventually clean up.
            unsafe { forget(p) }
          }
          full {
            // This is impossible
            fail "you dun goofed"
          }
          terminated {
            // I have to clean up, use drop_glue
          }
        }
    }

    fn receiver_terminate<T: send>(p: *packet<T>) {
        let p = unsafe { uniquify(p) };
        alt swap_state_rel((*p).state, terminated) {
          empty {
            // the sender will clean up
            unsafe { forget(p) }
          }
          blocked {
            // this shouldn't happen.
            fail "terminating a blocked packet"
          }
          terminated | full {
            // I have to clean up, use drop_glue
          }
        }
    }

    class send_packet<T: send> {
        let mut p: option<*packet<T>>;
        new(p: *packet<T>) { self.p = some(p); }
        drop {
            if self.p != none {
                let mut p = none;
                p <-> self.p;
                sender_terminate(option::unwrap(p))
            }
        }
        fn unwrap() -> *packet<T> {
            let mut p = none;
            p <-> self.p;
            option::unwrap(p)
        }
    }

    class recv_packet<T: send> {
        let mut p: option<*packet<T>>;
        new(p: *packet<T>) { self.p = some(p); }
        drop {
            if self.p != none {
                let mut p = none;
                p <-> self.p;
                receiver_terminate(option::unwrap(p))
            }
        }
        fn unwrap() -> *packet<T> {
            let mut p = none;
            p <-> self.p;
            option::unwrap(p)
        }
    }

    fn entangle<T: send>() -> (send_packet<T>, recv_packet<T>) {
        let p = packet();
        (send_packet(p), recv_packet(p))
    }
}

mod pingpong {
    enum ping = *pipes::packet<pong>;
    enum pong = *pipes::packet<ping>;

    fn init() -> (client::ping, server::ping) {
        pipes::entangle()
    }

    mod client {
        type ping = pipes::send_packet<pingpong::ping>;
        type pong = pipes::recv_packet<pingpong::pong>;

        fn do_ping(-c: ping) -> pong {
            let p = pipes::packet();

            pipes::send(c, pingpong::ping(p));
            pipes::recv_packet(p)
        }

        fn do_pong(-c: pong) -> (ping, ()) {
            let packet = pipes::recv(c);
            if packet == none {
                fail "sender closed the connection"
            }
            (pipes::send_packet(*option::unwrap(packet)), ())
        }
    }

    mod server {
        type ping = pipes::recv_packet<pingpong::ping>;
        type pong = pipes::send_packet<pingpong::pong>;

        fn do_ping(-c: ping) -> (pong, ()) {
            let packet = pipes::recv(c);
            if packet == none {
                fail "sender closed the connection"
            }
            (pipes::send_packet(*option::unwrap(packet)), ())
        }

        fn do_pong(-c: pong) -> ping {
            let p = pipes::packet();
            pipes::send(c, pingpong::pong(p));
            pipes::recv_packet(p)
        }
    }
}

fn client(-chan: pingpong::client::ping) {
    let chan = pingpong::client::do_ping(chan);
    log(error, "Sent ping");
    let (chan, _data) = pingpong::client::do_pong(chan);
    log(error, "Received pong");
}

fn server(-chan: pingpong::server::ping) {
    let (chan, _data) = pingpong::server::do_ping(chan);
    log(error, "Received ping");
    let chan = pingpong::server::do_pong(chan);
    log(error, "Sent pong");
}

fn main() {
    let (client_, server_) = pingpong::init();
    let client_ = ~mut some(client_);
    let server_ = ~mut some(server_);

    task::spawn {|move client_|
        let mut client__ = none;
        *client_ <-> client__;
        client(option::unwrap(client__));
    };
    task::spawn {|move server_|
        let mut server_ˊ = none;
        *server_ <-> server_ˊ;
        server(option::unwrap(server_ˊ));
    };
}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #27131 - apasel422:issue-20162, r=arielb1<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct X { x: i32 }

fn main() {
    let mut b: Vec<X> = vec![];
    b.sort();
    //~^ ERROR the trait `core::cmp::Ord` is not implemented for the type `X`
}
<|endoftext|>


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

// Check that we can use `-C lto` when linking against libraries that were
// separately compiled.

// aux-build:sepcomp_lib.rs
// compile-flags: -C lto -g
// no-prefer-dynamic
// ignore-android FIXME #18800

extern crate sepcomp_lib;
use sepcomp_lib::a::one;
use sepcomp_lib::b::two;
use sepcomp_lib::c::three;

fn main() {
    assert_eq!(one(), 1);
    assert_eq!(two(), 2);
    assert_eq!(three(), 3);
}
<commit_msg>Rollup merge of #52526 - ljedrz:cleanup_18800, r=alexcrichton<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Check that we can use `-C lto` when linking against libraries that were
// separately compiled.

// aux-build:sepcomp_lib.rs
// compile-flags: -C lto -g
// no-prefer-dynamic

extern crate sepcomp_lib;
use sepcomp_lib::a::one;
use sepcomp_lib::b::two;
use sepcomp_lib::c::three;

fn main() {
    assert_eq!(one(), 1);
    assert_eq!(two(), 2);
    assert_eq!(three(), 3);
}
<|endoftext|>


<commit_before><commit_msg>Move io into stdio.rs<commit_after>#[allow(ctypes)];
#[no_std];
#[feature(macro_rules)];

use super::core::mem::transmute;
use super::core::slice::iter;
use super::core::iter::Iterator;
use super::core::option::{Some, Option, None};

static VGA_WIDTH  : u16 = 80;
static VGA_HEIGHT : u16 = 24;

pub enum Color {
    Black       = 0,
    Blue        = 1,
    Green       = 2,
    Cyan        = 3,
    Red         = 4,
    Pink        = 5,
    Brown       = 6,
    LightGray   = 7,
    DarkGray    = 8,
    LightBlue   = 9,
    LightGreen  = 10,
    LightCyan   = 11,
    LightRed    = 12,
    LightPink   = 13,
    Yellow      = 14,
    White       = 15,
}
fn to_bytes<'a>(s: &'a str) -> &'a [u8] { unsafe { transmute(s) } }

fn range(lo: uint, hi: uint, it: |uint| ) {
    let mut iter = lo;
    while iter < hi {
        it(iter);
        iter += 1;
    }
}

pub unsafe fn clear_screen(background: Color) {
    range(0, 80*25, |i| {
        *((0xb8000 + i * 2) as *mut u16) = make_vgaentry(0, Black, background);

    });
}

unsafe fn putchar(x: u16, y: u16, c: u8) {
    let idx : uint =  (y * VGA_WIDTH * 2 + x) as uint;
    *((0xb8000 + idx) as *mut u16) = make_vgaentry(c, Black, Yellow);
}

fn make_vgaentry(c: u8, fg: Color, bg: Color) -> u16 {
    let color = fg as u16 | (bg as u16 << 4);
    return c as u16 | (color << 8);
}

pub unsafe fn write(s: &str, x: u16, y: u16) {
    let bytes : &[u8] = to_bytes(s);
    let mut ix = x;
    let mut iy = y;
    let mut i = 0;
    for b in super::core::slice::iter(bytes) {
        putchar(ix, iy, *b);
        if (ix > VGA_WIDTH * 2) {
            ix = ix - VGA_WIDTH * 2;
            iy += 1;
        }
        i += 1;
        ix += 2;
    }
}
<|endoftext|>


<commit_before><commit_msg>Checking a connection may block, too.<commit_after><|endoftext|>


<commit_before><commit_msg>Add UI test for issue 74933<commit_after>// check-pass
//
// rust-lang/rust#74933: Lifetime error when indexing with borrowed index

use std::ops::{Index, IndexMut};

struct S(V);
struct K<'a>(&'a ());
struct V;

impl<'a> Index<&'a K<'a>> for S {
    type Output = V;

    fn index(&self, _: &'a K<'a>) -> &V {
        &self.0
    }
}

impl<'a> IndexMut<&'a K<'a>> for S {
    fn index_mut(&mut self, _: &'a K<'a>) -> &mut V {
        &mut self.0
    }
}

impl V {
    fn foo(&mut self) {}
}

fn test(s: &mut S, k: &K<'_>) {
    s[k] = V;
    s[k].foo();
}

fn main() {
    let mut s = S(V);
    let k = K(&());
    test(&mut s, &k);
}
<|endoftext|>


<commit_before>use alloc::boxed::Box;

use core::intrinsics::atomic_singlethreadfence;
use core::u32;

use drivers::pciconfig::PciConfig;

use schemes::KScheme;

const HBA_PxCMD_CR: u32 = 1 << 15;
const HBA_PxCMD_FR: u32 = 1 << 14;
const HBA_PxCMD_FRE: u32 = 1 << 4;
const HBA_PxCMD_ST: u32 = 1;

#[repr(packed)]
struct HBAPort {
    clb: u32,
    clbu: u32,
    fb: u32,
    fbu: u32,
    is: u32,
    ie: u32,
    cmd: u32,
    rsv0: u32,
    tfd: u32,
    sig: u32,
    ssts: u32,
    sctl: u32,
    serr: u32,
    sact: u32,
    ci: u32,
    sntf: u32,
    fbs: u32,
    rsv1: [u32; 11],
    vendor: [u32; 4]
}

#[derive(Debug)]
enum HBAPortType {
    None,
    Unknown(u32),
    SATA,
    SATAPI,
    PM,
    SEMB,
}

const HBA_PORT_PRESENT: u32 = 0x13;
const SATA_SIG_ATA: u32 = 0x00000101;
const SATA_SIG_ATAPI: u32 = 0xEB140101;
const SATA_SIG_PM: u32 = 0x96690101;
const SATA_SIG_SEMB: u32 = 0xC33C0101;

impl HBAPort {
    pub fn probe(&self) -> HBAPortType {
        if self.ssts & HBA_PORT_PRESENT != HBA_PORT_PRESENT {
            HBAPortType::None
        } else {
            match self.sig {
                SATA_SIG_ATA => HBAPortType::SATA,
                SATA_SIG_ATAPI => HBAPortType::SATAPI,
                SATA_SIG_PM => HBAPortType::PM,
                SATA_SIG_SEMB => HBAPortType::SEMB,
                _ => HBAPortType::Unknown(self.sig)
            }
        }
    }

    pub fn start(&mut self) {
        loop {
            if self.cmd & HBA_PxCMD_CR == 0 {
                break;
            }
            unsafe { atomic_singlethreadfence() };
        }

        self.cmd |= HBA_PxCMD_FRE;
        self.cmd |= HBA_PxCMD_ST;
    }

    pub fn stop(&mut self) {
    	self.cmd &= u32::MAX - HBA_PxCMD_ST;

    	loop {
    		if self.cmd & (HBA_PxCMD_FR | HBA_PxCMD_CR) == 0 {
                break;
            }
            unsafe { atomic_singlethreadfence() };
    	}

    	self.cmd &= u32::MAX - HBA_PxCMD_FRE;
    }

    pub fn slot(&self) -> Option<u32> {
        let slots = self.sact | self.ci;
        for i in 0..32 {
            if slots & 1 << i == 0 {
                return Some(i);
            }
        }
        None
    }
}

#[repr(packed)]
struct HBAMem {
    cap: u32,
    ghc: u32,
    is: u32,
    pi: u32,
    vs: u32,
    ccc_ctl: u32,
    ccc_pts: u32,
    em_loc: u32,
    em_ctl: u32,
    cap2: u32,
    bohc: u32,
    rsv: [u8; 116],
    vendor: [u8; 96],
    ports: [HBAPort; 32]
}

const FIS_TYPE_REG_H2D: u8 = 0x27;	// Register FIS - host to device
const FIS_TYPE_REG_D2H: u8 = 0x34;	// Register FIS - device to host
const FIS_TYPE_DMA_ACT: u8 = 0x39;	// DMA activate FIS - device to host
const FIS_TYPE_DMA_SETUP: u8 = 0x41;	// DMA setup FIS - bidirectional
const FIS_TYPE_DATA: u8 = 0x46;	// Data FIS - bidirectional
const FIS_TYPE_BIST: u8 = 0x58;	// BIST activate FIS - bidirectional
const FIS_TYPE_PIO_SETUP: u8 = 0x5F;	// PIO setup FIS - device to host
const FIS_TYPE_DEV_BITS: u8 = 0xA1;	// Set device bits FIS - device to host

#[repr(packed)]
struct FisRegH2D{
	// DWORD 0
	fis_type: u8,	// FIS_TYPE_REG_H2D

	pm: u8,	       // Port multiplier, 1: Command, 0: Control

	command: u8,	// Command register
	featurel: u8,	// Feature register, 7:0

	// DWORD 1
	lba0: u8,		// LBA low register, 7:0
	lba1: u8,		// LBA mid register, 15:8
	lba2: u8,		// LBA high register, 23:16
	device: u8,		// Device register

	// DWORD 2
	lba3: u8,		// LBA register, 31:24
	lba4: u8,		// LBA register, 39:32
	lba5: u8,		// LBA register, 47:40
	featureh: u8,	// Feature register, 15:8

	// DWORD 3
	countl: u8,		// Count register, 7:0
	counth: u8,		// Count register, 15:8
	icc: u8,		// Isochronous command completion
	control: u8,	// Control register

	// DWORD 4
	rsv1: [u8; 4],  // Reserved
}

#[repr(packed)]
struct FisRegD2H {
	// DWORD 0
	fis_type: u8,    // FIS_TYPE_REG_D2H

	pm: u8,          // Port multiplier, Interrupt bit: 2

	status: u8,      // Status register
	error: u8,       // Error register

	// DWORD 1
	lba0: u8,        // LBA low register, 7:0
	lba1: u8,        // LBA mid register, 15:8
	lba2: u8,        // LBA high register, 23:16
	device: u8,      // Device register

	// DWORD 2
	lba3: u8,        // LBA register, 31:24
	lba4: u8,        // LBA register, 39:32
	lba5: u8,        // LBA register, 47:40
	rsv2: u8,        // Reserved

	// DWORD 3
	countl: u8,      // Count register, 7:0
	counth: u8,      // Count register, 15:8
	rsv3: [u8; 2],   // Reserved

	// DWORD 4
	rsv4: [u8; 4],   // Reserved
}

#[repr(packed)]
struct FisData {
	// DWORD 0
	fis_type: u8,	// FIS_TYPE_DATA

	pm: u8,	        // Port multiplier

	rsv1: [u8; 2],	// Reserved

	// DWORD 1 ~ N
	data: u32,      // Payload
}

#[repr(packed)]
struct FisPioSetup {
	// DWORD 0
	fis_type: u8,	// FIS_TYPE_PIO_SETUP

	pm: u8,      	// Port multiplier, direction: 4 - device to host, interrupt: 2

	status: u8,		// Status register
	error: u8,		// Error register

	// DWORD 1
	lba0: u8,		// LBA low register, 7:0
	lba1: u8,		// LBA mid register, 15:8
	lba2: u8,		// LBA high register, 23:16
	device: u8,		// Device register

	// DWORD 2
	lba3: u8,		// LBA register, 31:24
	lba4: u8,		// LBA register, 39:32
	lba5: u8,		// LBA register, 47:40
	rsv2: u8,		// Reserved

	// DWORD 3
	countl: u8,		// Count register, 7:0
	counth: u8,		// Count register, 15:8
	rsv3: u8,		// Reserved
	e_status: u8,	// New value of status register

	// DWORD 4
	tc: u16,		// Transfer count
	rsv4: [u8; 2],	// Reserved
}

struct FisDmaSetup {
	// DWORD 0
	fis_type: u8,	     // FIS_TYPE_DMA_SETUP

	pm: u8,	             // Port multiplier, direction: 4 - device to host, interrupt: 2, auto-activate: 1

    rsv1: [u8; 2],       // Reserved

	//DWORD 1&2
    DMAbufferID: u64,    // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work.

    //DWORD 3
    rsv3: u32,           //More reserved

    //DWORD 4
    DMAbufOffset: u32,   //Byte offset into buffer. First 2 bits must be 0

    //DWORD 5
    TransferCount: u32,  //Number of bytes to transfer. Bit 0 must be 0

    //DWORD 6
    rsv6: u32,          //Reserved
}

pub struct Ahci {
    pci: PciConfig,
    mem: *mut HBAMem,
    irq: u8,
}

impl Ahci {
    pub fn new(mut pci: PciConfig) -> Box<Self> {
        let base = unsafe { (pci.read(0x24) & 0xFFFFFFF0) as usize };
        let irq = unsafe { (pci.read(0x3C) & 0xF) as u8 };

        let mut module = box Ahci {
            pci: pci,
            mem: base as *mut HBAMem,
            irq: irq,
        };

        module.init();

        module
    }

    fn init(&mut self) {
        debugln!("AHCI on: {:X} IRQ: {:X}", self.mem as usize, self.irq);

        let mem = unsafe { &mut * self.mem };

        for i in 0..32 {
            if mem.pi & 1 << i == 1 << i {
                debugln!("Port {}: {:X} {:?}", i, mem.ports[i].ssts, mem.ports[i].probe());
            }
        }
    }
}

impl KScheme for Ahci {
    fn on_irq(&mut self, irq: u8) {
        if irq == self.irq {
            debugln!("AHCI IRQ");
        }
    }

    fn on_poll(&mut self) {
    }
}
<commit_msg>Add derives to Fis<commit_after>use alloc::boxed::Box;

use core::intrinsics::atomic_singlethreadfence;
use core::u32;

use drivers::pciconfig::PciConfig;

use schemes::KScheme;

const HBA_PxCMD_CR: u32 = 1 << 15;
const HBA_PxCMD_FR: u32 = 1 << 14;
const HBA_PxCMD_FRE: u32 = 1 << 4;
const HBA_PxCMD_ST: u32 = 1;

#[repr(packed)]
struct HBAPort {
    clb: u32,
    clbu: u32,
    fb: u32,
    fbu: u32,
    is: u32,
    ie: u32,
    cmd: u32,
    rsv0: u32,
    tfd: u32,
    sig: u32,
    ssts: u32,
    sctl: u32,
    serr: u32,
    sact: u32,
    ci: u32,
    sntf: u32,
    fbs: u32,
    rsv1: [u32; 11],
    vendor: [u32; 4]
}

#[derive(Debug)]
enum HBAPortType {
    None,
    Unknown(u32),
    SATA,
    SATAPI,
    PM,
    SEMB,
}

const HBA_PORT_PRESENT: u32 = 0x13;
const SATA_SIG_ATA: u32 = 0x00000101;
const SATA_SIG_ATAPI: u32 = 0xEB140101;
const SATA_SIG_PM: u32 = 0x96690101;
const SATA_SIG_SEMB: u32 = 0xC33C0101;

impl HBAPort {
    pub fn probe(&self) -> HBAPortType {
        if self.ssts & HBA_PORT_PRESENT != HBA_PORT_PRESENT {
            HBAPortType::None
        } else {
            match self.sig {
                SATA_SIG_ATA => HBAPortType::SATA,
                SATA_SIG_ATAPI => HBAPortType::SATAPI,
                SATA_SIG_PM => HBAPortType::PM,
                SATA_SIG_SEMB => HBAPortType::SEMB,
                _ => HBAPortType::Unknown(self.sig)
            }
        }
    }

    pub fn start(&mut self) {
        loop {
            if self.cmd & HBA_PxCMD_CR == 0 {
                break;
            }
            unsafe { atomic_singlethreadfence() };
        }

        self.cmd |= HBA_PxCMD_FRE;
        self.cmd |= HBA_PxCMD_ST;
    }

    pub fn stop(&mut self) {
    	self.cmd &= u32::MAX - HBA_PxCMD_ST;

    	loop {
    		if self.cmd & (HBA_PxCMD_FR | HBA_PxCMD_CR) == 0 {
                break;
            }
            unsafe { atomic_singlethreadfence() };
    	}

    	self.cmd &= u32::MAX - HBA_PxCMD_FRE;
    }

    pub fn slot(&self) -> Option<u32> {
        let slots = self.sact | self.ci;
        for i in 0..32 {
            if slots & 1 << i == 0 {
                return Some(i);
            }
        }
        None
    }
}

#[repr(packed)]
struct HBAMem {
    cap: u32,
    ghc: u32,
    is: u32,
    pi: u32,
    vs: u32,
    ccc_ctl: u32,
    ccc_pts: u32,
    em_loc: u32,
    em_ctl: u32,
    cap2: u32,
    bohc: u32,
    rsv: [u8; 116],
    vendor: [u8; 96],
    ports: [HBAPort; 32]
}

const FIS_TYPE_REG_H2D: u8 = 0x27;	// Register FIS - host to device
const FIS_TYPE_REG_D2H: u8 = 0x34;	// Register FIS - device to host
const FIS_TYPE_DMA_ACT: u8 = 0x39;	// DMA activate FIS - device to host
const FIS_TYPE_DMA_SETUP: u8 = 0x41;	// DMA setup FIS - bidirectional
const FIS_TYPE_DATA: u8 = 0x46;	// Data FIS - bidirectional
const FIS_TYPE_BIST: u8 = 0x58;	// BIST activate FIS - bidirectional
const FIS_TYPE_PIO_SETUP: u8 = 0x5F;	// PIO setup FIS - device to host
const FIS_TYPE_DEV_BITS: u8 = 0xA1;	// Set device bits FIS - device to host

#[repr(packed)]
#[derive(Copy, Clone, Debug, Default)]
struct FisRegH2D{
	// DWORD 0
	fis_type: u8,	// FIS_TYPE_REG_H2D

	pm: u8,	       // Port multiplier, 1: Command, 0: Control

	command: u8,	// Command register
	featurel: u8,	// Feature register, 7:0

	// DWORD 1
	lba0: u8,		// LBA low register, 7:0
	lba1: u8,		// LBA mid register, 15:8
	lba2: u8,		// LBA high register, 23:16
	device: u8,		// Device register

	// DWORD 2
	lba3: u8,		// LBA register, 31:24
	lba4: u8,		// LBA register, 39:32
	lba5: u8,		// LBA register, 47:40
	featureh: u8,	// Feature register, 15:8

	// DWORD 3
	countl: u8,		// Count register, 7:0
	counth: u8,		// Count register, 15:8
	icc: u8,		// Isochronous command completion
	control: u8,	// Control register

	// DWORD 4
	rsv1: [u8; 4],  // Reserved
}

#[repr(packed)]
#[derive(Copy, Clone, Debug, Default)]
struct FisRegD2H {
	// DWORD 0
	fis_type: u8,    // FIS_TYPE_REG_D2H

	pm: u8,          // Port multiplier, Interrupt bit: 2

	status: u8,      // Status register
	error: u8,       // Error register

	// DWORD 1
	lba0: u8,        // LBA low register, 7:0
	lba1: u8,        // LBA mid register, 15:8
	lba2: u8,        // LBA high register, 23:16
	device: u8,      // Device register

	// DWORD 2
	lba3: u8,        // LBA register, 31:24
	lba4: u8,        // LBA register, 39:32
	lba5: u8,        // LBA register, 47:40
	rsv2: u8,        // Reserved

	// DWORD 3
	countl: u8,      // Count register, 7:0
	counth: u8,      // Count register, 15:8
	rsv3: [u8; 2],   // Reserved

	// DWORD 4
	rsv4: [u8; 4],   // Reserved
}

#[repr(packed)]
#[derive(Copy, Clone, Debug, Default)]
struct FisData {
	// DWORD 0
	fis_type: u8,	// FIS_TYPE_DATA

	pm: u8,	        // Port multiplier

	rsv1: [u8; 2],	// Reserved

	// DWORD 1 ~ N
	data: u32,      // Payload
}

#[repr(packed)]
#[derive(Copy, Clone, Debug, Default)]
struct FisPioSetup {
	// DWORD 0
	fis_type: u8,	// FIS_TYPE_PIO_SETUP

	pm: u8,      	// Port multiplier, direction: 4 - device to host, interrupt: 2

	status: u8,		// Status register
	error: u8,		// Error register

	// DWORD 1
	lba0: u8,		// LBA low register, 7:0
	lba1: u8,		// LBA mid register, 15:8
	lba2: u8,		// LBA high register, 23:16
	device: u8,		// Device register

	// DWORD 2
	lba3: u8,		// LBA register, 31:24
	lba4: u8,		// LBA register, 39:32
	lba5: u8,		// LBA register, 47:40
	rsv2: u8,		// Reserved

	// DWORD 3
	countl: u8,		// Count register, 7:0
	counth: u8,		// Count register, 15:8
	rsv3: u8,		// Reserved
	e_status: u8,	// New value of status register

	// DWORD 4
	tc: u16,		// Transfer count
	rsv4: [u8; 2],	// Reserved
}

#[repr(packed)]
#[derive(Copy, Clone, Debug, Default)]
struct FisDmaSetup {
	// DWORD 0
	fis_type: u8,	     // FIS_TYPE_DMA_SETUP

	pm: u8,	             // Port multiplier, direction: 4 - device to host, interrupt: 2, auto-activate: 1

    rsv1: [u8; 2],       // Reserved

	//DWORD 1&2
    DMAbufferID: u64,    // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work.

    //DWORD 3
    rsv3: u32,           //More reserved

    //DWORD 4
    DMAbufOffset: u32,   //Byte offset into buffer. First 2 bits must be 0

    //DWORD 5
    TransferCount: u32,  //Number of bytes to transfer. Bit 0 must be 0

    //DWORD 6
    rsv6: u32,          //Reserved
}

pub struct Ahci {
    pci: PciConfig,
    mem: *mut HBAMem,
    irq: u8,
}

impl Ahci {
    pub fn new(mut pci: PciConfig) -> Box<Self> {
        let base = unsafe { (pci.read(0x24) & 0xFFFFFFF0) as usize };
        let irq = unsafe { (pci.read(0x3C) & 0xF) as u8 };

        let mut module = box Ahci {
            pci: pci,
            mem: base as *mut HBAMem,
            irq: irq,
        };

        module.init();

        module
    }

    fn init(&mut self) {
        debugln!("AHCI on: {:X} IRQ: {:X}", self.mem as usize, self.irq);

        let mem = unsafe { &mut * self.mem };

        for i in 0..32 {
            if mem.pi & 1 << i == 1 << i {
                debugln!("Port {}: {:X} {:?}", i, mem.ports[i].ssts, mem.ports[i].probe());
            }
        }
    }
}

impl KScheme for Ahci {
    fn on_irq(&mut self, irq: u8) {
        if irq == self.irq {
            debugln!("AHCI IRQ");
        }
    }

    fn on_poll(&mut self) {
    }
}
<|endoftext|>


<commit_before>#![cfg(feature = "cloudhsm")]

extern crate rusoto_core;
extern crate rusoto_cloudhsm;

use rusoto_cloudhsm::{CloudHsm, CloudHsmClient, ListHapgsRequest, ListHsmsRequest, ListLunaClientsRequest};
use rusoto_core::{DefaultCredentialsProvider, Region};
use rusoto_core::default_tls_client;

#[test]
fn should_list_hapgs() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = CloudHsmClient::new(default_tls_client().unwrap(), credentials, Region::UsEast1);
    let request = ListHapgsRequest::default();

    client.list_hapgs(&request).unwrap();
}

#[test]
fn should_list_hsms() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = CloudHsmClient::new(default_tls_client().unwrap(), credentials, Region::UsEast1);
    let request = ListHsmsRequest::default();

    client.list_hsms(&request).unwrap();
}
#[test]
fn should_list_luna_clients() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = CloudHsmClient::new(default_tls_client().unwrap(), credentials, Region::UsEast1);
    let request = ListLunaClientsRequest::default();

    client.list_luna_clients(&request).unwrap();
}
<commit_msg>Don't fail cloudhsm tests if we get service unavailable message.<commit_after>#![cfg(feature = "cloudhsm")]

extern crate rusoto_core;
extern crate rusoto_cloudhsm;

use rusoto_cloudhsm::{CloudHsm, CloudHsmClient, ListHapgsRequest, ListHsmsRequest, ListLunaClientsRequest};
use rusoto_core::{DefaultCredentialsProvider, Region};
use rusoto_core::default_tls_client;

#[test]
fn should_list_hapgs() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = CloudHsmClient::new(default_tls_client().unwrap(), credentials, Region::UsEast1);
    let request = ListHapgsRequest::default();

    match client.list_hapgs(&request) {
        Ok(_) => (),
        Err(e) => {
            if e.to_string().contains("This service is unavailable.") {
                ()
            } else {
                panic!("Error unrelated to service being unavailable: {:?}", e);
            }
        }
    }
}

#[test]
fn should_list_hsms() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = CloudHsmClient::new(default_tls_client().unwrap(), credentials, Region::UsEast1);
    let request = ListHsmsRequest::default();

    match client.list_hsms(&request) {
        Ok(_) => (),
        Err(e) => {
            if e.to_string().contains("This service is unavailable.") {
                ()
            } else {
                panic!("Error unrelated to service being unavailable: {:?}", e);
            }
        }
    }
}
#[test]
fn should_list_luna_clients() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = CloudHsmClient::new(default_tls_client().unwrap(), credentials, Region::UsEast1);
    let request = ListLunaClientsRequest::default();

    match client.list_luna_clients(&request) {
        Ok(_) => (),
        Err(e) => {
            if e.to_string().contains("This service is unavailable.") {
                ()
            } else {
                panic!("Error unrelated to service being unavailable: {:?}", e);
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Minor stuff<commit_after><|endoftext|>


<commit_before><commit_msg>Remove the unnecessary send_embed fn<commit_after><|endoftext|>


<commit_before><commit_msg>Implemented some traits for Category<commit_after><|endoftext|>


<commit_before>use std::{Vec, String, ToString};
use std::collections::{BTreeMap, VecDeque};

use super::dvaddr::DVAddr;
use super::zio;

/// MRU - Most Recently Used cache
struct Mru {
    map: BTreeMap<DVAddr, Vec<u8>>,
    queue: VecDeque<DVAddr>, // Oldest DVAddrs are at the end
    size: usize, // Max mru cache size in blocks
    used: usize, // Number of used blocks in mru cache
}

impl Mru {
    pub fn new() -> Self {
        Mru {
            map: BTreeMap::new(),
            queue: VecDeque::new(),
            size: 1000,
            used: 0,
        }
    }

    fn cache_block(&mut self, dva: &DVAddr, block: Vec<u8>) -> Result<Vec<u8>, String> {
        // If necessary, make room for the block in the cache
        while self.used + (dva.asize() as usize) > self.size {
            let last_dva = match self.queue.pop_back() {
                Some(dva) => dva,
                None => return Err("No more ARC MRU items to free".to_string()),
            };
            self.map.remove(&last_dva);
            self.used -= last_dva.asize() as usize;
        }

        // Add the block to the cache
        self.used += dva.asize() as usize;
        self.map.insert(*dva, block);
        self.queue.push_front(*dva);
        Ok(self.map.get(dva).unwrap().clone())
    }
}

/// MFU - Most Frequently Used cache
struct Mfu {
    // TODO: Keep track of use counts. So mfu_map becomes (use_count: u64, Vec<u8>). Reset the use
    // count every once in a while. For instance, every 1000 reads. This will probably end up being
    // a knob for the user.
    // TODO: Keep track of minimum frequency and corresponding DVA
    map: BTreeMap<DVAddr, (u64, Vec<u8>)>,
    size: usize, // Max mfu cache size in blocks
    used: usize, // Number of used bytes in mfu cache
}

impl Mfu {
    pub fn new() -> Self {
        Mfu {
            map: BTreeMap::new(),
            size: 1000,
            used: 0,
        }
    }

    // TODO: cache_block. Remove the DVA with the lowest frequency
    /*
    fn cache_block(&mut self, dva: &DVAddr, block: Vec<u8>) -> Result<Vec<u8>, String> {
    }
    */
}

// Our implementation of the Adaptive Replacement Cache (ARC) is set up to allocate
// its buffer on the heap rather than in a private pool thing. This makes it much
// simpler to implement, but defers the fragmentation problem to the heap allocator.
// We named the type `ArCache` to avoid confusion with Rust's `Arc` reference type.
pub struct ArCache {
    mru: Mru,
    mfu: Mfu,
}

impl ArCache {
    pub fn new() -> Self {
        ArCache {
            mru: Mru::new(),
            mfu: Mfu::new(),
        }
    }

    pub fn read(&mut self, reader: &mut zio::Reader, dva: &DVAddr) -> Result<Vec<u8>, String> {
        if let Some(block) = self.mru.map.remove(dva) {
            self.mfu.map.insert(*dva, (0, block.clone()));

            // Block is cached
            return Ok(block);
        }
        if let Some(block) = self.mfu.map.get_mut(dva) {
            // Block is cached
            if block.0 > 1000 {
                block.0 = 0;
            } else {
                block.0 += 1;
            }

            return Ok(block.1.clone());
        }

        // Block isn't cached, have to read it from disk
        let block = reader.read(dva.sector() as usize, dva.asize() as usize);

        // Blocks start in MRU cache
        self.mru.cache_block(dva, block)
    }
}
<commit_msg>Finish TODO for MFU in ZFS<commit_after>use std::{Vec, String, ToString};
use std::collections::{BTreeMap, VecDeque};

use super::dvaddr::DVAddr;
use super::zio;

/// MRU - Most Recently Used cache
struct Mru {
    map: BTreeMap<DVAddr, Vec<u8>>,
    queue: VecDeque<DVAddr>, // Oldest DVAddrs are at the end
    size: usize, // Max mru cache size in blocks
    used: usize, // Number of used blocks in mru cache
}

impl Mru {
    pub fn new() -> Self {
        Mru {
            map: BTreeMap::new(),
            queue: VecDeque::new(),
            size: 1000,
            used: 0,
        }
    }

    pub fn cache_block(&mut self, dva: &DVAddr, block: Vec<u8>) -> Result<Vec<u8>, String> {
        // If necessary, make room for the block in the cache
        while self.used + (dva.asize() as usize) > self.size {
            let last_dva = match self.queue.pop_back() {
                Some(dva) => dva,
                None => return Err("No more ARC MRU items to free".to_string()),
            };
            self.map.remove(&last_dva);
            self.used -= last_dva.asize() as usize;
        }

        // Add the block to the cache
        self.used += dva.asize() as usize;
        self.map.insert(*dva, block);
        self.queue.push_front(*dva);
        Ok(self.map.get(dva).unwrap().clone())
    }
}

/// MFU - Most Frequently Used cache
struct Mfu {
    // TODO: Keep track of use counts. So mfu_map becomes (use_count: u64, Vec<u8>). Reset the use
    // count every once in a while. For instance, every 1000 reads. This will probably end up being
    // a knob for the user.
    // TODO: Keep track of minimum frequency and corresponding DVA
    map: BTreeMap<DVAddr, (u64, Vec<u8>)>,
    size: usize, // Max mfu cache size in blocks
    used: usize, // Number of used bytes in mfu cache
}

impl Mfu {
    pub fn new() -> Self {
        Mfu {
            map: BTreeMap::new(),
            size: 1000,
            used: 0,
        }
    }

    pub fn cache_block(&mut self, dva: &DVAddr, block: Vec<u8>) -> Result<Vec<u8>, String> {
        {
            let mut lowest_freq = 0;
            let mut lowest_dva: Result<DVAddr, String> = Err("No valid DVA found.".to_string());

            for (&dva_key, &(freq, _)) in self.map.iter() {
                if freq < lowest_freq {
                    lowest_freq = freq;
                    lowest_dva = Ok(dva_key);
                }
            }

            self.map.remove(&try!(lowest_dva));
        }

        // Add the block to the cache
        self.used += dva.asize() as usize;
        self.map.insert(*dva, (1, block));
        Ok(self.map.get(dva).unwrap().1.clone())
    }
}

// Our implementation of the Adaptive Replacement Cache (ARC) is set up to allocate
// its buffer on the heap rather than in a private pool thing. This makes it much
// simpler to implement, but defers the fragmentation problem to the heap allocator.
// We named the type `ArCache` to avoid confusion with Rust's `Arc` reference type.
pub struct ArCache {
    mru: Mru,
    mfu: Mfu,
}

impl ArCache {
    pub fn new() -> Self {
        ArCache {
            mru: Mru::new(),
            mfu: Mfu::new(),
        }
    }

    pub fn read(&mut self, reader: &mut zio::Reader, dva: &DVAddr) -> Result<Vec<u8>, String> {
        if let Some(block) = self.mru.map.remove(dva) {
            self.mfu.map.insert(*dva, (0, block.clone()));

            // Block is cached
            return Ok(block);
        }
        if let Some(block) = self.mfu.map.get_mut(dva) {
            // Block is cached
            if block.0 > 1000 {
                block.0 = 0;
            } else {
                block.0 += 1;
            }

            return Ok(block.1.clone());
        }

        // Block isn't cached, have to read it from disk
        let block = reader.read(dva.sector() as usize, dva.asize() as usize);

        // Blocks start in MRU cache
        self.mru.cache_block(dva, block)
    }
}
<|endoftext|>


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

//! Utilities for manipulating the char type

// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

use char;
use cmp::Eq;
use option::{None, Option, Some};
use str;
use u32;
use uint;
use unicode;

/*
    Lu  Uppercase_Letter    an uppercase letter
    Ll  Lowercase_Letter    a lowercase letter
    Lt  Titlecase_Letter    a digraphic character, with first part uppercase
    Lm  Modifier_Letter     a modifier letter
    Lo  Other_Letter    other letters, including syllables and ideographs
    Mn  Nonspacing_Mark     a nonspacing combining mark (zero advance width)
    Mc  Spacing_Mark    a spacing combining mark (positive advance width)
    Me  Enclosing_Mark  an enclosing combining mark
    Nd  Decimal_Number  a decimal digit
    Nl  Letter_Number   a letterlike numeric character
    No  Other_Number    a numeric character of other type
    Pc  Connector_Punctuation   a connecting punctuation mark, like a tie
    Pd  Dash_Punctuation    a dash or hyphen punctuation mark
    Ps  Open_Punctuation    an opening punctuation mark (of a pair)
    Pe  Close_Punctuation   a closing punctuation mark (of a pair)
    Pi  Initial_Punctuation     an initial quotation mark
    Pf  Final_Punctuation   a final quotation mark
    Po  Other_Punctuation   a punctuation mark of other type
    Sm  Math_Symbol     a symbol of primarily mathematical use
    Sc  Currency_Symbol     a currency sign
    Sk  Modifier_Symbol     a non-letterlike modifier symbol
    So  Other_Symbol    a symbol of other type
    Zs  Space_Separator     a space character (of various non-zero widths)
    Zl  Line_Separator  U+2028 LINE SEPARATOR only
    Zp  Paragraph_Separator     U+2029 PARAGRAPH SEPARATOR only
    Cc  Control     a C0 or C1 control code
    Cf  Format  a format control character
    Cs  Surrogate   a surrogate code point
    Co  Private_Use     a private-use character
    Cn  Unassigned  a reserved unassigned code point or a noncharacter
*/

pub use is_alphabetic = unicode::derived_property::Alphabetic;
pub use is_XID_start = unicode::derived_property::XID_Start;
pub use is_XID_continue = unicode::derived_property::XID_Continue;

/**
 * Indicates whether a character is in lower case, defined
 * in terms of the Unicode General Category 'Ll'
 */
#[inline(always)]
pub pure fn is_lowercase(c: char) -> bool {
    return unicode::general_category::Ll(c);
}

/**
 * Indicates whether a character is in upper case, defined
 * in terms of the Unicode General Category 'Lu'.
 */
#[inline(always)]
pub pure fn is_uppercase(c: char) -> bool {
    return unicode::general_category::Lu(c);
}

/**
 * Indicates whether a character is whitespace. Whitespace is defined in
 * terms of the Unicode General Categories 'Zs', 'Zl', 'Zp'
 * additional 'Cc'-category control codes in the range [0x09, 0x0d]
 */
#[inline(always)]
pub pure fn is_whitespace(c: char) -> bool {
    return ('\x09' <= c && c <= '\x0d')
        || unicode::general_category::Zs(c)
        || unicode::general_category::Zl(c)
        || unicode::general_category::Zp(c);
}

/**
 * Indicates whether a character is alphanumeric. Alphanumericness is
 * defined in terms of the Unicode General Categories 'Nd', 'Nl', 'No'
 * and the Derived Core Property 'Alphabetic'.
 */
#[inline(always)]
pub pure fn is_alphanumeric(c: char) -> bool {
    return unicode::derived_property::Alphabetic(c) ||
        unicode::general_category::Nd(c) ||
        unicode::general_category::Nl(c) ||
        unicode::general_category::No(c);
}

/// Indicates whether the character is an ASCII character
#[inline(always)]
pub pure fn is_ascii(c: char) -> bool {
   c - ('\x7F' & c) == '\x00'
}

/// Indicates whether the character is numeric (Nd, Nl, or No)
#[inline(always)]
pub pure fn is_digit(c: char) -> bool {
    return unicode::general_category::Nd(c) ||
        unicode::general_category::Nl(c) ||
        unicode::general_category::No(c);
}

/**
 * Convert a char to the corresponding digit.
 *
 * # Return value
 *
 * If `c` is between '0' and '9', the corresponding value
 * between 0 and 9. If `c` is 'a' or 'A', 10. If `c` is
 * 'b' or 'B', 11, etc. Returns none if the char does not
 * refer to a digit in the given radix.
 */
#[inline]
pub pure fn to_digit(c: char, radix: uint) -> Option<uint> {
    let val = match c {
      '0' .. '9' => c as uint - ('0' as uint),
      'a' .. 'z' => c as uint + 10u - ('a' as uint),
      'A' .. 'Z' => c as uint + 10u - ('A' as uint),
      _ => return None
    };
    if val < radix { Some(val) }
    else { None }
}

/**
 * Return the hexadecimal unicode escape of a char.
 *
 * The rules are as follows:
 *
 *   - chars in [0,0xff] get 2-digit escapes: `\\xNN`
 *   - chars in [0x100,0xffff] get 4-digit escapes: `\\uNNNN`
 *   - chars above 0x10000 get 8-digit escapes: `\\UNNNNNNNN`
 */
pub pure fn escape_unicode(c: char) -> ~str {
    let s = u32::to_str(c as u32, 16u);
    let (c, pad) = (if c <= '\xff' { ('x', 2u) }
                    else if c <= '\uffff' { ('u', 4u) }
                    else { ('U', 8u) });
    assert str::len(s) <= pad;
    let mut out = ~"\\";
    unsafe {
        str::push_str(&mut out, str::from_char(c));
        for uint::range(str::len(s), pad) |_i|
            { str::push_str(&mut out, ~"0"); }
        str::push_str(&mut out, s);
    }
    out
}

/**
 * Return a 'default' ASCII and C++11-like char-literal escape of a char.
 *
 * The default is chosen with a bias toward producing literals that are
 * legal in a variety of languages, including C++11 and similar C-family
 * languages. The exact rules are:
 *
 *   - Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
 *   - Single-quote, double-quote and backslash chars are backslash-escaped.
 *   - Any other chars in the range [0x20,0x7e] are not escaped.
 *   - Any other chars are given hex unicode escapes; see `escape_unicode`.
 */
pub pure fn escape_default(c: char) -> ~str {
    match c {
      '\t' => ~"\\t",
      '\r' => ~"\\r",
      '\n' => ~"\\n",
      '\\' => ~"\\\\",
      '\'' => ~"\\'",
      '"'  => ~"\\\"",
      '\x20' .. '\x7e' => str::from_char(c),
      _ => escape_unicode(c)
    }
}

/**
 * Compare two chars
 *
 * # Return value
 *
 * -1 if a < b, 0 if a == b, +1 if a > b
 */
#[inline(always)]
pub pure fn cmp(a: char, b: char) -> int {
    return  if b > a { -1 }
    else if b < a { 1 }
    else { 0 }
}

#[cfg(notest)]
impl char : Eq {
    pure fn eq(&self, other: &char) -> bool { (*self) == (*other) }
    pure fn ne(&self, other: &char) -> bool { (*self) != (*other) }
}

#[test]
fn test_is_lowercase() {
    assert is_lowercase('a');
    assert is_lowercase('ö');
    assert is_lowercase('ß');
    assert !is_lowercase('Ü');
    assert !is_lowercase('P');
}

#[test]
fn test_is_uppercase() {
    assert !is_uppercase('h');
    assert !is_uppercase('ä');
    assert !is_uppercase('ß');
    assert is_uppercase('Ö');
    assert is_uppercase('T');
}

#[test]
fn test_is_whitespace() {
    assert is_whitespace(' ');
    assert is_whitespace('\u2007');
    assert is_whitespace('\t');
    assert is_whitespace('\n');

    assert !is_whitespace('a');
    assert !is_whitespace('_');
    assert !is_whitespace('\u0000');
}

#[test]
fn test_to_digit() {
    assert to_digit('0', 10u) == Some(0u);
    assert to_digit('1', 2u) == Some(1u);
    assert to_digit('2', 3u) == Some(2u);
    assert to_digit('9', 10u) == Some(9u);
    assert to_digit('a', 16u) == Some(10u);
    assert to_digit('A', 16u) == Some(10u);
    assert to_digit('b', 16u) == Some(11u);
    assert to_digit('B', 16u) == Some(11u);
    assert to_digit('z', 36u) == Some(35u);
    assert to_digit('Z', 36u) == Some(35u);

    assert to_digit(' ', 10u).is_none();
    assert to_digit('$', 36u).is_none();
}

#[test]
fn test_is_ascii() {
   assert str::all(~"banana", char::is_ascii);
   assert ! str::all(~"ประเทศไทย中华Việt Nam", char::is_ascii);
}

#[test]
fn test_is_digit() {
   assert is_digit('2');
   assert is_digit('7');
   assert ! is_digit('c');
   assert ! is_digit('i');
   assert ! is_digit('z');
   assert ! is_digit('Q');
}

#[test]
fn test_escape_default() {
    assert escape_default('\n') == ~"\\n";
    assert escape_default('\r') == ~"\\r";
    assert escape_default('\'') == ~"\\'";
    assert escape_default('"') == ~"\\\"";
    assert escape_default(' ') == ~" ";
    assert escape_default('a') == ~"a";
    assert escape_default('~') == ~"~";
    assert escape_default('\x00') == ~"\\x00";
    assert escape_default('\x1f') == ~"\\x1f";
    assert escape_default('\x7f') == ~"\\x7f";
    assert escape_default('\xff') == ~"\\xff";
    assert escape_default('\u011b') == ~"\\u011b";
    assert escape_default('\U0001d4b6') == ~"\\U0001d4b6";
}

#[test]
fn test_escape_unicode() {
    assert escape_unicode('\x00') == ~"\\x00";
    assert escape_unicode('\n') == ~"\\x0a";
    assert escape_unicode(' ') == ~"\\x20";
    assert escape_unicode('a') == ~"\\x61";
    assert escape_unicode('\u011b') == ~"\\u011b";
    assert escape_unicode('\U0001d4b6') == ~"\\U0001d4b6";
}
<commit_msg>Added char::from_digit(), char::is_digit_radix() and an argument check to char::to_digit().<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Utilities for manipulating the char type

// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

use char;
use cmp::Eq;
use option::{None, Option, Some};
use str;
use u32;
use uint;
use unicode;

/*
    Lu  Uppercase_Letter    an uppercase letter
    Ll  Lowercase_Letter    a lowercase letter
    Lt  Titlecase_Letter    a digraphic character, with first part uppercase
    Lm  Modifier_Letter     a modifier letter
    Lo  Other_Letter    other letters, including syllables and ideographs
    Mn  Nonspacing_Mark     a nonspacing combining mark (zero advance width)
    Mc  Spacing_Mark    a spacing combining mark (positive advance width)
    Me  Enclosing_Mark  an enclosing combining mark
    Nd  Decimal_Number  a decimal digit
    Nl  Letter_Number   a letterlike numeric character
    No  Other_Number    a numeric character of other type
    Pc  Connector_Punctuation   a connecting punctuation mark, like a tie
    Pd  Dash_Punctuation    a dash or hyphen punctuation mark
    Ps  Open_Punctuation    an opening punctuation mark (of a pair)
    Pe  Close_Punctuation   a closing punctuation mark (of a pair)
    Pi  Initial_Punctuation     an initial quotation mark
    Pf  Final_Punctuation   a final quotation mark
    Po  Other_Punctuation   a punctuation mark of other type
    Sm  Math_Symbol     a symbol of primarily mathematical use
    Sc  Currency_Symbol     a currency sign
    Sk  Modifier_Symbol     a non-letterlike modifier symbol
    So  Other_Symbol    a symbol of other type
    Zs  Space_Separator     a space character (of various non-zero widths)
    Zl  Line_Separator  U+2028 LINE SEPARATOR only
    Zp  Paragraph_Separator     U+2029 PARAGRAPH SEPARATOR only
    Cc  Control     a C0 or C1 control code
    Cf  Format  a format control character
    Cs  Surrogate   a surrogate code point
    Co  Private_Use     a private-use character
    Cn  Unassigned  a reserved unassigned code point or a noncharacter
*/

pub use is_alphabetic = unicode::derived_property::Alphabetic;
pub use is_XID_start = unicode::derived_property::XID_Start;
pub use is_XID_continue = unicode::derived_property::XID_Continue;

/**
 * Indicates whether a character is in lower case, defined
 * in terms of the Unicode General Category 'Ll'
 */
#[inline(always)]
pub pure fn is_lowercase(c: char) -> bool {
    return unicode::general_category::Ll(c);
}

/**
 * Indicates whether a character is in upper case, defined
 * in terms of the Unicode General Category 'Lu'.
 */
#[inline(always)]
pub pure fn is_uppercase(c: char) -> bool {
    return unicode::general_category::Lu(c);
}

/**
 * Indicates whether a character is whitespace. Whitespace is defined in
 * terms of the Unicode General Categories 'Zs', 'Zl', 'Zp'
 * additional 'Cc'-category control codes in the range [0x09, 0x0d]
 */
#[inline(always)]
pub pure fn is_whitespace(c: char) -> bool {
    return ('\x09' <= c && c <= '\x0d')
        || unicode::general_category::Zs(c)
        || unicode::general_category::Zl(c)
        || unicode::general_category::Zp(c);
}

/**
 * Indicates whether a character is alphanumeric. Alphanumericness is
 * defined in terms of the Unicode General Categories 'Nd', 'Nl', 'No'
 * and the Derived Core Property 'Alphabetic'.
 */
#[inline(always)]
pub pure fn is_alphanumeric(c: char) -> bool {
    return unicode::derived_property::Alphabetic(c) ||
        unicode::general_category::Nd(c) ||
        unicode::general_category::Nl(c) ||
        unicode::general_category::No(c);
}

/// Indicates whether the character is an ASCII character
#[inline(always)]
pub pure fn is_ascii(c: char) -> bool {
   c - ('\x7F' & c) == '\x00'
}

/// Indicates whether the character is numeric (Nd, Nl, or No)
#[inline(always)]
pub pure fn is_digit(c: char) -> bool {
    return unicode::general_category::Nd(c) ||
        unicode::general_category::Nl(c) ||
        unicode::general_category::No(c);
}

/**
 * Checks if a character parses as a numeric digit in the given radix.
 * Compared to `is_digit()`, this function only recognizes the ascii
 * characters `0-9`, `a-z` and `A-Z`.
 *
 * Returns `true` if `c` is a valid digit under `radix`, and `false`
 * otherwise.
 *
 * Fails if given a `radix` > 36.
 *
 * Note: This just wraps `to_digit()`.
 */
#[inline(always)]
pub pure fn is_digit_radix(c: char, radix: uint) -> bool {
    match to_digit(c, radix) {
        Some(_) => true,
        None    => false
    }
}

/**
 * Convert a char to the corresponding digit.
 *
 * # Return value
 *
 * If `c` is between '0' and '9', the corresponding value
 * between 0 and 9. If `c` is 'a' or 'A', 10. If `c` is
 * 'b' or 'B', 11, etc. Returns none if the char does not
 * refer to a digit in the given radix.
 *
 * # Failure
 * Fails if given a `radix` outside the range `[0..36]`.
 */
#[inline]
pub pure fn to_digit(c: char, radix: uint) -> Option<uint> {
    if radix > 36 {
        fail fmt!("to_digit: radix %? is to high (maximum 36)", radix)
    }
    let val = match c {
      '0' .. '9' => c as uint - ('0' as uint),
      'a' .. 'z' => c as uint + 10u - ('a' as uint),
      'A' .. 'Z' => c as uint + 10u - ('A' as uint),
      _ => return None
    };
    if val < radix { Some(val) }
    else { None }
}

/**
 * Converts a number to the ascii character representing it.
 *
 * Returns `Some(char)` if `num` represents one digit under `radix`,
 * using one character of `0-9` or `a-z`, or `None` if it doesn't.
 *
 * Fails if given an `radix` > 36.
 */
#[inline]
pub pure fn from_digit(num: uint, radix: uint) -> Option<char> {
    if radix > 36 {
        fail fmt!("from_digit: radix %? is to high (maximum 36)", num)
    }
    if num < radix {
        if num < 10 {
            Some(('0' as uint + num) as char)
        } else {
            Some(('a' as uint + num - 10u) as char)
        }
    } else {
        None
    }
}

/**
 * Return the hexadecimal unicode escape of a char.
 *
 * The rules are as follows:
 *
 *   - chars in [0,0xff] get 2-digit escapes: `\\xNN`
 *   - chars in [0x100,0xffff] get 4-digit escapes: `\\uNNNN`
 *   - chars above 0x10000 get 8-digit escapes: `\\UNNNNNNNN`
 */
pub pure fn escape_unicode(c: char) -> ~str {
    let s = u32::to_str(c as u32, 16u);
    let (c, pad) = (if c <= '\xff' { ('x', 2u) }
                    else if c <= '\uffff' { ('u', 4u) }
                    else { ('U', 8u) });
    assert str::len(s) <= pad;
    let mut out = ~"\\";
    unsafe {
        str::push_str(&mut out, str::from_char(c));
        for uint::range(str::len(s), pad) |_i|
            { str::push_str(&mut out, ~"0"); }
        str::push_str(&mut out, s);
    }
    out
}

/**
 * Return a 'default' ASCII and C++11-like char-literal escape of a char.
 *
 * The default is chosen with a bias toward producing literals that are
 * legal in a variety of languages, including C++11 and similar C-family
 * languages. The exact rules are:
 *
 *   - Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
 *   - Single-quote, double-quote and backslash chars are backslash-escaped.
 *   - Any other chars in the range [0x20,0x7e] are not escaped.
 *   - Any other chars are given hex unicode escapes; see `escape_unicode`.
 */
pub pure fn escape_default(c: char) -> ~str {
    match c {
      '\t' => ~"\\t",
      '\r' => ~"\\r",
      '\n' => ~"\\n",
      '\\' => ~"\\\\",
      '\'' => ~"\\'",
      '"'  => ~"\\\"",
      '\x20' .. '\x7e' => str::from_char(c),
      _ => escape_unicode(c)
    }
}

/**
 * Compare two chars
 *
 * # Return value
 *
 * -1 if a < b, 0 if a == b, +1 if a > b
 */
#[inline(always)]
pub pure fn cmp(a: char, b: char) -> int {
    return  if b > a { -1 }
    else if b < a { 1 }
    else { 0 }
}

#[cfg(notest)]
impl char : Eq {
    pure fn eq(&self, other: &char) -> bool { (*self) == (*other) }
    pure fn ne(&self, other: &char) -> bool { (*self) != (*other) }
}

#[test]
fn test_is_lowercase() {
    assert is_lowercase('a');
    assert is_lowercase('ö');
    assert is_lowercase('ß');
    assert !is_lowercase('Ü');
    assert !is_lowercase('P');
}

#[test]
fn test_is_uppercase() {
    assert !is_uppercase('h');
    assert !is_uppercase('ä');
    assert !is_uppercase('ß');
    assert is_uppercase('Ö');
    assert is_uppercase('T');
}

#[test]
fn test_is_whitespace() {
    assert is_whitespace(' ');
    assert is_whitespace('\u2007');
    assert is_whitespace('\t');
    assert is_whitespace('\n');

    assert !is_whitespace('a');
    assert !is_whitespace('_');
    assert !is_whitespace('\u0000');
}

#[test]
fn test_to_digit() {
    assert to_digit('0', 10u) == Some(0u);
    assert to_digit('1', 2u) == Some(1u);
    assert to_digit('2', 3u) == Some(2u);
    assert to_digit('9', 10u) == Some(9u);
    assert to_digit('a', 16u) == Some(10u);
    assert to_digit('A', 16u) == Some(10u);
    assert to_digit('b', 16u) == Some(11u);
    assert to_digit('B', 16u) == Some(11u);
    assert to_digit('z', 36u) == Some(35u);
    assert to_digit('Z', 36u) == Some(35u);

    assert to_digit(' ', 10u).is_none();
    assert to_digit('$', 36u).is_none();
}

#[test]
fn test_is_ascii() {
   assert str::all(~"banana", char::is_ascii);
   assert ! str::all(~"ประเทศไทย中华Việt Nam", char::is_ascii);
}

#[test]
fn test_is_digit() {
   assert is_digit('2');
   assert is_digit('7');
   assert ! is_digit('c');
   assert ! is_digit('i');
   assert ! is_digit('z');
   assert ! is_digit('Q');
}

#[test]
fn test_escape_default() {
    assert escape_default('\n') == ~"\\n";
    assert escape_default('\r') == ~"\\r";
    assert escape_default('\'') == ~"\\'";
    assert escape_default('"') == ~"\\\"";
    assert escape_default(' ') == ~" ";
    assert escape_default('a') == ~"a";
    assert escape_default('~') == ~"~";
    assert escape_default('\x00') == ~"\\x00";
    assert escape_default('\x1f') == ~"\\x1f";
    assert escape_default('\x7f') == ~"\\x7f";
    assert escape_default('\xff') == ~"\\xff";
    assert escape_default('\u011b') == ~"\\u011b";
    assert escape_default('\U0001d4b6') == ~"\\U0001d4b6";
}

#[test]
fn test_escape_unicode() {
    assert escape_unicode('\x00') == ~"\\x00";
    assert escape_unicode('\n') == ~"\\x0a";
    assert escape_unicode(' ') == ~"\\x20";
    assert escape_unicode('a') == ~"\\x61";
    assert escape_unicode('\u011b') == ~"\\u011b";
    assert escape_unicode('\U0001d4b6') == ~"\\U0001d4b6";
}
<|endoftext|>


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

#![feature(unboxed_closures)]
#![feature(core)]

struct Fun<F>(F);

impl<F, T> FnOnce<(T,)> for Fun<F> where F: Fn(T) -> T {
    type Output = T;

    extern "rust-call" fn call_once(self, (t,): (T,)) -> T {
        (self.0)(t)
    }
}

fn main() {
    let fun = Fun(|i: isize| i * 2);
    println!("{}", fun(3));
}
<|endoftext|>


<commit_before><commit_msg>Use std::c_str instead of std::raw<commit_after><|endoftext|>


<commit_before><commit_msg>Add example how to create a task from Rust<commit_after>extern crate task_hookrs;
extern crate chrono;
extern crate serde_json;
extern crate uuid;

use task_hookrs::task::Task;
use task_hookrs::status::TaskStatus;

use chrono::NaiveDateTime;
use serde_json::to_string;
use uuid::Uuid;

fn main() {
    let uuid = Uuid::nil();
    let date = NaiveDateTime::parse_from_str("2016-12-31 12:13:14", "%Y-%m-%d %H:%M:%S").unwrap();
    let t    = Task::new(TaskStatus::Pending, uuid, date.into(), "Test task".to_string(),
    None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,);
    println!("[{}]", to_string(&t).unwrap());
}
<|endoftext|>


<commit_before><commit_msg>Implement Append for hlist<commit_after><|endoftext|>


<commit_before><commit_msg>Add compression example<commit_after>//! Enable compression.
//! The default middleware pipeline supports compression, but is disabled
//! by default.

#![feature(question_mark)]

#[macro_use]
extern crate protocol;

pub const ALGORITHM: protocol::wire::middleware::compression::Algorithm = protocol::wire::middleware::compression::Algorithm::Zlib;

define_packet!(Hello {
    id: i64,
    data: Vec<u8>
});

fn main() {
    use std::net::TcpStream;

    let stream = TcpStream::connect("127.0.0.1:34254").unwrap();
    let mut connection = protocol::wire::stream::Connection::new(stream, protocol::wire::middleware::pipeline::default());

    connection.middleware.compression = protocol::wire::middleware::Compression::Enabled(ALGORITHM);

    connection.send_packet(&Hello { id: 0, data: vec![ 55 ]}).unwrap();

    loop {
        connection.process_incoming_data().unwrap();

        if let Some(response) = connection.receive_packet().unwrap() {
            println!("{:?}", response);
            break;
        }
    }
}

<|endoftext|>


<commit_before><commit_msg>Clean up `read_uint` as in PR #2 (thanks @jkozera)<commit_after><|endoftext|>


<commit_before><commit_msg>add numeric intrinsics<commit_after><|endoftext|>