<commit_before>// Provide standard values for the eight standard colours and custom
// values for up to 256. There are terminals that can do the full RGB
// spectrum, but for something as simple as discerning file types this
// doesn't really seem worth it.

// Bear in mind that the first eight (and their bold variants) are
// user-definable and can look different on different terminals, but
// the other 256 have their values fixed. Prefer using a fixed grey,
// such as Fixed(244), to bold black, as bold black looks really weird
// on some terminals.

pub enum Colour {
    Black, Red, Green, Yellow, Blue, Purple, Cyan, White, Fixed(u8),
}

// These are the standard numeric sequences.
// See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html

impl Colour {
    fn foreground_code(&self) -> String {
        match *self {
            Black => "30".to_string(),
            Red => "31".to_string(),
            Green => "32".to_string(),
            Yellow => "33".to_string(),
            Blue => "34".to_string(),
            Purple => "35".to_string(),
            Cyan => "36".to_string(),
            White => "37".to_string(),
            Fixed(num) => format!("38;5;{}", num),
        }
    }

    fn background_code(&self) -> String {
        match *self {
            Black => "40".to_string(),
            Red => "41".to_string(),
            Green => "42".to_string(),
            Yellow => "43".to_string(),
            Blue => "44".to_string(),
            Purple => "45".to_string(),
            Cyan => "46".to_string(),
            White => "47".to_string(),
            Fixed(num) => format!("48;5;{}", num),
        }
    }
}

// There are only three different styles: plain (no formatting), only
// a foreground colour, and a catch-all for anything more complicated
// than that. It's technically possible to write other cases such as
// "bold foreground", but probably isn't worth writing all the code.

pub enum Style {
    Plain,
    Foreground(Colour),
    Style(StyleStruct),
}

// Having a struct inside an enum is currently unfinished in Rust, but
// should be put in there when that feature is complete.

pub struct StyleStruct {
    foreground: Colour,
    background: Option<Colour>,
    bold: bool,
    underline: bool,
}

impl Style {
    pub fn paint(&self, input: &str) -> String {
        match *self {
            Plain => input.to_string(),
            Foreground(c) => c.paint(input),
            Style(s) => match s {
                StyleStruct { foreground, background, bold, underline } => {
                    let bg = match background {
                        Some(c) => format!("{};", c.background_code()),
                        None => "".to_string()
                    };
                    let bo = if bold { "1;" } else { "" };
                    let un = if underline { "4;" } else { "" };
                    let painted = format!("\x1B[{}{}{}{}m{}\x1B[0m", bo, un, bg, foreground.foreground_code(), input.to_string());
                    return painted.to_string();
                }
            }
        }
    }
}

impl Style {
    pub fn bold(&self) -> Style {
      match *self {
        Plain => Style(StyleStruct         { foreground: White,         background: None,          bold: true, underline: false }),
        Foreground(c) => Style(StyleStruct { foreground: c,             background: None,          bold: true, underline: false }),
        Style(st) => Style(StyleStruct     { foreground: st.foreground, background: st.background, bold: true, underline: false }),
      }
    }

    pub fn underline(&self) -> Style {
      match *self {
        Plain => Style(StyleStruct         { foreground: White,         background: None,          bold: false, underline: true }),
        Foreground(c) => Style(StyleStruct { foreground: c,             background: None,          bold: false, underline: true }),
        Style(st) => Style(StyleStruct     { foreground: st.foreground, background: st.background, bold: false, underline: true }),
      }
    }

    pub fn on(&self, background: Colour) -> Style {
      match *self {
        Plain => Style(StyleStruct         { foreground: White,         background: Some(background), bold: false, underline: false }),
        Foreground(c) => Style(StyleStruct { foreground: c,             background: Some(background), bold: false, underline: false }),
        Style(st) => Style(StyleStruct     { foreground: st.foreground, background: Some(background), bold: false, underline: false }),
      }
    }
}

impl Colour {
    // This is a short-cut so you don't have to use Blue.normal() just
    // to turn Blue into a Style. Annoyingly, this means that Blue and
    // Blue.normal() aren't of the same type, but this hasn't been an
    // issue so far.

    pub fn paint(&self, input: &str) -> String {
        let re = format!("\x1B[{}m{}\x1B[0m", self.foreground_code(), input);
        return re.to_string();
    }

    pub fn underline(&self) -> Style {
        Style(StyleStruct { foreground: *self, background: None, bold: false, underline: true })
    }

    pub fn bold(&self) -> Style {
        Style(StyleStruct { foreground: *self, background: None, bold: true, underline: false })
    }

    pub fn normal(&self) -> Style {
        Style(StyleStruct { foreground: *self, background: None, bold: false, underline: false })
    }

    pub fn on(&self, background: Colour) -> Style {
        Style(StyleStruct { foreground: *self, background: Some(background), bold: false, underline: false })
    }
}

pub fn strip_formatting(input: &String) -> String {
    let re = regex!("\x1B\\[.+?m");
    re.replace_all(input.as_slice(), "").to_string()
}
<commit_msg>Add colour tests<commit_after>// Provide standard values for the eight standard colours and custom
// values for up to 256. There are terminals that can do the full RGB
// spectrum, but for something as simple as discerning file types this
// doesn't really seem worth it.

// Bear in mind that the first eight (and their bold variants) are
// user-definable and can look different on different terminals, but
// the other 256 have their values fixed. Prefer using a fixed grey,
// such as Fixed(244), to bold black, as bold black looks really weird
// on some terminals.

pub enum Colour {
    Black, Red, Green, Yellow, Blue, Purple, Cyan, White, Fixed(u8),
}

// These are the standard numeric sequences.
// See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html

impl Colour {
    fn foreground_code(&self) -> String {
        match *self {
            Black => "30".to_string(),
            Red => "31".to_string(),
            Green => "32".to_string(),
            Yellow => "33".to_string(),
            Blue => "34".to_string(),
            Purple => "35".to_string(),
            Cyan => "36".to_string(),
            White => "37".to_string(),
            Fixed(num) => format!("38;5;{}", num),
        }
    }

    fn background_code(&self) -> String {
        match *self {
            Black => "40".to_string(),
            Red => "41".to_string(),
            Green => "42".to_string(),
            Yellow => "43".to_string(),
            Blue => "44".to_string(),
            Purple => "45".to_string(),
            Cyan => "46".to_string(),
            White => "47".to_string(),
            Fixed(num) => format!("48;5;{}", num),
        }
    }
}

// There are only three different styles: plain (no formatting), only
// a foreground colour, and a catch-all for anything more complicated
// than that. It's technically possible to write other cases such as
// "bold foreground", but probably isn't worth writing all the code.

pub enum Style {
    Plain,
    Foreground(Colour),
    Style(StyleStruct),
}

// Having a struct inside an enum is currently unfinished in Rust, but
// should be put in there when that feature is complete.

pub struct StyleStruct {
    foreground: Colour,
    background: Option<Colour>,
    bold: bool,
    underline: bool,
}

impl Style {
    pub fn paint(&self, input: &str) -> String {
        match *self {
            Plain => input.to_string(),
            Foreground(c) => c.paint(input),
            Style(s) => match s {
                StyleStruct { foreground, background, bold, underline } => {
                    let bg = match background {
                        Some(c) => format!("{};", c.background_code()),
                        None => "".to_string()
                    };
                    let bo = if bold { "1;" } else { "" };
                    let un = if underline { "4;" } else { "" };
                    let painted = format!("\x1B[{}{}{}{}m{}\x1B[0m", bo, un, bg, foreground.foreground_code(), input.to_string());
                    return painted.to_string();
                }
            }
        }
    }
}

impl Style {
    pub fn bold(&self) -> Style {
      match *self {
        Plain => Style(StyleStruct         { foreground: White,         background: None,          bold: true, underline: false }),
        Foreground(c) => Style(StyleStruct { foreground: c,             background: None,          bold: true, underline: false }),
        Style(st) => Style(StyleStruct     { foreground: st.foreground, background: st.background, bold: true, underline: st.underline }),
      }
    }

    pub fn underline(&self) -> Style {
      match *self {
        Plain => Style(StyleStruct         { foreground: White,         background: None,          bold: false,   underline: true }),
        Foreground(c) => Style(StyleStruct { foreground: c,             background: None,          bold: false,   underline: true }),
        Style(st) => Style(StyleStruct     { foreground: st.foreground, background: st.background, bold: st.bold, underline: true }),
      }
    }

    pub fn on(&self, background: Colour) -> Style {
      match *self {
        Plain => Style(StyleStruct         { foreground: White,         background: Some(background), bold: false,   underline: false }),
        Foreground(c) => Style(StyleStruct { foreground: c,             background: Some(background), bold: false,   underline: false }),
        Style(st) => Style(StyleStruct     { foreground: st.foreground, background: Some(background), bold: st.bold, underline: st.underline }),
      }
    }
}

impl Colour {
    // This is a short-cut so you don't have to use Blue.normal() just
    // to turn Blue into a Style. Annoyingly, this means that Blue and
    // Blue.normal() aren't of the same type, but this hasn't been an
    // issue so far.

    pub fn paint(&self, input: &str) -> String {
        let re = format!("\x1B[{}m{}\x1B[0m", self.foreground_code(), input);
        return re.to_string();
    }

    pub fn underline(&self) -> Style {
        Style(StyleStruct { foreground: *self, background: None, bold: false, underline: true })
    }

    pub fn bold(&self) -> Style {
        Style(StyleStruct { foreground: *self, background: None, bold: true, underline: false })
    }

    pub fn normal(&self) -> Style {
        Style(StyleStruct { foreground: *self, background: None, bold: false, underline: false })
    }

    pub fn on(&self, background: Colour) -> Style {
        Style(StyleStruct { foreground: *self, background: Some(background), bold: false, underline: false })
    }
}

pub fn strip_formatting(input: &String) -> String {
    let re = regex!("\x1B\\[.+?m");
    re.replace_all(input.as_slice(), "").to_string()
}

#[test]
fn test_red() {
    let hi = Red.paint("hi");
    assert!(hi == "\x1B[31mhi\x1B[0m".to_string());
}

#[test]
fn test_black() {
    let hi = Black.normal().paint("hi");
    assert!(hi == "\x1B[30mhi\x1B[0m".to_string());
}

#[test]
fn test_yellow_bold() {
    let hi = Yellow.bold().paint("hi");
    assert!(hi == "\x1B[1;33mhi\x1B[0m".to_string());
}

#[test]
fn test_yellow_bold_2() {
    let hi = Yellow.normal().bold().paint("hi");
    assert!(hi == "\x1B[1;33mhi\x1B[0m".to_string());
}

#[test]
fn test_blue_underline() {
    let hi = Blue.underline().paint("hi");
    assert!(hi == "\x1B[4;34mhi\x1B[0m".to_string());
}

#[test]
fn test_green_bold_underline() {
    let hi = Green.bold().underline().paint("hi");
    assert!(hi == "\x1B[1;4;32mhi\x1B[0m".to_string());
}

#[test]
fn test_green_bold_underline_2() {
    let hi = Green.underline().bold().paint("hi");
    assert!(hi == "\x1B[1;4;32mhi\x1B[0m".to_string());
}

#[test]
fn test_purple_on_white() {
    let hi = Purple.on(White).paint("hi");
    assert!(hi == "\x1B[47;35mhi\x1B[0m".to_string());
}

#[test]
fn test_purple_on_white_2() {
    let hi = Purple.normal().on(White).paint("hi");
    assert!(hi == "\x1B[47;35mhi\x1B[0m".to_string());
}

#[test]
fn test_cyan_bold_on_white() {
    let hi = Cyan.bold().on(White).paint("hi");
    assert!(hi == "\x1B[1;47;36mhi\x1B[0m".to_string());
}

#[test]
fn test_cyan_underline_on_white() {
    let hi = Cyan.underline().on(White).paint("hi");
    assert!(hi == "\x1B[4;47;36mhi\x1B[0m".to_string());
}

#[test]
fn test_cyan_bold_underline_on_white() {
    let hi = Cyan.bold().underline().on(White).paint("hi");
    assert!(hi == "\x1B[1;4;47;36mhi\x1B[0m".to_string());
}

#[test]
fn test_cyan_underline_bold_on_white() {
    let hi = Cyan.underline().bold().on(White).paint("hi");
    assert!(hi == "\x1B[1;4;47;36mhi\x1B[0m".to_string());
}

#[test]
fn test_fixed() {
    let hi = Fixed(100).paint("hi");
    assert!(hi == "\x1B[38;5;100mhi\x1B[0m".to_string());
}

#[test]
fn test_fixed_on_purple() {
    let hi = Fixed(100).on(Purple).paint("hi");
    assert!(hi == "\x1B[45;38;5;100mhi\x1B[0m".to_string());
}

#[test]
fn test_fixed_on_fixed() {
    let hi = Fixed(100).on(Fixed(200)).paint("hi");
    assert!(hi == "\x1B[48;5;200;38;5;100mhi\x1B[0m".to_string());
}

<|endoftext|>


<commit_before>use std::collections::VecMap;
use std::io::Read;
use std::fs::File;
use core::Program;
use parse::{parse_program, ProgramErrors};
use error::pretty_print_save_errors;

pub type Save = VecMap<Program>;

pub type SaveErrors = VecMap<ProgramErrors>;

pub fn load_save(filename: &str) -> Option<Save> {
    if let Ok(mut file) = File::open(filename) {
        let mut src = String::new();
        if let Ok(_) = file.read_to_string(&mut src) {
            match parse_save(&src) {
                Ok(save) => Some(save),
                Err(errors) => {
                    pretty_print_save_errors(errors);
                    None
                }
            }
        } else {
            None
        }
    } else {
        None
    }
}

fn parse_save(src: &str) -> Result<Save, SaveErrors> {
    let mut save = VecMap::new();
    let mut errors = VecMap::new();
    let mut prog_src = String::new();
    let mut num = None;

    for line in src.lines() {
        if line.starts_with("@") {
            if let Some(n) = num {
                match parse_program(&prog_src) {
                    Ok(prog) => {
                        save.insert(n, prog);
                    },
                    Err(errs) => {
                        errors.insert(n, errs);
                    },
                };
                prog_src.clear();
            }

            num = line.chars()
                .skip(1)
                .take_while(|c| c.is_numeric())
                .collect::<String>()
                .parse::<usize>()
                .ok();
        } else if num != None {
            prog_src.push_str(line);
        }
    }

    if let Some(n) = num {
        if prog_src.len() > 0 {
            match parse_program(&prog_src) {
                Ok(prog) => {
                    save.insert(n, prog);
                },
                Err(errs) => {
                    errors.insert(n, errs);
                }
            };
            prog_src.clear();
        }
    }

    if errors.len() > 0 {
        Err(errors)
    } else {
        Ok(save)
    }
}
<commit_msg>Reinsert newline when parsing save programs<commit_after>use std::collections::VecMap;
use std::io::Read;
use std::fs::File;
use core::Program;
use parse::{parse_program, ProgramErrors};
use error::pretty_print_save_errors;

pub type Save = VecMap<Program>;

pub type SaveErrors = VecMap<ProgramErrors>;

pub fn load_save(filename: &str) -> Option<Save> {
    if let Ok(mut file) = File::open(filename) {
        let mut src = String::new();
        if let Ok(_) = file.read_to_string(&mut src) {
            match parse_save(&src) {
                Ok(save) => Some(save),
                Err(errors) => {
                    pretty_print_save_errors(errors);
                    None
                }
            }
        } else {
            None
        }
    } else {
        None
    }
}

fn parse_save(src: &str) -> Result<Save, SaveErrors> {
    let mut save = VecMap::new();
    let mut errors = VecMap::new();
    let mut prog_src = String::new();
    let mut num = None;

    for line in src.lines() {
        if line.starts_with("@") {
            if let Some(n) = num {
                match parse_program(&prog_src) {
                    Ok(prog) => {
                        save.insert(n, prog);
                    },
                    Err(errs) => {
                        errors.insert(n, errs);
                    },
                };
                prog_src.clear();
            }

            num = line.chars()
                .skip(1)
                .take_while(|c| c.is_numeric())
                .collect::<String>()
                .parse::<usize>()
                .ok();
        } else if num != None {
            prog_src.push_str(line);
            prog_src.push('\n');
        }
    }

    if let Some(n) = num {
        if prog_src.len() > 0 {
            match parse_program(&prog_src) {
                Ok(prog) => {
                    save.insert(n, prog);
                },
                Err(errs) => {
                    errors.insert(n, errs);
                }
            };
            prog_src.clear();
        }
    }

    if errors.len() > 0 {
        Err(errors)
    } else {
        Ok(save)
    }
}
<|endoftext|>


<commit_before>use std::sync::mpsc;
use std::ptr;

use Display;

use libc;
use context;
use gl;

/// Provides a way to wait for a server-side operation to be finished.
///
/// Creating a `SyncFence` injects an element in the commands queue of the backend.
/// When this element is reached, the fence becomes signaled.
///
/// ## Example
///
/// ```no_run
/// # let display: glium::Display = unsafe { std::mem::uninitialized() };
/// # fn do_something<T>(_: &T) {}
/// let fence = glium::SyncFence::new_if_supported(&display).unwrap();
/// do_something(&display);
/// fence.wait();   // blocks until the previous operations have finished
/// ```
pub struct SyncFence {
    display: Display,
    id: Option<gl::types::GLsync>,
}

impl SyncFence {
    /// Builds a new `SyncFence` that is injected in the server.
    ///
    /// ## Features
    ///
    /// Only available if the `gl_sync` feature is enabled.
    #[cfg(feature = "gl_sync")]
    pub fn new(display: &Display) -> SyncFence {
        SyncFence::new_if_supported(display).unwrap()
    }

    /// Builds a new `SyncFence` that is injected in the server.
    ///
    /// Returns `None` is this is not supported by the backend.
    pub fn new_if_supported(display: &Display) -> Option<SyncFence> {
        let (tx, rx) = mpsc::channel();

        display.context.context.exec(move |: mut ctxt| {
            tx.send(unsafe { new_linear_sync_fence_if_supported(&mut ctxt) }).unwrap();
        });

        rx.recv().unwrap().map(|f| f.into_sync_fence(display))
    }

    /// Blocks until the operation has finished on the server.
    pub fn wait(mut self) {
        let sync = ptr::Unique(self.id.take().unwrap() as *mut libc::c_void);
        let (tx, rx) = mpsc::channel();

        self.display.context.context.exec(move |: ctxt| {
            unsafe {
                // waiting with a deadline of one year
                // the reason why the deadline is so long is because if you attach a GL debugger,
                // the wait can be blocked during a breaking point of the debugger
                let result = ctxt.gl.ClientWaitSync(sync.0 as gl::types::GLsync,
                                                    gl::SYNC_FLUSH_COMMANDS_BIT,
                                                    365 * 24 * 3600 * 1000 * 1000 * 1000);
                tx.send(result).unwrap();
                ctxt.gl.DeleteSync(sync.0 as gl::types::GLsync);
            }
        });

        match rx.recv().unwrap() {
            gl::ALREADY_SIGNALED | gl::CONDITION_SATISFIED => (),
            _ => panic!("Could not wait for the fence")
        };
    }
}

impl Drop for SyncFence {
    fn drop(&mut self) {
        let sync = match self.id {
            None => return,     // fence has already been deleted
            Some(s) => ptr::Unique(s as *mut libc::c_void)
        };

        self.display.context.context.exec(move |: ctxt| {
            unsafe {
                ctxt.gl.DeleteSync(sync.0 as gl::types::GLsync);
            }
        });
    }
}

/// Prototype for a `SyncFence`.
///
/// The fence must be consumed with either `into_sync_fence`, otherwise
/// the destructor will panic.
#[must_use]
pub struct LinearSyncFence {
    id: Option<gl::types::GLsync>,
}

unsafe impl Send for LinearSyncFence {}

impl LinearSyncFence {
    /// Turns the prototype into a real fence.
    pub fn into_sync_fence(mut self, display: &Display) -> SyncFence {
        SyncFence {
            display: display.clone(),
            id: self.id.take()
        }
    }
}

impl Drop for LinearSyncFence {
    fn drop(&mut self) {
        assert!(self.id.is_none());
    }
}

#[cfg(feature = "gl_sync")]
pub unsafe fn new_linear_sync_fence(ctxt: &mut context::CommandContext) -> LinearSyncFence {
    LinearSyncFence {
        id: Some(ctxt.gl.FenceSync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0)),
    }
}

pub unsafe fn new_linear_sync_fence_if_supported(ctxt: &mut context::CommandContext) -> Option<LinearSyncFence> {
    if ctxt.version < &context::GlVersion(3, 2) && !ctxt.extensions.gl_arb_sync {
        return None;
    }

    Some(LinearSyncFence {
        id: Some(ctxt.gl.FenceSync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0)),
    })
}

/// Waits for this fence and destroys it, from within the commands context.
pub unsafe fn wait_linear_sync_fence_and_drop(mut fence: LinearSyncFence, ctxt: &mut context::CommandContext) {
    let fence = fence.id.take().unwrap();
    ctxt.gl.ClientWaitSync(fence, gl::SYNC_FLUSH_COMMANDS_BIT,
                           365 * 24 * 3600 * 1000 * 1000 * 1000);
    ctxt.gl.DeleteSync(fence);
}
<commit_msg>Try waiting on the fence without flushing first<commit_after>use std::sync::mpsc;
use std::ptr;

use Display;

use libc;
use context;
use gl;

/// Provides a way to wait for a server-side operation to be finished.
///
/// Creating a `SyncFence` injects an element in the commands queue of the backend.
/// When this element is reached, the fence becomes signaled.
///
/// ## Example
///
/// ```no_run
/// # let display: glium::Display = unsafe { std::mem::uninitialized() };
/// # fn do_something<T>(_: &T) {}
/// let fence = glium::SyncFence::new_if_supported(&display).unwrap();
/// do_something(&display);
/// fence.wait();   // blocks until the previous operations have finished
/// ```
pub struct SyncFence {
    display: Display,
    id: Option<gl::types::GLsync>,
}

impl SyncFence {
    /// Builds a new `SyncFence` that is injected in the server.
    ///
    /// ## Features
    ///
    /// Only available if the `gl_sync` feature is enabled.
    #[cfg(feature = "gl_sync")]
    pub fn new(display: &Display) -> SyncFence {
        SyncFence::new_if_supported(display).unwrap()
    }

    /// Builds a new `SyncFence` that is injected in the server.
    ///
    /// Returns `None` is this is not supported by the backend.
    pub fn new_if_supported(display: &Display) -> Option<SyncFence> {
        let (tx, rx) = mpsc::channel();

        display.context.context.exec(move |: mut ctxt| {
            tx.send(unsafe { new_linear_sync_fence_if_supported(&mut ctxt) }).unwrap();
        });

        rx.recv().unwrap().map(|f| f.into_sync_fence(display))
    }

    /// Blocks until the operation has finished on the server.
    pub fn wait(mut self) {
        let sync = ptr::Unique(self.id.take().unwrap() as *mut libc::c_void);
        let (tx, rx) = mpsc::channel();

        self.display.context.context.exec(move |: ctxt| {
            unsafe {
                // waiting with a deadline of one year
                // the reason why the deadline is so long is because if you attach a GL debugger,
                // the wait can be blocked during a breaking point of the debugger
                let result = ctxt.gl.ClientWaitSync(sync.0 as gl::types::GLsync,
                                                    gl::SYNC_FLUSH_COMMANDS_BIT,
                                                    365 * 24 * 3600 * 1000 * 1000 * 1000);
                tx.send(result).unwrap();
                ctxt.gl.DeleteSync(sync.0 as gl::types::GLsync);
            }
        });

        match rx.recv().unwrap() {
            gl::ALREADY_SIGNALED | gl::CONDITION_SATISFIED => (),
            _ => panic!("Could not wait for the fence")
        };
    }
}

impl Drop for SyncFence {
    fn drop(&mut self) {
        let sync = match self.id {
            None => return,     // fence has already been deleted
            Some(s) => ptr::Unique(s as *mut libc::c_void)
        };

        self.display.context.context.exec(move |: ctxt| {
            unsafe {
                ctxt.gl.DeleteSync(sync.0 as gl::types::GLsync);
            }
        });
    }
}

/// Prototype for a `SyncFence`.
///
/// The fence must be consumed with either `into_sync_fence`, otherwise
/// the destructor will panic.
#[must_use]
pub struct LinearSyncFence {
    id: Option<gl::types::GLsync>,
}

unsafe impl Send for LinearSyncFence {}

impl LinearSyncFence {
    /// Turns the prototype into a real fence.
    pub fn into_sync_fence(mut self, display: &Display) -> SyncFence {
        SyncFence {
            display: display.clone(),
            id: self.id.take()
        }
    }
}

impl Drop for LinearSyncFence {
    fn drop(&mut self) {
        assert!(self.id.is_none());
    }
}

#[cfg(feature = "gl_sync")]
pub unsafe fn new_linear_sync_fence(ctxt: &mut context::CommandContext) -> LinearSyncFence {
    LinearSyncFence {
        id: Some(ctxt.gl.FenceSync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0)),
    }
}

pub unsafe fn new_linear_sync_fence_if_supported(ctxt: &mut context::CommandContext) -> Option<LinearSyncFence> {
    if ctxt.version < &context::GlVersion(3, 2) && !ctxt.extensions.gl_arb_sync {
        return None;
    }

    Some(LinearSyncFence {
        id: Some(ctxt.gl.FenceSync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0)),
    })
}

/// Waits for this fence and destroys it, from within the commands context.
pub unsafe fn wait_linear_sync_fence_and_drop(mut fence: LinearSyncFence, ctxt: &mut context::CommandContext) {
    let fence = fence.id.take().unwrap();

    // we try waiting without flushing first
    let success = match ctxt.gl.ClientWaitSync(fence, 0, 0) {
        gl::ALREADY_SIGNALED => true,
        gl::TIMEOUT_EXPIRED => false,
        gl::WAIT_FAILED => false,
        gl::CONDITION_SATISFIED => true,
        _ => unreachable!()
    };

    // waiting *with* flushing this time
    if !success {
        ctxt.gl.ClientWaitSync(fence, gl::SYNC_FLUSH_COMMANDS_BIT,
                               365 * 24 * 3600 * 1000 * 1000 * 1000);
    }

    ctxt.gl.DeleteSync(fence);
}
<|endoftext|>


<commit_before>// TODO
// should directly test the plugins, because why not?
// maybe ladspa should have some testing facilities built in.

use super::get_ladspa_descriptor;
use ladspa::{Data, Port, PortConnection, PortData};
use std::cell::RefCell;
use std::thread;
use std::time::Duration;

const SAMPLE_RATE: u64 = 44100;

// TODO this port connection stuff is a mess because the Plugin trait in ladspa is too specific.
// it would be a breaking change to fix it, but should be done at some point because this is nuts.

#[derive(Debug)]
enum OwnedPortData {
    AudioInput(Vec<Data>),
    AudioOutput(Vec<Data>),
    ControlInput(Data),
    ControlOutput(Data),
}

impl PartialEq for OwnedPortData {
    fn eq(&self, other: &Self) -> bool {
        use self::OwnedPortData::*;

        match *self {
            AudioInput(ref a) | AudioOutput(ref a) => {
                match *other {
                    AudioInput(ref b) | AudioOutput(ref b) => a == b,
                    _ => false,
                }
            }
            ControlInput(ref a) | ControlOutput(ref a) => {
                match *other {
                    ControlInput(ref b) | ControlOutput(ref b) => a == b,
                    _ => false,
                }
            }
        }
    }
}

struct OwnedPortConnection {
    port: Port,
    data: OwnedPortData,
}

fn make_owned_port_connections(ports: &[Port], size: usize) -> Vec<OwnedPortConnection> {
    use ladspa::PortDescriptor::*;

    let mut out = Vec::new();
    for port in ports {
        let data = match port.desc {
            AudioInput => OwnedPortData::AudioInput(vec![0.0; size]),
            AudioOutput => OwnedPortData::AudioOutput(vec![0.0; size]),
            ControlInput => OwnedPortData::ControlInput(0.0),
            ControlOutput => OwnedPortData::ControlOutput(0.0),
            Invalid => panic!(),
        };
        out.push(OwnedPortConnection {
            port: port.clone(),
            data: data,
        });
    }
    out
}

trait Tagged {
    fn set_tags(&mut self, port_tag: f32, input_tag: f32, output_tag: f32);
}

impl Tagged for Vec<OwnedPortConnection> {
    fn set_tags(&mut self, port_tag: f32, input_tag: f32, output_tag: f32) {
        use self::OwnedPortData::*;

        for port in self {
            match port.data {
                AudioInput(ref mut v) => {
                    for x in v.iter_mut() {
                        *x = input_tag;
                    }
                }
                AudioOutput(ref mut v) => {
                    for x in v.iter_mut() {
                        *x = output_tag;
                    }
                }
                ControlInput(ref mut x) => {
                    match port.port.name {
                        "Channel" => *x = port_tag,
                        _ => *x = 0.0,
                    }
                }
                ControlOutput(ref mut x) => {
                    *x = 0.0;
                }
            }
        }
    }
}

fn make_port_connections<'a>(owned: &'a mut [OwnedPortConnection]) -> Vec<PortConnection<'a>> {
    let mut out = Vec::new();
    for port in owned {
        let data = match port.data {
            OwnedPortData::AudioInput(ref data) => PortData::AudioInput(data),
            OwnedPortData::AudioOutput(ref mut data) => PortData::AudioOutput(RefCell::new(data)),
            OwnedPortData::ControlInput(ref data) => PortData::ControlInput(data),
            OwnedPortData::ControlOutput(ref mut data) => {
                PortData::ControlOutput(RefCell::new(data))
            }
        };

        out.push(PortConnection {
            port: port.port,
            data: data,
        });
    }
    out
}

fn borrow_port_connections<'a>(ports: &'a [PortConnection<'a>]) -> Vec<&'a PortConnection<'a>> {
    ports.iter().map(|x| x).collect()
}

#[test]
fn test_working_basic() {
    let sample_count = super::packet::BUFFER_SIZE;
    test_sample_count(sample_count, 0);
}

#[test]
fn test_working_multi_packet() {
    let sample_count = super::packet::BUFFER_SIZE * 32;
    test_sample_count(sample_count, 1);
}

fn test_sample_count(sample_count: usize, port: u8) {
    let tx_desc = get_ladspa_descriptor(0).unwrap();
    let rx_desc = get_ladspa_descriptor(1).unwrap();
    let mut tx = (tx_desc.new)(&tx_desc, SAMPLE_RATE);
    let mut rx = (rx_desc.new)(&rx_desc, SAMPLE_RATE);

    rx.activate();
    tx.activate();

    let mut tx_owned = make_owned_port_connections(&tx_desc.ports, sample_count);
    tx_owned.set_tags(port as f32, 1.0, 0.0);
    let mut rx_owned = make_owned_port_connections(&rx_desc.ports, sample_count);
    rx_owned.set_tags(port as f32, 0.0, 0.0);

    // run once to handle channel change
    {
        let tx_ports = make_port_connections(&mut tx_owned);
        let rx_ports = make_port_connections(&mut rx_owned);
        let tx_ports = borrow_port_connections(&tx_ports);
        let rx_ports = borrow_port_connections(&rx_ports);

        rx.run(sample_count, &rx_ports);
        tx.run(sample_count, &tx_ports);
    }

    // reset state
    rx.deactivate();
    tx.deactivate();
    rx.activate();
    thread::sleep(Duration::from_millis(100));
    tx.activate();
    thread::sleep(Duration::from_millis(100));

    tx_owned.set_tags(port as f32, 1.0, 0.0);
    rx_owned.set_tags(port as f32, 0.0, 0.0);

    // run again to do the computation
    {
        let tx_ports = make_port_connections(&mut tx_owned);
        let rx_ports = make_port_connections(&mut rx_owned);
        let tx_ports = borrow_port_connections(&tx_ports);
        let rx_ports = borrow_port_connections(&rx_ports);

        tx.run(sample_count, &tx_ports);
        thread::sleep(Duration::from_millis(100)); // wait for recv
        rx.run(sample_count, &rx_ports);
    }

    for i in 0..2 {
        assert_eq!(tx_owned[i].data, rx_owned[i + 2].data);
    }

    rx.deactivate();
    tx.deactivate();
}
<commit_msg>Fix testing and add new failing tests for odd buffer sizes, although the tests are probably wrong and the code is fine<commit_after>// TODO
// should directly test the plugins, because why not?
// maybe ladspa should have some testing facilities built in.

use super::get_ladspa_descriptor;
use ladspa::{Data, Port, PortConnection, PortData};
use std::cell::RefCell;
use std::thread;
use std::time::Duration;

const SAMPLE_RATE: u64 = 44100;

// TODO this port connection stuff is a mess because the Plugin trait in ladspa is too specific.
// it would be a breaking change to fix it, but should be done at some point because this is nuts.

#[derive(Debug)]
enum OwnedPortData {
    AudioInput(Vec<Data>),
    AudioOutput(Vec<Data>),
    ControlInput(Data),
    ControlOutput(Data),
}

impl PartialEq for OwnedPortData {
    fn eq(&self, other: &Self) -> bool {
        use self::OwnedPortData::*;

        match *self {
            AudioInput(ref a) | AudioOutput(ref a) => {
                match *other {
                    AudioInput(ref b) | AudioOutput(ref b) => a == b,
                    _ => false,
                }
            }
            ControlInput(ref a) | ControlOutput(ref a) => {
                match *other {
                    ControlInput(ref b) | ControlOutput(ref b) => a == b,
                    _ => false,
                }
            }
        }
    }
}

struct OwnedPortConnection {
    port: Port,
    data: OwnedPortData,
}

fn make_owned_port_connections(ports: &[Port], size: usize) -> Vec<OwnedPortConnection> {
    use ladspa::PortDescriptor::*;

    let mut out = Vec::new();
    for port in ports {
        let data = match port.desc {
            AudioInput => OwnedPortData::AudioInput(vec![0.0; size]),
            AudioOutput => OwnedPortData::AudioOutput(vec![0.0; size]),
            ControlInput => OwnedPortData::ControlInput(0.0),
            ControlOutput => OwnedPortData::ControlOutput(0.0),
            Invalid => panic!(),
        };
        out.push(OwnedPortConnection {
            port: port.clone(),
            data: data,
        });
    }
    out
}

trait Tagged {
    fn set_tags(&mut self, port_tag: f32, input_tag: f32, output_tag: f32);
}

impl Tagged for Vec<OwnedPortConnection> {
    fn set_tags(&mut self, port_tag: f32, input_tag: f32, output_tag: f32) {
        use self::OwnedPortData::*;

        for port in self {
            match port.data {
                AudioInput(ref mut v) => {
                    for x in v.iter_mut() {
                        *x = input_tag;
                    }
                }
                AudioOutput(ref mut v) => {
                    for x in v.iter_mut() {
                        *x = output_tag;
                    }
                }
                ControlInput(ref mut x) => {
                    match port.port.name {
                        "Channel" => *x = port_tag,
                        _ => *x = 1.0,
                    }
                }
                ControlOutput(ref mut x) => {
                    *x = 0.0;
                }
            }
        }
    }
}

fn make_port_connections<'a>(owned: &'a mut [OwnedPortConnection]) -> Vec<PortConnection<'a>> {
    let mut out = Vec::new();
    for port in owned {
        let data = match port.data {
            OwnedPortData::AudioInput(ref data) => PortData::AudioInput(data),
            OwnedPortData::AudioOutput(ref mut data) => PortData::AudioOutput(RefCell::new(data)),
            OwnedPortData::ControlInput(ref data) => PortData::ControlInput(data),
            OwnedPortData::ControlOutput(ref mut data) => {
                PortData::ControlOutput(RefCell::new(data))
            }
        };

        out.push(PortConnection {
            port: port.port,
            data: data,
        });
    }
    out
}

fn borrow_port_connections<'a>(ports: &'a [PortConnection<'a>]) -> Vec<&'a PortConnection<'a>> {
    ports.iter().map(|x| x).collect()
}

#[test]
fn test_working_basic() {
    let sample_count = super::packet::BUFFER_SIZE;
    test_sample_count(sample_count, 0);
}

#[test]
fn test_working_multi_packet() {
    let sample_count = super::packet::BUFFER_SIZE * 32;
    test_sample_count(sample_count, 1);
}

#[test]
fn test_working_odd_sample_number_small() {
    let sample_count = super::packet::BUFFER_SIZE * 2 - 15;
    test_sample_count(sample_count, 2);
}

#[test]
fn test_working_odd_sample_number_large() {
    let sample_count = super::packet::BUFFER_SIZE + 15;
    test_sample_count(sample_count, 3);
}

fn test_sample_count(sample_count: usize, port: u8) {
    let tx_desc = get_ladspa_descriptor(0).unwrap();
    let rx_desc = get_ladspa_descriptor(1).unwrap();
    let mut tx = (tx_desc.new)(&tx_desc, SAMPLE_RATE);
    let mut rx = (rx_desc.new)(&rx_desc, SAMPLE_RATE);

    rx.activate();
    tx.activate();

    let mut tx_owned = make_owned_port_connections(&tx_desc.ports, sample_count);
    tx_owned.set_tags(port as f32, 1.0, 0.0);
    let mut rx_owned = make_owned_port_connections(&rx_desc.ports, sample_count);
    rx_owned.set_tags(port as f32, 0.0, 0.0);

    // run once to handle channel change
    {
        let tx_ports = make_port_connections(&mut tx_owned);
        let rx_ports = make_port_connections(&mut rx_owned);
        let tx_ports = borrow_port_connections(&tx_ports);
        let rx_ports = borrow_port_connections(&rx_ports);

        rx.run(sample_count, &rx_ports);
        tx.run(sample_count, &tx_ports);
    }

    // reset state
    rx.deactivate();
    tx.deactivate();
    rx.activate();
    thread::sleep(Duration::from_millis(100));
    tx.activate();
    thread::sleep(Duration::from_millis(100));

    tx_owned.set_tags(port as f32, 1.0, 0.0);
    rx_owned.set_tags(port as f32, 0.0, 0.0);

    // run again to do the computation
    {
        let tx_ports = make_port_connections(&mut tx_owned);
        let rx_ports = make_port_connections(&mut rx_owned);
        let tx_ports = borrow_port_connections(&tx_ports);
        let rx_ports = borrow_port_connections(&rx_ports);

        tx.run(sample_count, &tx_ports);
        thread::sleep(Duration::from_millis(100)); // wait for recv
        rx.run(sample_count, &rx_ports);
    }

    for i in 0..2 {
        assert_eq!(tx_owned[i].data, rx_owned[i + 2].data);
    }

    rx.deactivate();
    tx.deactivate();
}
<|endoftext|>


<commit_before>use openssl::ssl::{self, SslMethod, SslConnectorBuilder};
use std::io::{Read, Write};
use std::net::{TcpStream, TcpListener};
use std::thread;

use super::*;

#[test]
fn connect_google() {
    let builder = TlsConnector::builder().unwrap().build().unwrap();
    let s = TcpStream::connect("google.com:443").unwrap();
    let mut socket = builder.connect("google.com", s).unwrap();

    socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
    let mut result = vec![];
    socket.read_to_end(&mut result).unwrap();

    println!("{}", String::from_utf8_lossy(&result));
    assert!(result.starts_with(b"HTTP/1.0"));
    assert!(result.ends_with(b"\r\n") || result.ends_with(b""));
}

#[test]
fn connect_bad_hostname() {
    let builder = TlsConnector::builder().unwrap().build().unwrap();
    let s = TcpStream::connect("wrong.host.badssl.com:443").unwrap();
    assert!(builder.connect("wrong.host.badssl.com", s).is_err());
}

#[test]
fn server() {
    let buf = include_bytes!("../test/identity.p12");
    let pkcs12 = Pkcs12::from_der(buf, "mypass").unwrap();
    let builder = TlsAcceptor::builder(pkcs12).unwrap().build().unwrap();

    let listener = TcpListener::bind("0.0.0.0:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    thread::spawn(move || {
        let socket = listener.accept().unwrap().0;
        let mut socket = builder.accept(socket).unwrap();

        let mut buf = [0; 5];
        socket.read_exact(&mut buf).unwrap();
        assert_eq!(&buf, b"hello");

        socket.write_all(b"world").unwrap();
    });

    let socket = TcpStream::connect(("localhost", port)).unwrap();
    let mut builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
    builder.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
    let connector = builder.build();
    let mut socket = connector.connect("foobar.com", socket).unwrap();
    println!("{}", socket.ssl().current_cipher().unwrap().description());
    socket.write_all(b"hello").unwrap();
    let mut buf = vec![];
    socket.read_to_end(&mut buf).unwrap();
    assert_eq!(buf, b"world");
}

#[test]
fn server_tls11_only() {
    let buf = include_bytes!("../test/identity.p12");
    let pkcs12 = Pkcs12::from_der(buf, "mypass").unwrap();
    let mut builder = TlsAcceptor::builder(pkcs12).unwrap();
    builder.supported_protocols(&[Protocol::Tlsv11]).unwrap();
    let builder = builder.build().unwrap();

    let listener = TcpListener::bind("0.0.0.0:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    let j = thread::spawn(move || {
        let socket = listener.accept().unwrap().0;
        let mut socket = builder.accept(socket).unwrap();

        let mut buf = [0; 5];
        socket.read_exact(&mut buf).unwrap();
        assert_eq!(&buf, b"hello");

        socket.write_all(b"world").unwrap();
        socket.shutdown().unwrap();
    });

    let socket = TcpStream::connect(("localhost", port)).unwrap();
    let mut builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
    builder.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
    let options = ssl::SSL_OP_NO_SSLV3 | ssl::SSL_OP_NO_TLSV1 | ssl::SSL_OP_NO_TLSV1_2;
    builder.builder_mut().set_options(options);
    let connector = builder.build();
    let mut socket = connector.connect("foobar.com", socket).unwrap();
    println!("{}", socket.ssl().current_cipher().unwrap().description());
    socket.write_all(b"hello").unwrap();
    let mut buf = vec![];
    socket.read_to_end(&mut buf).unwrap();
    assert_eq!(buf, b"world");
    socket.shutdown().unwrap();

    j.join().unwrap();
}

#[test]
fn server_no_shared_protocol() {
    let buf = include_bytes!("../test/identity.p12");
    let pkcs12 = Pkcs12::from_der(buf, "mypass").unwrap();
    let mut builder = TlsAcceptor::builder(pkcs12).unwrap();
    builder.supported_protocols(&[Protocol::Tlsv11]).unwrap();
    let builder = builder.build().unwrap();

    let listener = TcpListener::bind("0.0.0.0:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    let j = thread::spawn(move || {
        let socket = listener.accept().unwrap().0;
        assert!(builder.accept(socket).is_err());
    });

    let socket = TcpStream::connect(("localhost", port)).unwrap();
    let mut builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
    builder.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
    let options = ssl::SSL_OP_NO_SSLV3 | ssl::SSL_OP_NO_TLSV1 | ssl::SSL_OP_NO_TLSV1_1;
    builder.builder_mut().set_options(options);
    let connector = builder.build();
    assert!(connector.connect("foobar.com", socket).is_err());

    j.join().unwrap();
}
<commit_msg>Make a more careful shutdown test<commit_after>use openssl::ssl::{self, SslMethod, SslConnectorBuilder};
use std::io::{Read, Write};
use std::net::{TcpStream, TcpListener};
use std::thread;

use super::*;

#[test]
fn connect_google() {
    let builder = TlsConnector::builder().unwrap().build().unwrap();
    let s = TcpStream::connect("google.com:443").unwrap();
    let mut socket = builder.connect("google.com", s).unwrap();

    socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
    let mut result = vec![];
    socket.read_to_end(&mut result).unwrap();

    println!("{}", String::from_utf8_lossy(&result));
    assert!(result.starts_with(b"HTTP/1.0"));
    assert!(result.ends_with(b"\r\n") || result.ends_with(b""));
}

#[test]
fn connect_bad_hostname() {
    let builder = TlsConnector::builder().unwrap().build().unwrap();
    let s = TcpStream::connect("wrong.host.badssl.com:443").unwrap();
    assert!(builder.connect("wrong.host.badssl.com", s).is_err());
}

#[test]
fn server() {
    let buf = include_bytes!("../test/identity.p12");
    let pkcs12 = Pkcs12::from_der(buf, "mypass").unwrap();
    let builder = TlsAcceptor::builder(pkcs12).unwrap().build().unwrap();

    let listener = TcpListener::bind("0.0.0.0:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    thread::spawn(move || {
        let socket = listener.accept().unwrap().0;
        let mut socket = builder.accept(socket).unwrap();

        let mut buf = [0; 5];
        socket.read_exact(&mut buf).unwrap();
        assert_eq!(&buf, b"hello");

        socket.write_all(b"world").unwrap();
    });

    let socket = TcpStream::connect(("localhost", port)).unwrap();
    let mut builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
    builder.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
    let connector = builder.build();
    let mut socket = connector.connect("foobar.com", socket).unwrap();
    println!("{}", socket.ssl().current_cipher().unwrap().description());
    socket.write_all(b"hello").unwrap();
    let mut buf = vec![];
    socket.read_to_end(&mut buf).unwrap();
    assert_eq!(buf, b"world");
}

#[test]
fn server_tls11_only() {
    let buf = include_bytes!("../test/identity.p12");
    let pkcs12 = Pkcs12::from_der(buf, "mypass").unwrap();
    let mut builder = TlsAcceptor::builder(pkcs12).unwrap();
    builder.supported_protocols(&[Protocol::Tlsv11]).unwrap();
    let builder = builder.build().unwrap();

    let listener = TcpListener::bind("0.0.0.0:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    let j = thread::spawn(move || {
        let socket = listener.accept().unwrap().0;
        let mut socket = builder.accept(socket).unwrap();

        let mut buf = [0; 5];
        socket.read_exact(&mut buf).unwrap();
        assert_eq!(&buf, b"hello");

        socket.write_all(b"world").unwrap();
    });

    let socket = TcpStream::connect(("localhost", port)).unwrap();
    let mut builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
    builder.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
    let options = ssl::SSL_OP_NO_SSLV3 | ssl::SSL_OP_NO_TLSV1 | ssl::SSL_OP_NO_TLSV1_2;
    builder.builder_mut().set_options(options);
    let connector = builder.build();
    let mut socket = connector.connect("foobar.com", socket).unwrap();
    println!("{}", socket.ssl().current_cipher().unwrap().description());
    socket.write_all(b"hello").unwrap();
    let mut buf = vec![];
    socket.read_to_end(&mut buf).unwrap();
    assert_eq!(buf, b"world");

    j.join().unwrap();
}

#[test]
fn server_no_shared_protocol() {
    let buf = include_bytes!("../test/identity.p12");
    let pkcs12 = Pkcs12::from_der(buf, "mypass").unwrap();
    let mut builder = TlsAcceptor::builder(pkcs12).unwrap();
    builder.supported_protocols(&[Protocol::Tlsv11]).unwrap();
    let builder = builder.build().unwrap();

    let listener = TcpListener::bind("0.0.0.0:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    let j = thread::spawn(move || {
        let socket = listener.accept().unwrap().0;
        assert!(builder.accept(socket).is_err());
    });

    let socket = TcpStream::connect(("localhost", port)).unwrap();
    let mut builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
    builder.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
    let options = ssl::SSL_OP_NO_SSLV3 | ssl::SSL_OP_NO_TLSV1 | ssl::SSL_OP_NO_TLSV1_1;
    builder.builder_mut().set_options(options);
    let connector = builder.build();
    assert!(connector.connect("foobar.com", socket).is_err());

    j.join().unwrap();
}

#[test]
fn shutdown() {
    let buf = include_bytes!("../test/identity.p12");
    let pkcs12 = Pkcs12::from_der(buf, "mypass").unwrap();
    let builder = TlsAcceptor::builder(pkcs12).unwrap().build().unwrap();

    let listener = TcpListener::bind("0.0.0.0:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    let j = thread::spawn(move || {
        let socket = listener.accept().unwrap().0;
        let mut socket = builder.accept(socket).unwrap();

        let mut buf = [0; 5];
        socket.read_exact(&mut buf).unwrap();
        assert_eq!(&buf, b"hello");

        assert_eq!(socket.read(&mut buf).unwrap(), 0);
    });

    let socket = TcpStream::connect(("localhost", port)).unwrap();
    let mut builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
    builder.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
    let connector = builder.build();
    let mut socket = connector.connect("foobar.com", socket).unwrap();
    println!("{}", socket.ssl().current_cipher().unwrap().description());
    socket.write_all(b"hello").unwrap();
    socket.shutdown().unwrap();

    j.join().unwrap();
}
<|endoftext|>


<commit_before>use std::f64::consts::PI;
use std::num::Float;
use std::num::FloatMath;

#[deriving(Copy)]
pub struct SineWave(pub f64);

impl Fn<(f64, ), f64> for SineWave {
    extern "rust-call" fn call(&self, (t, ): (f64, )) -> f64 {
        let SineWave(frequency) = *self;
        FloatMath::sin(t * frequency * 2.0 * PI)
    }
}

#[deriving(Copy)]
pub struct SquareWave(pub f64);

impl Fn<(f64, ), f64> for SquareWave {
    extern "rust-call" fn call(&self, (t, ): (f64, )) -> f64 {
        let SquareWave(frequency) = *self;
        let sin_wave = SineWave(frequency);
        if sin_wave(t).is_positive() { 1.0 } else { -1.0 }
    }
}

#[deriving(Copy)]
pub struct SawtoothWave(pub f64);

impl Fn<(f64, ), f64> for SawtoothWave {
    extern "rust-call" fn call(&self, (t, ): (f64, )) -> f64 {
        let SawtoothWave(frequency) = *self;
        let t_factor = t * frequency;
        t_factor - t_factor.floor() - 0.5
    }
}

#[deriving(Copy)]
pub struct TriangleWave(pub f64);

impl Fn<(f64, ), f64> for TriangleWave {
    extern "rust-call" fn call(&self, (t, ): (f64, )) -> f64 {
        let TriangleWave(frequency) = *self;
        let sawtooth_wave = SawtoothWave(frequency);
        (sawtooth_wave(t).abs() - 0.25) * 4.0
    }
}

#[deriving(Copy)]
pub struct TangentWave(pub f64);

impl Fn<(f64, ), f64> for TangentWave {
    extern "rust-call" fn call(&self, (t, ): (f64, )) -> f64 {
        let TangentWave(frequency) = *self;
        FloatMath::tan(t * frequency * PI)
    }
}

#[deriving(Copy)]
// http://computermusicresource.com/Simple.bell.tutorial.html
pub struct Bell(pub f64, pub f64, pub f64);

impl Fn<(f64, ), f64> for Bell {
    extern "rust-call" fn call(&self, (t, ): (f64, )) -> f64 {
        let Bell(frequency, attack, decay) = *self;

        let envelope = |t: f64, f: f64| -> f64 {
            let tf = t / f;
            if tf < attack {
                (tf / attack).min(1.0)
            } else {
                (1.0 - (tf / decay)).max(0.0)
            }
        };

        let h1 = SineWave(frequency * 0.56);
        let h2 = SineWave(frequency * 0.92);
        let h3 = SineWave(frequency * 1.19);
        let h4 = SineWave(frequency * 1.71);
        let h5 = SineWave(frequency * 2.00);
        let h6 = SineWave(frequency * 2.74);
        let h7 = SineWave(frequency * 3.00);
        let h8 = SineWave(frequency * 3.76);
        let h9 = SineWave(frequency * 4.07);

        (h1(t) * 1.0 * envelope(t, 1.0) +
         h2(t) * 0.5 * envelope(t, 2.0) +
         h3(t) * 0.25 * envelope(t, 4.0) +
         h4(t) * 0.125 * envelope(t, 6.0) +
         h5(t) * 0.0625 * envelope(t, 8.4) +
         h6(t) * 0.03125 * envelope(t, 10.8) +
         h7(t) * 0.015625 * envelope(t, 13.6) +
         h8(t) * 0.0078125 * envelope(t, 16.4) +
         h9(t) * 0.00390625 * envelope(t, 19.6)) / 2.0
    }
}
<commit_msg>Clip TangentWave to [-1.0, 1.0] so peak normalization works<commit_after>use std::f64::consts::PI;
use std::num::Float;
use std::num::FloatMath;

#[deriving(Copy)]
pub struct SineWave(pub f64);

impl Fn<(f64, ), f64> for SineWave {
    extern "rust-call" fn call(&self, (t, ): (f64, )) -> f64 {
        let SineWave(frequency) = *self;
        FloatMath::sin(t * frequency * 2.0 * PI)
    }
}

#[deriving(Copy)]
pub struct SquareWave(pub f64);

impl Fn<(f64, ), f64> for SquareWave {
    extern "rust-call" fn call(&self, (t, ): (f64, )) -> f64 {
        let SquareWave(frequency) = *self;
        let sin_wave = SineWave(frequency);
        if sin_wave(t).is_positive() { 1.0 } else { -1.0 }
    }
}

#[deriving(Copy)]
pub struct SawtoothWave(pub f64);

impl Fn<(f64, ), f64> for SawtoothWave {
    extern "rust-call" fn call(&self, (t, ): (f64, )) -> f64 {
        let SawtoothWave(frequency) = *self;
        let t_factor = t * frequency;
        t_factor - t_factor.floor() - 0.5
    }
}

#[deriving(Copy)]
pub struct TriangleWave(pub f64);

impl Fn<(f64, ), f64> for TriangleWave {
    extern "rust-call" fn call(&self, (t, ): (f64, )) -> f64 {
        let TriangleWave(frequency) = *self;
        let sawtooth_wave = SawtoothWave(frequency);
        (sawtooth_wave(t).abs() - 0.25) * 4.0
    }
}

#[deriving(Copy)]
pub struct TangentWave(pub f64);

impl Fn<(f64, ), f64> for TangentWave {
    extern "rust-call" fn call(&self, (t, ): (f64, )) -> f64 {
        let TangentWave(frequency) = *self;
        FloatMath::tan(t * frequency * PI).max(0.0).min(1.0)
    }
}

#[deriving(Copy)]
// http://computermusicresource.com/Simple.bell.tutorial.html
pub struct Bell(pub f64, pub f64, pub f64);

impl Fn<(f64, ), f64> for Bell {
    extern "rust-call" fn call(&self, (t, ): (f64, )) -> f64 {
        let Bell(frequency, attack, decay) = *self;

        let envelope = |t: f64, f: f64| -> f64 {
            let tf = t / f;
            if tf < attack {
                (tf / attack).min(1.0)
            } else {
                (1.0 - (tf / decay)).max(0.0)
            }
        };

        let h1 = SineWave(frequency * 0.56);
        let h2 = SineWave(frequency * 0.92);
        let h3 = SineWave(frequency * 1.19);
        let h4 = SineWave(frequency * 1.71);
        let h5 = SineWave(frequency * 2.00);
        let h6 = SineWave(frequency * 2.74);
        let h7 = SineWave(frequency * 3.00);
        let h8 = SineWave(frequency * 3.76);
        let h9 = SineWave(frequency * 4.07);

        (h1(t) * 1.0 * envelope(t, 1.0) +
         h2(t) * 0.5 * envelope(t, 2.0) +
         h3(t) * 0.25 * envelope(t, 4.0) +
         h4(t) * 0.125 * envelope(t, 6.0) +
         h5(t) * 0.0625 * envelope(t, 8.4) +
         h6(t) * 0.03125 * envelope(t, 10.8) +
         h7(t) * 0.015625 * envelope(t, 13.6) +
         h8(t) * 0.0078125 * envelope(t, 16.4) +
         h9(t) * 0.00390625 * envelope(t, 19.6)) / 2.0
    }
}
<|endoftext|>


<commit_before>//#![feature(custom_derive, plugin, test)]
//#![feature(custom_attribute)]
//#![plugin(serde_macros)]

//extern crate serde;
//extern crate serde_xml;

use std::collections::HashMap;

use futures::{Future, Poll};
use futures::stream::Stream;

//use tokio_core::io::{copy, Io};
use tokio_core::net::{TcpStream};
//use tokio_core::reactor::Core;

use data::Data;

struct XmlParser {

}

// Helpful typedefs for the values read in and out of the list.
type Ser<D> = Box<Fn(D)       -> Option<Vec<u8>>>;
type De<D>  = Box<Fn(Vec<u8>) -> Option<D>>;

/// This will contain a hashmap for the possible XML messages / formats.
/// Type 'D' for the Data type which will be returned by the function
/// passed in via HashMap.
struct XmlStream<D> {
    stream: TcpStream,
    id: String,
    host: String,
    ser: HashMap<String, Ser<D>>, // probably will want to use slices here instead.
    de: HashMap<String, De<D>>,
}

impl<D> XmlStream<D> {

}

impl<D> Stream for XmlStream<D> {
    type Item = Data;
    type Error = Result<(), ()>;
    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        Err(Err(())) // uhhh fix this l8er
    }
}

<commit_msg>Next: Custom parsing for attributes!<commit_after>// TODO: Implement reading XmlStream struct: An absraction over a TCP stream
//       sending data back and forth, handling all setup beyond binding the
//       tokio_core::net::TcpStream struct.

use std::collections::HashMap;

use std::io::{Read, Write};

use futures::{Future, Poll};
use futures::stream::Stream;

use serde_xml::from_str;
use serde_xml::value::{Element, from_value};
use serde_xml::Error;

/// This will contain a hashmap for the possible XML messages / formats.
/// Type 'D' for the Data type which will be returned by the function
/// passed in via HashMap.
struct XmlStream<S> where S : Read + Write {
    stream: S,
    stanzas: Vec<String>, // Describes the various types of messages.
}

// Note:
// XmlStreams will be unaware of domains, as domains are a characteristic of
// network streams, an XmlStream should be looked at as a (asynch?) parser.

impl<S> XmlStream<S> where S : Read + Write {
    /// Consumes a stream for the purpose of reading a 'stream' of XML elements
    /// sent from a client.
    fn new(stream : S) -> XmlStream<S> {
        XmlStream {
            stream: stream,
            stanzas: vec![],
        }
    }
}

//impl<S> Read

impl<S> Stream for XmlStream<S> where S : Read + Write {
    type Item = String;
    type Error = String;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        Err("Nope".to_string()) // uhhh fix this l8er
    }
}

// -- Old code:
// Helpful typedefs for the values read in and out of the list.
//type Ser<D> = Box<Fn(D)       -> Option<Vec<u8>>>;
//type De<D>  = Box<Fn(Vec<u8>) -> Option<D>>;

<|endoftext|>


<commit_before>use decoders::Image;
use imageops::fcol;

pub fn whitebalance(img: &Image, inb: &[f32]) -> Vec<f32> {
  let mut out: Vec<f32> = vec![0.0; (img.width*img.height) as usize];

  let max: f32 = img.wb_coeffs.iter().fold(0.0, |acc, &x| acc.max(x));
  let mul = img.wb_coeffs.iter().map(|x| if x.is_nan() { 1.0 } else { x / max }).collect::<Vec<f32>>();

  let mut pos = 0;
  for row in 0..img.height {
    for col in 0..img.width {
      let pixel = inb[pos];
      let color = fcol(img, row, col);
      out[pos] = pixel * mul[color];
      pos += 1;
    }
  }

  out
}
<commit_msg>demosaic: apply multipliers with green=1.0<commit_after>use decoders::Image;
use imageops::fcol;

pub fn whitebalance(img: &Image, inb: &[f32]) -> Vec<f32> {
  let mut out: Vec<f32> = vec![0.0; (img.width*img.height) as usize];

  // Set green multiplier as 1.0
  let unity: f32 = img.wb_coeffs[1];
  let mul = img.wb_coeffs.iter().map(|x| if x.is_nan() { 1.0 } else { x / unity }).collect::<Vec<f32>>();

  let mut pos = 0;
  for row in 0..img.height {
    for col in 0..img.width {
      let pixel = inb[pos];
      let color = fcol(img, row, col);
      out[pos] = pixel * mul[color];
      pos += 1;
    }
  }

  out
}
<|endoftext|>


<commit_before>pub trait Response: Clone + Send {}
<commit_msg>(feat) Added Response trait, limited by rust-http.<commit_after>use http::server::response::ResponseWriter;
use http::server::request::Request;
use http::headers::response::HeaderCollection;
use http::status::Status;

pub trait Response: Writer {
    fn request_mut<'a>(&'a self) -> &'a mut Request;
    fn headers_mut<'a>(&'a self) -> &'a mut Box<HeaderCollection>;
    fn status_mut<'a>(&'a self) -> &'a mut Status;

    fn request<'a>(&'a self) -> &'a Request;
    fn headers<'a>(&'a self) -> &'a HeaderCollection;
    fn status<'a>(&'a self) -> Status;

    fn from_http(&ResponseWriter) -> Self;
    fn to_http(&self, &mut ResponseWriter);
}
<|endoftext|>


<commit_before>use crate::consts::{constant, Constant};
use crate::utils::{is_direct_expn_of, is_expn_of, match_panic_call, snippet_opt, span_lint_and_help};
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
use rustc_hir::{Expr, ExprKind, PatKind, UnOp};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for `assert!(true)` and `assert!(false)` calls.
    ///
    /// **Why is this bad?** Will be optimized out by the compiler or should probably be replaced by a
    /// `panic!()` or `unreachable!()`
    ///
    /// **Known problems:** None
    ///
    /// **Example:**
    /// ```rust,ignore
    /// assert!(false)
    /// assert!(true)
    /// const B: bool = false;
    /// assert!(B)
    /// ```
    pub ASSERTIONS_ON_CONSTANTS,
    style,
    "`assert!(true)` / `assert!(false)` will be optimized out by the compiler, and should probably be replaced by a `panic!()` or `unreachable!()`"
}

declare_lint_pass!(AssertionsOnConstants => [ASSERTIONS_ON_CONSTANTS]);

impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
        let lint_true = |is_debug: bool| {
            span_lint_and_help(
                cx,
                ASSERTIONS_ON_CONSTANTS,
                e.span,
                if is_debug {
                    "`debug_assert!(true)` will be optimized out by the compiler"
                } else {
                    "`assert!(true)` will be optimized out by the compiler"
                },
                None,
                "remove it",
            );
        };
        let lint_false_without_message = || {
            span_lint_and_help(
                cx,
                ASSERTIONS_ON_CONSTANTS,
                e.span,
                "`assert!(false)` should probably be replaced",
                None,
                "use `panic!()` or `unreachable!()`",
            );
        };
        let lint_false_with_message = |panic_message: String| {
            span_lint_and_help(
                cx,
                ASSERTIONS_ON_CONSTANTS,
                e.span,
                &format!("`assert!(false, {})` should probably be replaced", panic_message),
                None,
                &format!("use `panic!({})` or `unreachable!({})`", panic_message, panic_message),
            )
        };

        if let Some(debug_assert_span) = is_expn_of(e.span, "debug_assert") {
            if debug_assert_span.from_expansion() {
                return;
            }
            if_chain! {
                if let ExprKind::Unary(_, ref lit) = e.kind;
                if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.typeck_results(), lit);
                if is_true;
                then {
                    lint_true(true);
                }
            };
        } else if let Some(assert_span) = is_direct_expn_of(e.span, "assert") {
            if assert_span.from_expansion() {
                return;
            }
            if let Some(assert_match) = match_assert_with_message(&cx, e) {
                match assert_match {
                    // matched assert but not message
                    AssertKind::WithoutMessage(false) => lint_false_without_message(),
                    AssertKind::WithoutMessage(true) | AssertKind::WithMessage(_, true) => lint_true(false),
                    AssertKind::WithMessage(panic_message, false) => lint_false_with_message(panic_message),
                };
            }
        }
    }
}

/// Result of calling `match_assert_with_message`.
enum AssertKind {
    WithMessage(String, bool),
    WithoutMessage(bool),
}

/// Check if the expression matches
///
/// ```rust,ignore
/// match { let _t = !c; _t } {
///     true => {
///         {
///             ::std::rt::begin_panic(message, _)
///         }
///     }
///     _ => { }
/// };
/// ```
///
/// where `message` is any expression and `c` is a constant bool.
fn match_assert_with_message<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<AssertKind> {
    if_chain! {
        if let ExprKind::Match(ref expr, ref arms, _) = expr.kind;
        // matches { let _t = expr; _t }
        if let ExprKind::DropTemps(ref expr) = expr.kind;
        if let ExprKind::Unary(UnOp::UnNot, ref expr) = expr.kind;
        // bind the first argument of the `assert!` macro
        if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.typeck_results(), expr);
        // arm 1 pattern
        if let PatKind::Lit(ref lit_expr) = arms[0].pat.kind;
        if let ExprKind::Lit(ref lit) = lit_expr.kind;
        if let LitKind::Bool(true) = lit.node;
        // arm 1 block
        if let ExprKind::Block(ref block, _) = arms[0].body.kind;
        if block.stmts.is_empty();
        if let Some(block_expr) = &block.expr;
        // inner block is optional. unwarp it if it exists, or use the expression as is otherwise.
        if let Some(begin_panic_call) = match block_expr.kind {
            ExprKind::Block(ref inner_block, _) => &inner_block.expr,
            _ => &block.expr,
        };
        // function call
        if let Some(args) = match_panic_call(cx, begin_panic_call);
        if args.len() == 1;
        // bind the second argument of the `assert!` macro if it exists
        if let panic_message = snippet_opt(cx, args[0].span);
        // second argument of begin_panic is irrelevant
        // as is the second match arm
        then {
            // an empty message occurs when it was generated by the macro
            // (and not passed by the user)
            return panic_message
                .filter(|msg| !msg.is_empty())
                .map(|msg| AssertKind::WithMessage(msg, is_true))
                .or(Some(AssertKind::WithoutMessage(is_true)));
        }
    }
    None
}
<commit_msg>a typo<commit_after>use crate::consts::{constant, Constant};
use crate::utils::{is_direct_expn_of, is_expn_of, match_panic_call, snippet_opt, span_lint_and_help};
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
use rustc_hir::{Expr, ExprKind, PatKind, UnOp};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for `assert!(true)` and `assert!(false)` calls.
    ///
    /// **Why is this bad?** Will be optimized out by the compiler or should probably be replaced by a
    /// `panic!()` or `unreachable!()`
    ///
    /// **Known problems:** None
    ///
    /// **Example:**
    /// ```rust,ignore
    /// assert!(false)
    /// assert!(true)
    /// const B: bool = false;
    /// assert!(B)
    /// ```
    pub ASSERTIONS_ON_CONSTANTS,
    style,
    "`assert!(true)` / `assert!(false)` will be optimized out by the compiler, and should probably be replaced by a `panic!()` or `unreachable!()`"
}

declare_lint_pass!(AssertionsOnConstants => [ASSERTIONS_ON_CONSTANTS]);

impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
        let lint_true = |is_debug: bool| {
            span_lint_and_help(
                cx,
                ASSERTIONS_ON_CONSTANTS,
                e.span,
                if is_debug {
                    "`debug_assert!(true)` will be optimized out by the compiler"
                } else {
                    "`assert!(true)` will be optimized out by the compiler"
                },
                None,
                "remove it",
            );
        };
        let lint_false_without_message = || {
            span_lint_and_help(
                cx,
                ASSERTIONS_ON_CONSTANTS,
                e.span,
                "`assert!(false)` should probably be replaced",
                None,
                "use `panic!()` or `unreachable!()`",
            );
        };
        let lint_false_with_message = |panic_message: String| {
            span_lint_and_help(
                cx,
                ASSERTIONS_ON_CONSTANTS,
                e.span,
                &format!("`assert!(false, {})` should probably be replaced", panic_message),
                None,
                &format!("use `panic!({})` or `unreachable!({})`", panic_message, panic_message),
            )
        };

        if let Some(debug_assert_span) = is_expn_of(e.span, "debug_assert") {
            if debug_assert_span.from_expansion() {
                return;
            }
            if_chain! {
                if let ExprKind::Unary(_, ref lit) = e.kind;
                if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.typeck_results(), lit);
                if is_true;
                then {
                    lint_true(true);
                }
            };
        } else if let Some(assert_span) = is_direct_expn_of(e.span, "assert") {
            if assert_span.from_expansion() {
                return;
            }
            if let Some(assert_match) = match_assert_with_message(&cx, e) {
                match assert_match {
                    // matched assert but not message
                    AssertKind::WithoutMessage(false) => lint_false_without_message(),
                    AssertKind::WithoutMessage(true) | AssertKind::WithMessage(_, true) => lint_true(false),
                    AssertKind::WithMessage(panic_message, false) => lint_false_with_message(panic_message),
                };
            }
        }
    }
}

/// Result of calling `match_assert_with_message`.
enum AssertKind {
    WithMessage(String, bool),
    WithoutMessage(bool),
}

/// Check if the expression matches
///
/// ```rust,ignore
/// match { let _t = !c; _t } {
///     true => {
///         {
///             ::std::rt::begin_panic(message, _)
///         }
///     }
///     _ => { }
/// };
/// ```
///
/// where `message` is any expression and `c` is a constant bool.
fn match_assert_with_message<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<AssertKind> {
    if_chain! {
        if let ExprKind::Match(ref expr, ref arms, _) = expr.kind;
        // matches { let _t = expr; _t }
        if let ExprKind::DropTemps(ref expr) = expr.kind;
        if let ExprKind::Unary(UnOp::UnNot, ref expr) = expr.kind;
        // bind the first argument of the `assert!` macro
        if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.typeck_results(), expr);
        // arm 1 pattern
        if let PatKind::Lit(ref lit_expr) = arms[0].pat.kind;
        if let ExprKind::Lit(ref lit) = lit_expr.kind;
        if let LitKind::Bool(true) = lit.node;
        // arm 1 block
        if let ExprKind::Block(ref block, _) = arms[0].body.kind;
        if block.stmts.is_empty();
        if let Some(block_expr) = &block.expr;
        // inner block is optional. unwrap it if it exists, or use the expression as is otherwise.
        if let Some(begin_panic_call) = match block_expr.kind {
            ExprKind::Block(ref inner_block, _) => &inner_block.expr,
            _ => &block.expr,
        };
        // function call
        if let Some(args) = match_panic_call(cx, begin_panic_call);
        if args.len() == 1;
        // bind the second argument of the `assert!` macro if it exists
        if let panic_message = snippet_opt(cx, args[0].span);
        // second argument of begin_panic is irrelevant
        // as is the second match arm
        then {
            // an empty message occurs when it was generated by the macro
            // (and not passed by the user)
            return panic_message
                .filter(|msg| !msg.is_empty())
                .map(|msg| AssertKind::WithMessage(msg, is_true))
                .or(Some(AssertKind::WithoutMessage(is_true)));
        }
    }
    None
}
<|endoftext|>