<commit_before>extern crate libc;

use std::io::Write;
use std::path::Path;

/// Takes a user-supplied string and tries to parse to u16 mode bitmask.
pub fn parse(mode_string: &str, considering_dir: bool) -> Result<libc::mode_t, String> {
    let numbers: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];

    // Passing 000 as the existing permissions seems to mirror GNU behaviour.
    if mode_string.contains(numbers) {
        chmod_rs::parse_numeric(0, mode_string)
    } else {
        chmod_rs::parse_symbolic(0, mode_string, considering_dir)
    }
}

/// chmod a file or directory on UNIX.
///
/// Adapted from mkdir.rs.  Handles own error printing.
///
#[cfg(unix)]
pub fn chmod(path: &Path, mode: libc::mode_t) -> Result<(), ()> {
    use std::ffi::CString;
    use std::io::Error;

    let file = CString::new(path.as_os_str().to_str().unwrap()).
                            unwrap_or_else(|e| crash!(1, "{}", e));
    let mode = mode as libc::mode_t;

    if unsafe { libc::chmod(file.as_ptr(), mode) } != 0 {
        show_info!("{}: chmod failed with errno {}", path.display(),
                   Error::last_os_error().raw_os_error().unwrap());
        return Err(());
    }
    Ok(())
}

/// chmod a file or directory on Windows.
///
/// Adapted from mkdir.rs.
///
#[cfg(windows)]
pub fn chmod(path: &Path, mode: libc::mode_t) -> Result<(), ()> {
    // chmod on Windows only sets the readonly flag, which isn't even honored on directories
    Ok(())
}

/// Parsing functions taken from chmod.rs.
///
/// We keep these in a dedicated module to minimize debt of duplicated code.
///
mod chmod_rs {
    extern crate libc;

    pub fn parse_numeric(fperm: libc::mode_t, mut mode: &str) -> Result<libc::mode_t, String> {
        let (op, pos) = try!(parse_op(mode, Some('=')));
        mode = mode[pos..].trim_left_matches('0');
        if mode.len() > 4 {
            Err(format!("mode is too large ({} > 7777)", mode))
        } else {
            match libc::mode_t::from_str_radix(mode, 8) {
                Ok(change) => {
                    Ok(match op {
                        '+' => fperm | change,
                        '-' => fperm & !change,
                        '=' => change,
                        _ => unreachable!()
                    })
                }
                Err(err) => Err(String::from("numeric parsing error"))
            }
        }
    }

    pub fn parse_symbolic(mut fperm: libc::mode_t, mut mode: &str, considering_dir: bool) -> Result<libc::mode_t, String> {
        let (mask, pos) = parse_levels(mode);
        if pos == mode.len() {
            return Err(format!("invalid mode ({})", mode));
        }
        let respect_umask = pos == 0;
        let last_umask = unsafe {
            libc::umask(0)
        };
        mode = &mode[pos..];
        while mode.len() > 0 {
            let (op, pos) = try!(parse_op(mode, None));
            mode = &mode[pos..];
            let (mut srwx, pos) = parse_change(mode, fperm, considering_dir);
            if respect_umask {
                srwx &= !last_umask;
            }
            mode = &mode[pos..];
            match op {
                '+' => fperm |= srwx & mask,
                '-' => fperm &= !(srwx & mask),
                '=' => fperm = (fperm & !mask) | (srwx & mask),
                _ => unreachable!()
            }
        }
        unsafe {
            libc::umask(last_umask);
        }
        Ok(fperm)
    }

    fn parse_levels(mode: &str) -> (libc::mode_t, usize) {
        let mut mask = 0;
        let mut pos = 0;
        for ch in mode.chars() {
            mask |= match ch {
                'u' => 0o7700,
                'g' => 0o7070,
                'o' => 0o7007,
                'a' => 0o7777,
                _ => break
            };
            pos += 1;
        }
        if pos == 0 {
            mask = 0o7777;  // default to 'a'
        }
        (mask, pos)
    }

    fn parse_op(mode: &str, default: Option<char>) -> Result<(char, usize), String> {
        match mode.chars().next() {
            Some(ch) => match ch {
                '+' | '-' | '=' => Ok((ch, 1)),
                _ => match default {
                    Some(ch) => Ok((ch, 0)),
                    None => Err(format!("invalid operator (expected +, -, or =, but found {})", ch))
                }
            },
            None => Err("unexpected end of mode".to_owned())
        }
    }

    fn parse_change(mode: &str, fperm: libc::mode_t, considering_dir: bool) -> (libc::mode_t, usize) {
        let mut srwx = fperm & 0o7000;
        let mut pos = 0;
        for ch in mode.chars() {
            match ch {
                'r' => srwx |= 0o444,
                'w' => srwx |= 0o222,
                'x' => srwx |= 0o111,
                'X' => {
                    if considering_dir || (fperm & 0o0111) != 0 {
                        srwx |= 0o111
                    }
                }
                's' => srwx |= 0o4000 | 0o2000,
                't' => srwx |= 0o1000,
                'u' => srwx = (fperm & 0o700) | ((fperm >> 3) & 0o070) | ((fperm >> 6) & 0o007),
                'g' => srwx = ((fperm << 3) & 0o700) | (fperm & 0o070) | ((fperm >> 3) & 0o007),
                'o' => srwx = ((fperm << 6) & 0o700) | ((fperm << 3) & 0o070) | (fperm & 0o007),
                _ => break
            };
            pos += 1;
        }
        if pos == 0 {
            srwx = 0;
        }
        (srwx, pos)
    }
}
<commit_msg>Remove unused variable binding.<commit_after>extern crate libc;

use std::io::Write;
use std::path::Path;

/// Takes a user-supplied string and tries to parse to u16 mode bitmask.
pub fn parse(mode_string: &str, considering_dir: bool) -> Result<libc::mode_t, String> {
    let numbers: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];

    // Passing 000 as the existing permissions seems to mirror GNU behaviour.
    if mode_string.contains(numbers) {
        chmod_rs::parse_numeric(0, mode_string)
    } else {
        chmod_rs::parse_symbolic(0, mode_string, considering_dir)
    }
}

/// chmod a file or directory on UNIX.
///
/// Adapted from mkdir.rs.  Handles own error printing.
///
#[cfg(unix)]
pub fn chmod(path: &Path, mode: libc::mode_t) -> Result<(), ()> {
    use std::ffi::CString;
    use std::io::Error;

    let file = CString::new(path.as_os_str().to_str().unwrap()).
                            unwrap_or_else(|e| crash!(1, "{}", e));
    let mode = mode as libc::mode_t;

    if unsafe { libc::chmod(file.as_ptr(), mode) } != 0 {
        show_info!("{}: chmod failed with errno {}", path.display(),
                   Error::last_os_error().raw_os_error().unwrap());
        return Err(());
    }
    Ok(())
}

/// chmod a file or directory on Windows.
///
/// Adapted from mkdir.rs.
///
#[cfg(windows)]
pub fn chmod(path: &Path, mode: libc::mode_t) -> Result<(), ()> {
    // chmod on Windows only sets the readonly flag, which isn't even honored on directories
    Ok(())
}

/// Parsing functions taken from chmod.rs.
///
/// We keep these in a dedicated module to minimize debt of duplicated code.
///
mod chmod_rs {
    extern crate libc;

    pub fn parse_numeric(fperm: libc::mode_t, mut mode: &str) -> Result<libc::mode_t, String> {
        let (op, pos) = try!(parse_op(mode, Some('=')));
        mode = mode[pos..].trim_left_matches('0');
        if mode.len() > 4 {
            Err(format!("mode is too large ({} > 7777)", mode))
        } else {
            match libc::mode_t::from_str_radix(mode, 8) {
                Ok(change) => {
                    Ok(match op {
                        '+' => fperm | change,
                        '-' => fperm & !change,
                        '=' => change,
                        _ => unreachable!()
                    })
                }
                Err(_) => Err(String::from("numeric parsing error"))
            }
        }
    }

    pub fn parse_symbolic(mut fperm: libc::mode_t, mut mode: &str, considering_dir: bool) -> Result<libc::mode_t, String> {
        let (mask, pos) = parse_levels(mode);
        if pos == mode.len() {
            return Err(format!("invalid mode ({})", mode));
        }
        let respect_umask = pos == 0;
        let last_umask = unsafe {
            libc::umask(0)
        };
        mode = &mode[pos..];
        while mode.len() > 0 {
            let (op, pos) = try!(parse_op(mode, None));
            mode = &mode[pos..];
            let (mut srwx, pos) = parse_change(mode, fperm, considering_dir);
            if respect_umask {
                srwx &= !last_umask;
            }
            mode = &mode[pos..];
            match op {
                '+' => fperm |= srwx & mask,
                '-' => fperm &= !(srwx & mask),
                '=' => fperm = (fperm & !mask) | (srwx & mask),
                _ => unreachable!()
            }
        }
        unsafe {
            libc::umask(last_umask);
        }
        Ok(fperm)
    }

    fn parse_levels(mode: &str) -> (libc::mode_t, usize) {
        let mut mask = 0;
        let mut pos = 0;
        for ch in mode.chars() {
            mask |= match ch {
                'u' => 0o7700,
                'g' => 0o7070,
                'o' => 0o7007,
                'a' => 0o7777,
                _ => break
            };
            pos += 1;
        }
        if pos == 0 {
            mask = 0o7777;  // default to 'a'
        }
        (mask, pos)
    }

    fn parse_op(mode: &str, default: Option<char>) -> Result<(char, usize), String> {
        match mode.chars().next() {
            Some(ch) => match ch {
                '+' | '-' | '=' => Ok((ch, 1)),
                _ => match default {
                    Some(ch) => Ok((ch, 0)),
                    None => Err(format!("invalid operator (expected +, -, or =, but found {})", ch))
                }
            },
            None => Err("unexpected end of mode".to_owned())
        }
    }

    fn parse_change(mode: &str, fperm: libc::mode_t, considering_dir: bool) -> (libc::mode_t, usize) {
        let mut srwx = fperm & 0o7000;
        let mut pos = 0;
        for ch in mode.chars() {
            match ch {
                'r' => srwx |= 0o444,
                'w' => srwx |= 0o222,
                'x' => srwx |= 0o111,
                'X' => {
                    if considering_dir || (fperm & 0o0111) != 0 {
                        srwx |= 0o111
                    }
                }
                's' => srwx |= 0o4000 | 0o2000,
                't' => srwx |= 0o1000,
                'u' => srwx = (fperm & 0o700) | ((fperm >> 3) & 0o070) | ((fperm >> 6) & 0o007),
                'g' => srwx = ((fperm << 3) & 0o700) | (fperm & 0o070) | ((fperm >> 3) & 0o007),
                'o' => srwx = ((fperm << 6) & 0o700) | ((fperm << 3) & 0o070) | (fperm & 0o007),
                _ => break
            };
            pos += 1;
        }
        if pos == 0 {
            srwx = 0;
        }
        (srwx, pos)
    }
}
<|endoftext|>


<commit_before>use std::mem;
use rand::{Rng, SeedableRng};
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use serde::de::impls::VecVisitor;
use serde::de::Error;
use to_log_odds;

/// Additional methods for random number generators.
pub trait RngExt {
    /// Return true with 50 % probability.
    fn coinflip(&mut self) -> bool;

    /// Return true with probability 1 / n.
    fn one_chance_in(&mut self, n: u32) -> bool;

    /// Return true with p probability.
    fn with_chance(&mut self, p: f32) -> bool;

    /// Return a log odds deciban score that corresponds to a random
    /// probability from [0, 1].
    ///
    fn log_odds(&mut self) -> f32;

    /// Return true with the probability corresponding to the log odds with
    /// the given deciban value.
    fn with_log_odds(&mut self, db: f32) -> bool;
}

impl<T: Rng> RngExt for T {
    fn coinflip(&mut self) -> bool {
        self.gen_weighted_bool(2)
    }

    fn one_chance_in(&mut self, n: u32) -> bool {
        self.gen_weighted_bool(n)
    }

    fn with_chance(&mut self, p: f32) -> bool {
        self.gen_range(0.0, 1.0) < p
    }

    fn log_odds(&mut self) -> f32 {
        to_log_odds(self.gen_range(0.0, 1.0))
    }

    fn with_log_odds(&mut self, db: f32) -> bool {
        db > self.log_odds()
    }
}

/// A wrapper that makes a Rng implementation encodable.
///
/// For games that want to store the current Rng state as a part of the save
/// game. Works by casting the Rng representation into a binary blob, will
/// crash and burn if the Rng struct is not plain-old-data.
pub struct EncodeRng<T> {
    inner: T,
}

impl<T: Rng+'static> EncodeRng<T> {
    pub fn new(inner: T) -> EncodeRng<T> {
        EncodeRng { inner: inner }
    }
}

impl<T: SeedableRng<S>+Rng+'static, S> SeedableRng<S> for EncodeRng<T> {
    fn reseed(&mut self, seed: S) {
        self.inner.reseed(seed);
    }

    fn from_seed(seed: S) -> EncodeRng<T> {
        EncodeRng::new(SeedableRng::from_seed(seed))
    }
}

impl<T: Rng> Rng for EncodeRng<T> {
    fn next_u32(&mut self) -> u32 {
        self.inner.next_u32()
    }
}

impl<T: Rng+'static> Serialize for EncodeRng<T> {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        let mut vec = Vec::new();
        unsafe {
            let view = self as *const _ as *const u8;
            for i in 0..(mem::size_of::<T>()) {
                vec.push(*view.offset(i as isize));
            }
        }
        serializer.visit_bytes(&vec)
    }
}

impl<T: Rng+'static> Deserialize for EncodeRng<T> {
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer
    {
        let blob: Vec<u8> = try!(deserializer.visit(VecVisitor::new()));
        unsafe {
            if blob.len() == mem::size_of::<T>() {
                Ok(EncodeRng::new(mem::transmute_copy(&blob[0])))
            } else {
                Err(Error::syntax("Bad RNG blob length"))
            }
        }
    }
}
<commit_msg>Fix EncodeRng serdification<commit_after>use std::mem;
use rand::{Rng, SeedableRng};
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use serde::de::Error;
use to_log_odds;

/// Additional methods for random number generators.
pub trait RngExt {
    /// Return true with 50 % probability.
    fn coinflip(&mut self) -> bool;

    /// Return true with probability 1 / n.
    fn one_chance_in(&mut self, n: u32) -> bool;

    /// Return true with p probability.
    fn with_chance(&mut self, p: f32) -> bool;

    /// Return a log odds deciban score that corresponds to a random
    /// probability from [0, 1].
    ///
    fn log_odds(&mut self) -> f32;

    /// Return true with the probability corresponding to the log odds with
    /// the given deciban value.
    fn with_log_odds(&mut self, db: f32) -> bool;
}

impl<T: Rng> RngExt for T {
    fn coinflip(&mut self) -> bool {
        self.gen_weighted_bool(2)
    }

    fn one_chance_in(&mut self, n: u32) -> bool {
        self.gen_weighted_bool(n)
    }

    fn with_chance(&mut self, p: f32) -> bool {
        self.gen_range(0.0, 1.0) < p
    }

    fn log_odds(&mut self) -> f32 {
        to_log_odds(self.gen_range(0.0, 1.0))
    }

    fn with_log_odds(&mut self, db: f32) -> bool {
        db > self.log_odds()
    }
}

/// A wrapper that makes a Rng implementation encodable.
///
/// For games that want to store the current Rng state as a part of the save
/// game. Works by casting the Rng representation into a binary blob, will
/// crash and burn if the Rng struct is not plain-old-data.
pub struct EncodeRng<T> {
    inner: T,
}

impl<T: Rng+'static> EncodeRng<T> {
    pub fn new(inner: T) -> EncodeRng<T> {
        EncodeRng { inner: inner }
    }
}

impl<T: SeedableRng<S>+Rng+'static, S> SeedableRng<S> for EncodeRng<T> {
    fn reseed(&mut self, seed: S) {
        self.inner.reseed(seed);
    }

    fn from_seed(seed: S) -> EncodeRng<T> {
        EncodeRng::new(SeedableRng::from_seed(seed))
    }
}

impl<T: Rng> Rng for EncodeRng<T> {
    fn next_u32(&mut self) -> u32 {
        self.inner.next_u32()
    }
}

impl<T: Rng+'static> Serialize for EncodeRng<T> {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        let mut vec = Vec::new();
        unsafe {
            let view = self as *const _ as *const u8;
            for i in 0..(mem::size_of::<T>()) {
                vec.push(*view.offset(i as isize));
            }
        }
        vec.serialize(serializer)
    }
}

impl<T: Rng+'static> Deserialize for EncodeRng<T> {
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer
    {
        let blob: Vec<u8> = try!(Deserialize::deserialize(deserializer));
        unsafe {
            if blob.len() == mem::size_of::<T>() {
                Ok(EncodeRng::new(mem::transmute_copy(&blob[0])))
            } else {
                Err(Error::syntax("Bad RNG blob length"))
            }
        }
    }
}

#[cfg(test)]
mod test {
use rand::{Rng, XorShiftRng, SeedableRng};
use super::EncodeRng;

    #[test]
    fn test_serialize_rng() {
        use bincode::{serde, SizeLimit};

        let mut rng: EncodeRng<XorShiftRng> = SeedableRng::from_seed([1, 2, 3, 4]);

        let saved = serde::serialize(&rng, SizeLimit::Infinite).expect("Serialization failed");
        let mut rng2 = serde::deserialize::<EncodeRng<XorShiftRng>>(&saved).expect("Deserialization failed");

        assert!(rng.next_u32() == rng2.next_u32());
    }
}
<|endoftext|>


<commit_before>fn main(){
	let original : [u8, ..7] = [ 0u8, 1, 2, 3, 4, 5, 6];
	let original_copy = copy( original);}

fn copy( slice : &[u8]) -> [u8] {
	let result : Vec<u8> = Vec::new();
	for i in range( 0, slice.len()) {
		result.push( slice[i]);}
	return result.as_slice();}
<commit_msg>resetting asdf.rs<commit_after>
fn main(){}
<|endoftext|>


<commit_before>//! Back-end module for the task queue. The back-end is running
//! on a separate thread. All it does is listening to a command
//! channel and starting new tasks when the time comes.

use std::thread;
use std::sync::atomic::*;
use std::sync::Arc;
use atom::*;
use pulse::*;

use {Handle, Wait, Task, Schedule, IntoTask};

// Todo 64bit verison
const BLOCK: usize = 0x8000_0000;
const REF_COUNT: usize = 0x7FFF_FFFF;

/// Task queue back-end.
pub struct Backend {
    active: AtomicUsize,
    work_done: Atom<Pulse>,
}

impl Backend {
    /// Create a new back-end.
    pub fn new() -> Backend {
        Backend {
            active: AtomicUsize::new(0),
            work_done: Atom::empty()
        }
    }

    /// Check to see if the scheduler has put a hold on the
    /// starting of new tasks (occurs during shutdown)
    fn try_active_inc(&self) -> bool {
        loop {
            let value = self.active.load(Ordering::SeqCst);
            if value & BLOCK == BLOCK {
                return false;
            }

            // This is used instead of a fetch_add to allow for checking of the
            // block flag
            if value == self.active.compare_and_swap(value, value + 1, Ordering::SeqCst) {
                return true;
            }
        }
    }

    /// Decrement the active count, wakeing up scheduler
    /// if you were the last running task.
    fn active_dec(&self) {
        // This should not effect the flags
        let count = self.active.fetch_sub(1, Ordering::SeqCst);
        if count & REF_COUNT == 1 {
            self.work_done.take().map(|p| p.pulse());
        }
    }

    /// Start a task that will run once all the Handle's have
    /// been completed.
    pub fn start(back: Arc<Backend>, mut task: TaskBuilder,
                 ack: Option<(Signal, Arc<DoneAck>)>) -> Handle {

        // Create or reuse the DoneAck
        let (done_signal, ack) = if task.extend {
            ack.expect("No parent thread to extend")
        } else {
            let (signal, complete) = Signal::new();
            (signal, Arc::new(DoneAck::new(complete)))
        };

        // Create the wait signal if needed
        let signal = if task.wait.len() == 0 {
            Signal::pulsed()
        } else if task.wait.len() == 1 {
            task.wait.pop().unwrap()
        } else {
            Barrier::new(&task.wait).signal()
        };

        let sig = done_signal.clone();
        signal.callback(move || {
            if back.try_active_inc() {
                thread::spawn(move || {
                    let mut back = (back, sig, ack);
                    task.inner.run(&mut back);

                    let (back, sig, ack) = back;
                    // Drop this before active_dec so that any pending
                    // tasks are started before we try and signal the backend
                    // that work is done
                    drop((sig, ack));
                    back.active_dec();
                });
            }
        });

        done_signal
    }

    /// Kill the backend, wait until the condition is satisfied.
    pub fn exit(&self, wait: Wait) {
        let (signal, pulse) = Signal::new();
        // Install the pulse (if needed)
        match wait {
            Wait::Active | Wait::Pending => {
                self.work_done.swap(pulse);
            }
            Wait::None => {
                pulse.pulse()
            }
        }

        // read the current active count, OR in the BLOCK
        // flag if needed for the wait
        let count = match wait {
            Wait::None | Wait::Active => {
                self.active.fetch_or(BLOCK, Ordering::SeqCst)
            }
            Wait::Pending => {
                self.active.load(Ordering::SeqCst)
            }
        };

        // Wait until the count is equal to 0.
        if count & REF_COUNT == 0 {
            return;
        } else {
            signal.wait().unwrap();
        }
    }
}

impl Schedule for (Arc<Backend>, Signal, Arc<DoneAck>)  {
    fn add_task(&self, task: TaskBuilder) -> Handle {
        Backend::start(self.0.clone(), task, Some((self.1.clone(), self.2.clone())))
    }
}

impl<'a> Schedule for &'a mut (Arc<Backend>, Signal, Arc<DoneAck>)  {
    fn add_task(&self, task: TaskBuilder) -> Handle {
        Backend::start(self.0.clone(), task, Some((self.1.clone(), self.2.clone())))
    }
}

/// This is a shareable object to allow multiple
/// tasks to
pub struct DoneAck(Option<Pulse>);

impl DoneAck {
    fn new(pulse: Pulse) -> DoneAck {
        DoneAck(Some(pulse))
    }
}

impl Drop for DoneAck {
    fn drop(&mut self) {
        self.0.take().map(|x| x.pulse());
    }
}

/// A structure to help build a task
pub struct TaskBuilder {
    /// The task to be run
    inner: Box<Task+Send>,
    /// is the task extended or not
    extend: bool,
    /// The signals to wait on
    wait: Vec<Signal>
}

impl TaskBuilder {
    /// Create a new TaskBuilder around `t`
    pub fn new<T>(t: T) -> TaskBuilder where T: IntoTask {
        TaskBuilder {
            inner: t.into_task(),
            extend: false,
            wait: Vec::new()
        }
    }

    /// A task extend will extend the lifetime of the parent task
    /// Externally to this task the Handle will not show as complete
    /// until both the parent, and child are completed.
    ///
    /// A parent should not wait on the child task if it is extended
    /// the parent's lifetime. As this will deadlock.
    pub fn extend(mut self) -> TaskBuilder {
        self.extend = true;
        self
    }

    /// Start the task only after `signal` is asserted
    pub fn after(mut self, signal: Signal) -> TaskBuilder {
        self.wait.push(signal);
        self
    }

    /// Start the task using the supplied scheduler
    pub fn start(self, sched: &mut Schedule) -> Signal {
        sched.add_task(self)
    }
}<commit_msg>add idle pool to back<commit_after>//! Back-end module for the task queue. The back-end is running
//! on a separate thread. All it does is listening to a command
//! channel and starting new tasks when the time comes.

use std::thread;
use std::sync::atomic::*;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{SyncSender, Sender, Receiver, sync_channel, channel};
use std::boxed::FnBox;
use atom::*;
use pulse::*;

use {Handle, Wait, Task, Schedule, IntoTask};

// Todo 64bit verison
const BLOCK: usize = 0x8000_0000;
const REF_COUNT: usize = 0x7FFF_FFFF;

// Todo, user define...
const MAX_IDLE: usize = 32;

/// Task queue back-end.
pub struct Backend {
    active: AtomicUsize,
    work_done: Atom<Pulse>,

    // Idle queue of threads
    threads: Mutex<Receiver<Sender<Box<FnBox()+Send>>>>,
    queue: Mutex<SyncSender<Sender<Box<FnBox()+Send>>>>
}

impl Backend {
    /// Create a new back-end.
    pub fn new() -> Backend {
        let (tx, rx) = sync_channel(MAX_IDLE);

        Backend {
            active: AtomicUsize::new(0),
            work_done: Atom::empty(),
            threads: Mutex::new(rx),
            queue: Mutex::new(tx)
        }
    }

    /// Check to see if the scheduler has put a hold on the
    /// starting of new tasks (occurs during shutdown)
    fn try_active_inc(&self) -> bool {
        loop {
            let value = self.active.load(Ordering::SeqCst);
            if value & BLOCK == BLOCK {
                return false;
            }

            // This is used instead of a fetch_add to allow for checking of the
            // block flag
            if value == self.active.compare_and_swap(value, value+1, Ordering::SeqCst) {
                return true;
            }
        }
    }

    /// Decrement the active count, wakeing up scheduler
    /// if you were the last running task.
    fn active_dec(&self) {
        // This should not effect the flags
        let count = self.active.fetch_sub(1, Ordering::SeqCst);
        if count & REF_COUNT == 1 {
            self.work_done.take().map(|p| p.pulse());
        }
    }

    /// Creates a thread iff needed
    fn thread(&self) -> Sender<Box<FnBox()+Send>> {
        let guard = self.threads.lock().unwrap();
        if let Ok(thread) = guard.try_recv() {
            return thread;
        }

        drop(guard);
        let idle_msg = self.queue.lock().unwrap().clone();

        let (tx, rx): (Sender<Box<FnBox()+Send>>, Receiver<Box<FnBox()+Send>>) = channel();
        thread::spawn(move || {
            // run the first task
            if let Ok(work) = rx.recv() {
                work();
            } else {
                return;
            }

            // run any new messages
            loop {
                let (tx, rx) = channel();
                if let Err(_) = idle_msg.try_send(tx) {
                    return;
                }

                if let Ok(work) = rx.recv() {
                    work();
                } else {
                    return;
                }
            }
        });
        tx
    }

    /// Start a task that will run once all the Handle's have
    /// been completed.
    pub fn start(back: Arc<Backend>, mut task: TaskBuilder,
                 ack: Option<(Signal, Arc<DoneAck>)>) -> Handle {

        // Create or reuse the DoneAck
        let (done_signal, ack) = if task.extend {
            ack.expect("No parent thread to extend")
        } else {
            let (signal, complete) = Signal::new();
            (signal, Arc::new(DoneAck::new(complete)))
        };

        // Create the wait signal if needed
        let signal = if task.wait.len() == 0 {
            Signal::pulsed()
        } else if task.wait.len() == 1 {
            task.wait.pop().unwrap()
        } else {
            Barrier::new(&task.wait).signal()
        };

        let sig = done_signal.clone();
        signal.callback(move || {
            if back.try_active_inc() {
                let thread = back.thread();
                thread.send(Box::new(move || {
                    let mut back = (back, sig, ack);
                    task.inner.run(&mut back);

                    let (back, sig, ack) = back;
                    // Drop this before active_dec so that any pending
                    // tasks are started before we try and signal the backend
                    // that work is done
                    drop((sig, ack));
                    back.active_dec();
                })).unwrap();
            }
        });

        done_signal
    }

    /// Kill the backend, wait until the condition is satisfied.
    pub fn exit(&self, wait: Wait) {
        let (signal, pulse) = Signal::new();
        // Install the pulse (if needed)
        match wait {
            Wait::Active | Wait::Pending => {
                self.work_done.swap(pulse);
            }
            Wait::None => {
                pulse.pulse()
            }
        }

        // read the current active count, OR in the BLOCK
        // flag if needed for the wait
        let count = match wait {
            Wait::None | Wait::Active => {
                self.active.fetch_or(BLOCK, Ordering::SeqCst)
            }
            Wait::Pending => {
                self.active.load(Ordering::SeqCst)
            }
        };

        // Wait until the count is equal to 0.
        if count & REF_COUNT == 0 {
            return;
        } else {
            signal.wait().unwrap();
        }
    }
}

impl Schedule for (Arc<Backend>, Signal, Arc<DoneAck>)  {
    fn add_task(&self, task: TaskBuilder) -> Handle {
        Backend::start(self.0.clone(), task, Some((self.1.clone(), self.2.clone())))
    }
}

impl<'a> Schedule for &'a mut (Arc<Backend>, Signal, Arc<DoneAck>)  {
    fn add_task(&self, task: TaskBuilder) -> Handle {
        Backend::start(self.0.clone(), task, Some((self.1.clone(), self.2.clone())))
    }
}

/// This is a shareable object to allow multiple
/// tasks to
pub struct DoneAck(Option<Pulse>);

impl DoneAck {
    fn new(pulse: Pulse) -> DoneAck {
        DoneAck(Some(pulse))
    }
}

impl Drop for DoneAck {
    fn drop(&mut self) {
        self.0.take().map(|x| x.pulse());
    }
}

/// A structure to help build a task
pub struct TaskBuilder {
    /// The task to be run
    inner: Box<Task+Send>,
    /// is the task extended or not
    extend: bool,
    /// The signals to wait on
    wait: Vec<Signal>
}

impl TaskBuilder {
    /// Create a new TaskBuilder around `t`
    pub fn new<T>(t: T) -> TaskBuilder where T: IntoTask {
        TaskBuilder {
            inner: t.into_task(),
            extend: false,
            wait: Vec::new()
        }
    }

    /// A task extend will extend the lifetime of the parent task
    /// Externally to this task the Handle will not show as complete
    /// until both the parent, and child are completed.
    ///
    /// A parent should not wait on the child task if it is extended
    /// the parent's lifetime. As this will deadlock.
    pub fn extend(mut self) -> TaskBuilder {
        self.extend = true;
        self
    }

    /// Start the task only after `signal` is asserted
    pub fn after(mut self, signal: Signal) -> TaskBuilder {
        self.wait.push(signal);
        self
    }

    /// Start the task using the supplied scheduler
    pub fn start(self, sched: &mut Schedule) -> Signal {
        sched.add_task(self)
    }
}<|endoftext|>


<commit_before>extern crate num;
use std::collections::BTreeSet;
use std::cmp;
use rand::{Rng, Rand};
use std::ops::Range;
use std::iter::Rev;
use super::{Stateless, MateRand, Mutate};

/// Defines an opcode for the Mep. Every opcode contains an instruction and two parameter indices.
/// These specify which previous opcodes produced the result required as inputs to this opcode.
/// These parameters can also come from the inputs to the program, which sequentially
/// proceed the internal instructions.
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
struct Opcode<Ins> {
    instruction: Ins,
    first: usize,
    second: usize,
}

/// A multi-expression program represented using a series of operations that can reuse
/// results of previous operations.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Mep<Ins> {
    program: Vec<Opcode<Ins>>,
    mutate_lambda: usize,
    crossover_points: usize,
    inputs: usize,
    outputs: usize,
}

impl<Ins> Mep<Ins> {
    /// Generates a new Mep with a particular size and takes a closure to generate random
    /// instructions. Takes an RNG as well to generate random internal data for each instruction.
    ///
    /// `mutate_lambda` corresponds to the lambda of a poisson distribution. It is proportional
    /// to the average unit mutate cycles between mutations. It is biased by 1, so a `mutate_lambda`
    /// of 0 means it will be mutated every cycle.
    ///
    /// `crossover_points` corresponds to the maximum amount of crossover locations on the
    /// chromosome when mating. When mating the `crossover_points` is chosen randomly between the
    /// two Meps.
    pub fn new<R>(inputs: usize,
                  outputs: usize,
                  internal_instruction_count: usize,
                  mutate_lambda: usize,
                  crossover_points: usize,
                  rng: &mut R)
                  -> Self
        where R: Rng,
              Ins: Rand
    {
        Mep {
            program: (0..internal_instruction_count + outputs)
                .map(|i| if i < internal_instruction_count {
                    Opcode {
                        instruction: rng.gen(),
                        first: rng.gen_range(0, i + inputs),
                        second: rng.gen_range(0, i + inputs),
                    }
                } else {
                    Opcode {
                        instruction: rng.gen(),
                        first: rng.gen_range(0, internal_instruction_count + inputs),
                        second: rng.gen_range(0, internal_instruction_count + inputs),
                    }
                })
                .collect(),
            mutate_lambda: mutate_lambda,
            crossover_points: crossover_points,
            inputs: inputs,
            outputs: outputs,
        }
    }
}

impl<Ins, R> MateRand<R> for Mep<Ins>
    where R: Rng,
          Ins: Clone
{
    fn mate(&self, rhs: &Self, rng: &mut R) -> Self {
        // Each Mep must have the same amount of inputs
        // TODO: Once Rust implements generic values, this can be made explicit and is not needed
        assert!(self.inputs == rhs.inputs);
        assert!(self.outputs == rhs.outputs);
        // Get the smallest of the two lengths
        let total_instructions = cmp::min(self.program.len(), rhs.program.len());
        let crossover_choice = rng.gen_range(0, 2);
        Mep {
            program:
                // Generate a randomly sized sequence between 1 and the minimum between
                // `crossover_points` vs `total_instructions / 2`.
                (0..rng.gen_range(1, cmp::min(total_instructions / 2, {
                if crossover_choice == 0 {self}
                    else {rhs}}.crossover_points + 1)))
                // Map these to random crossover points.
                .map(|_| rng.gen_range(0, total_instructions))
                // Add total_instructions at the end so we can generate a range with it.
                .chain(Some(total_instructions))
                // Sort them by value into BTree, which removes duplicates and orders them.
                .fold(BTreeSet::new(), |mut set, i| {set.insert(i); set})
                // Iterate over the sorted values.
                .iter()
                // Turn every copy of two, prepending a 0, into a range.
                .scan(0, |prev, x| {let out = Some(*prev..*x); *prev = *x; out})
                // Enumerate by index to differentiate odd and even values.
                .enumerate()
                // Map even pairs to ranges in parent 0 and odd ones to ranges in
                // parent 1 and expand the ranges.
                .flat_map(|(index, range)| {
                    {if index % 2 == 0 {self} else {rhs}}.program[range].iter().cloned()
                })
                // Collect all the instruction ranges from each parent.
                .collect(),

            mutate_lambda: if self.mutate_lambda < rhs.mutate_lambda {
                rng.gen_range(self.mutate_lambda, rhs.mutate_lambda + 1)
            } else {
                rng.gen_range(rhs.mutate_lambda, self.mutate_lambda + 1)
            },

            crossover_points: if self.crossover_points < rhs.crossover_points {
                rng.gen_range(self.crossover_points, rhs.crossover_points + 1)
            } else {
                rng.gen_range(rhs.crossover_points, self.crossover_points + 1)
            },

            inputs: self.inputs,
            outputs: self.outputs,
        }
    }
}

impl<Ins, R> Mutate<R> for Mep<Ins>
    where Ins: Mutate<R>,
          R: Rng
{
    fn mutate(&mut self, rng: &mut R) {
        // For this entire cycle, the biased lambda from the previous cycle is effective.
        let effective_lambda = self.mutate_lambda + 1;

        // Mutate `mutate_lambda`.
        if rng.gen_range(0, effective_lambda) == 0 {
            // Make it possibly go up or down by 1.
            match rng.gen_range(0, 2) {
                0 => self.mutate_lambda = self.mutate_lambda.saturating_add(1),
                _ => self.mutate_lambda = self.mutate_lambda.saturating_sub(1),
            }
        }

        // Mutate `crossover_points`.
        if rng.gen_range(0, effective_lambda) == 0 {
            // Make it possibly go up or down by 1.
            match rng.gen_range(0, 2) {
                0 => self.crossover_points = self.crossover_points.saturating_add(1),
                _ => self.crossover_points = self.crossover_points.saturating_sub(1),
            }
        }

        // Mutate the instructions.
        loop {
            // Choose a random location in the instructions and then add a random value.
            // up to the unit_mutate_size.
            let choice = rng.gen_range(0, self.program.len() + effective_lambda);
            // Whenever we choose a location outside the vector reject the choice and end mutation.
            if choice >= self.program.len() {
                break;
            }
            let op = &mut self.program[choice];
            // Randomly mutate only one of the things contained here.
            match rng.gen_range(0, 3) {
                0 => op.instruction.mutate(rng),
                1 => op.first = rng.gen_range(0, choice + self.inputs),
                _ => op.second = rng.gen_range(0, choice + self.inputs),
            }
        }
    }
}

impl<'a, Ins, Param> Stateless<'a, &'a [Param], ResultIterator<'a, Ins, Param>> for Mep<Ins>
    where Param: Clone
{
    fn process(&'a self, inputs: &'a [Param]) -> ResultIterator<'a, Ins, Param> {
        ResultIterator {
            mep: self,
            buff: vec![None; self.program.len()],
            solve_iter: ((self.program.len() + self.inputs - self.outputs)..(self.program.len() +
                                                                             self.inputs))
                .rev(),
            inputs: inputs,
        }
    }
}

pub struct ResultIterator<'a, Ins, Param>
    where Ins: 'a,
          Param: 'a
{
    mep: &'a Mep<Ins>,
    buff: Vec<Option<Param>>,
    solve_iter: Rev<Range<usize>>,
    inputs: &'a [Param],
}

impl<'a, Ins, Param> ResultIterator<'a, Ins, Param> {
    #[inline]
    fn op_solved(&mut self, i: usize) -> Param
        where Param: Clone,
              Ins: Stateless<'a, (Param, Param), Param>
    {
        // If this is an input, it is already solved, so return the result immediately.
        if i < self.mep.inputs {
            return unsafe { self.inputs.get_unchecked(i) }.clone();
        }
        // Check if this has been evaluated or not.
        let possible = unsafe { self.buff.get_unchecked(i - self.mep.inputs) }.clone();
        match possible {
            // If it has, return the value.
            Some(x) => x,
            // If it hasn't been solved.
            None => {
                // Get a reference to the opcode.
                let op = unsafe { self.mep.program.get_unchecked(i - self.mep.inputs) };
                // Compute the result of the operation, ensuring the inputs are solved beforehand.
                let result = op.instruction
                    .process((self.op_solved(op.first), self.op_solved(op.second)));
                // Properly store the Some result to the buffer.
                unsafe { *self.buff.get_unchecked_mut(i - self.mep.inputs) = Some(result.clone()) };
                // Return the result.
                result
            }
        }
    }
}

impl<'a, Ins, Param> Iterator for ResultIterator<'a, Ins, Param>
    where Param: Clone,
          Ins: Stateless<'a, (Param, Param), Param>
{
    type Item = Param;
    #[inline]
    fn next(&mut self) -> Option<Param> {
        match self.solve_iter.next() {
            None => None,
            Some(i) => Some(self.op_solved(i)),
        }
    }
}

#[cfg(test)]
mod tests {
    use rand::{Isaac64Rng, SeedableRng, Rand};
    use super::*;
    use super::super::{MateRand, Mutate, Stateless};

    #[derive(Clone)]
    struct Op;

    impl<R> Mutate<R> for Op {
        fn mutate(&mut self, _: &mut R) {}
    }

    impl<'a> Stateless<'a, (i32, i32), i32> for Op {
        fn process(&'a self, inputs: (i32, i32)) -> i32 {
            inputs.0 + inputs.1
        }
    }

    impl Rand for Op {
        fn rand<R>(_: &mut R) -> Self {
            Op
        }
    }

    #[test]
    fn mep() {
        let mut rng = Isaac64Rng::from_seed(&[1, 2, 3, 4]);
        let (mut a, b) = {
            let mut clos = || Mep::<Op>::new(3, 1, 10, 10, 10, &mut rng);
            (clos(), clos())
        };
        a.mutate(&mut rng);
        let c = a.mate(&b, &mut rng);

        let inputs = [2i32, 3, 4];
        c.process(&inputs[..]).collect::<Vec<_>>();
    }
}
<commit_msg>fix bug where outputs were sometimes using other outputs as inputs after mutation<commit_after>extern crate num;
use std::collections::BTreeSet;
use std::cmp;
use rand::{Rng, Rand};
use std::ops::Range;
use std::iter::Rev;
use super::{Stateless, MateRand, Mutate};

/// Defines an opcode for the Mep. Every opcode contains an instruction and two parameter indices.
/// These specify which previous opcodes produced the result required as inputs to this opcode.
/// These parameters can also come from the inputs to the program, which sequentially
/// proceed the internal instructions.
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
struct Opcode<Ins> {
    instruction: Ins,
    first: usize,
    second: usize,
}

/// A multi-expression program represented using a series of operations that can reuse
/// results of previous operations.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Mep<Ins> {
    program: Vec<Opcode<Ins>>,
    mutate_lambda: usize,
    crossover_points: usize,
    inputs: usize,
    outputs: usize,
}

impl<Ins> Mep<Ins> {
    /// Generates a new Mep with a particular size and takes a closure to generate random
    /// instructions. Takes an RNG as well to generate random internal data for each instruction.
    ///
    /// `mutate_lambda` corresponds to the lambda of a poisson distribution. It is proportional
    /// to the average unit mutate cycles between mutations. It is biased by 1, so a `mutate_lambda`
    /// of 0 means it will be mutated every cycle.
    ///
    /// `crossover_points` corresponds to the maximum amount of crossover locations on the
    /// chromosome when mating. When mating the `crossover_points` is chosen randomly between the
    /// two Meps.
    pub fn new<R>(inputs: usize,
                  outputs: usize,
                  internal_instruction_count: usize,
                  mutate_lambda: usize,
                  crossover_points: usize,
                  rng: &mut R)
                  -> Self
        where R: Rng,
              Ins: Rand
    {
        Mep {
            program: (0..internal_instruction_count + outputs)
                .map(|i| if i < internal_instruction_count {
                    Opcode {
                        instruction: rng.gen(),
                        first: rng.gen_range(0, i + inputs),
                        second: rng.gen_range(0, i + inputs),
                    }
                } else {
                    Opcode {
                        instruction: rng.gen(),
                        first: rng.gen_range(0, internal_instruction_count + inputs),
                        second: rng.gen_range(0, internal_instruction_count + inputs),
                    }
                })
                .collect(),
            mutate_lambda: mutate_lambda,
            crossover_points: crossover_points,
            inputs: inputs,
            outputs: outputs,
        }
    }
}

impl<Ins, R> MateRand<R> for Mep<Ins>
    where R: Rng,
          Ins: Clone
{
    fn mate(&self, rhs: &Self, rng: &mut R) -> Self {
        // Each Mep must have the same amount of inputs
        // TODO: Once Rust implements generic values, this can be made explicit and is not needed
        assert!(self.inputs == rhs.inputs);
        assert!(self.outputs == rhs.outputs);
        // Get the smallest of the two lengths
        let total_instructions = cmp::min(self.program.len(), rhs.program.len());
        let crossover_choice = rng.gen_range(0, 2);
        Mep {
            program:
                // Generate a randomly sized sequence between 1 and the minimum between
                // `crossover_points` vs `total_instructions / 2`.
                (0..rng.gen_range(1, cmp::min(total_instructions / 2, {
                if crossover_choice == 0 {self}
                    else {rhs}}.crossover_points + 1)))
                // Map these to random crossover points.
                .map(|_| rng.gen_range(0, total_instructions))
                // Add total_instructions at the end so we can generate a range with it.
                .chain(Some(total_instructions))
                // Sort them by value into BTree, which removes duplicates and orders them.
                .fold(BTreeSet::new(), |mut set, i| {set.insert(i); set})
                // Iterate over the sorted values.
                .iter()
                // Turn every copy of two, prepending a 0, into a range.
                .scan(0, |prev, x| {let out = Some(*prev..*x); *prev = *x; out})
                // Enumerate by index to differentiate odd and even values.
                .enumerate()
                // Map even pairs to ranges in parent 0 and odd ones to ranges in
                // parent 1 and expand the ranges.
                .flat_map(|(index, range)| {
                    {if index % 2 == 0 {self} else {rhs}}.program[range].iter().cloned()
                })
                // Collect all the instruction ranges from each parent.
                .collect(),

            mutate_lambda: if self.mutate_lambda < rhs.mutate_lambda {
                rng.gen_range(self.mutate_lambda, rhs.mutate_lambda + 1)
            } else {
                rng.gen_range(rhs.mutate_lambda, self.mutate_lambda + 1)
            },

            crossover_points: if self.crossover_points < rhs.crossover_points {
                rng.gen_range(self.crossover_points, rhs.crossover_points + 1)
            } else {
                rng.gen_range(rhs.crossover_points, self.crossover_points + 1)
            },

            inputs: self.inputs,
            outputs: self.outputs,
        }
    }
}

impl<Ins, R> Mutate<R> for Mep<Ins>
    where Ins: Mutate<R>,
          R: Rng
{
    fn mutate(&mut self, rng: &mut R) {
        // For this entire cycle, the biased lambda from the previous cycle is effective.
        let effective_lambda = self.mutate_lambda + 1;

        // Mutate `mutate_lambda`.
        if rng.gen_range(0, effective_lambda) == 0 {
            // Make it possibly go up or down by 1.
            match rng.gen_range(0, 2) {
                0 => self.mutate_lambda = self.mutate_lambda.saturating_add(1),
                _ => self.mutate_lambda = self.mutate_lambda.saturating_sub(1),
            }
        }

        // Mutate `crossover_points`.
        if rng.gen_range(0, effective_lambda) == 0 {
            // Make it possibly go up or down by 1.
            match rng.gen_range(0, 2) {
                0 => self.crossover_points = self.crossover_points.saturating_add(1),
                _ => self.crossover_points = self.crossover_points.saturating_sub(1),
            }
        }

        // Get the program length.
        let plen = self.program.len();

        // Mutate the instructions.
        loop {
            // Choose a random location in the instructions and then add a random value.
            // up to the unit_mutate_size.
            let choice = rng.gen_range(0, plen + effective_lambda);
            // Whenever we choose a location outside the vector reject the choice and end mutation.
            if choice >= plen {
                break;
            }
            let op = &mut self.program[choice];
            // Randomly mutate only one of the things contained here.
            match rng.gen_range(0, 3) {
                0 => op.instruction.mutate(rng),
                1 => op.first = if choice > plen  - self.outputs {
                    // Handle the case where an output is selected.
                    rng.gen_range(0, choice + plen  - self.outputs)
                } else {
                    rng.gen_range(0, choice + self.inputs)
                },
                _ => op.second = if choice > plen  - self.outputs {
                    // Handle the case where an output is selected.
                    rng.gen_range(0, choice + plen  - self.outputs)
                } else {
                    rng.gen_range(0, choice + self.inputs)
                },
            }
        }
    }
}

impl<'a, Ins, Param> Stateless<'a, &'a [Param], ResultIterator<'a, Ins, Param>> for Mep<Ins>
    where Param: Clone
{
    fn process(&'a self, inputs: &'a [Param]) -> ResultIterator<'a, Ins, Param> {
        ResultIterator {
            mep: self,
            buff: vec![None; self.program.len()],
            solve_iter: ((self.program.len() + self.inputs - self.outputs)..(self.program.len() +
                                                                             self.inputs))
                .rev(),
            inputs: inputs,
        }
    }
}

pub struct ResultIterator<'a, Ins, Param>
    where Ins: 'a,
          Param: 'a
{
    mep: &'a Mep<Ins>,
    buff: Vec<Option<Param>>,
    solve_iter: Rev<Range<usize>>,
    inputs: &'a [Param],
}

impl<'a, Ins, Param> ResultIterator<'a, Ins, Param> {
    #[inline]
    fn op_solved(&mut self, i: usize) -> Param
        where Param: Clone,
              Ins: Stateless<'a, (Param, Param), Param>
    {
        // If this is an input, it is already solved, so return the result immediately.
        if i < self.mep.inputs {
            return unsafe { self.inputs.get_unchecked(i) }.clone();
        }
        // Check if this has been evaluated or not.
        let possible = unsafe { self.buff.get_unchecked(i - self.mep.inputs) }.clone();
        match possible {
            // If it has, return the value.
            Some(x) => x,
            // If it hasn't been solved.
            None => {
                // Get a reference to the opcode.
                let op = unsafe { self.mep.program.get_unchecked(i - self.mep.inputs) };
                // Compute the result of the operation, ensuring the inputs are solved beforehand.
                let result = op.instruction
                    .process((self.op_solved(op.first), self.op_solved(op.second)));
                // Properly store the Some result to the buffer.
                unsafe { *self.buff.get_unchecked_mut(i - self.mep.inputs) = Some(result.clone()) };
                // Return the result.
                result
            }
        }
    }
}

impl<'a, Ins, Param> Iterator for ResultIterator<'a, Ins, Param>
    where Param: Clone,
          Ins: Stateless<'a, (Param, Param), Param>
{
    type Item = Param;
    #[inline]
    fn next(&mut self) -> Option<Param> {
        match self.solve_iter.next() {
            None => None,
            Some(i) => Some(self.op_solved(i)),
        }
    }
}

#[cfg(test)]
mod tests {
    use rand::{Isaac64Rng, SeedableRng, Rand};
    use super::*;
    use super::super::{MateRand, Mutate, Stateless};

    #[derive(Clone)]
    struct Op;

    impl<R> Mutate<R> for Op {
        fn mutate(&mut self, _: &mut R) {}
    }

    impl<'a> Stateless<'a, (i32, i32), i32> for Op {
        fn process(&'a self, inputs: (i32, i32)) -> i32 {
            inputs.0 + inputs.1
        }
    }

    impl Rand for Op {
        fn rand<R>(_: &mut R) -> Self {
            Op
        }
    }

    #[test]
    fn mep() {
        let mut rng = Isaac64Rng::from_seed(&[1, 2, 3, 4]);
        let (mut a, b) = {
            let mut clos = || Mep::<Op>::new(3, 1, 10, 10, 10, &mut rng);
            (clos(), clos())
        };
        a.mutate(&mut rng);
        let c = a.mate(&b, &mut rng);

        let inputs = [2i32, 3, 4];
        c.process(&inputs[..]).collect::<Vec<_>>();
    }
}
<|endoftext|>


<commit_before>// Copyright 2018-2019, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use std::convert::TryFrom;
use std::ffi::{CStr, CString};
use std::fmt;
use std::io;
use std::mem;
use std::ops::Deref;
use std::path::Path;
use std::ptr;

#[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))]
use enums::SvgUnit;
use enums::{Status, SurfaceType, SvgVersion};
use ffi;
use surface::Surface;

#[cfg(feature = "use_glib")]
use glib::translate::*;

impl SvgVersion {
    pub fn as_str(self) -> Option<&'static str> {
        unsafe {
            let res = ffi::cairo_svg_version_to_string(self.into());
            res.as_ref()
                .and_then(|cstr| CStr::from_ptr(cstr as _).to_str().ok())
        }
    }
}

declare_surface!(SvgSurface, SurfaceType::Svg);

impl SvgSurface {
    pub fn new<P: AsRef<Path>>(width: f64, height: f64, path: P) -> Result<SvgSurface, Status> {
        let path = path.as_ref().to_string_lossy().into_owned();
        let path = CString::new(path).unwrap();

        unsafe {
            Ok(Self(Surface::from_raw_full(
                ffi::cairo_svg_surface_create(path.as_ptr(), width, height),
            )?))
        }
    }

    for_stream_constructors!(cairo_svg_surface_create_for_stream);

    pub fn get_versions() -> impl Iterator<Item = SvgVersion> {
        let vers_slice = unsafe {
            let mut vers_ptr = ptr::null_mut();
            let mut num_vers = mem::MaybeUninit::uninit();
            ffi::cairo_svg_get_versions(&mut vers_ptr, num_vers.as_mut_ptr());

            std::slice::from_raw_parts(vers_ptr, num_vers.assume_init() as _)
        };

        vers_slice.iter().map(|v| SvgVersion::from(*v))
    }

    pub fn restrict(&self, version: SvgVersion) {
        unsafe {
            ffi::cairo_svg_surface_restrict_to_version(self.0.to_raw_none(), version.into());
        }
    }

    #[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))]
    pub fn set_document_unit(&mut self, unit: SvgUnit) {
        unsafe {
            ffi::cairo_svg_surface_set_document_unit(self.0.to_raw_none(), unit.into());
        }
    }

    #[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))]
    pub fn get_document_unit(&self) -> SvgUnit {
        unsafe {
            SvgUnit::from(ffi::cairo_svg_surface_get_document_unit(
                self.0.to_raw_none(),
            ))
        }
    }
}

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

    fn draw(surface: &Surface) {
        let cr = Context::new(surface);

        cr.set_line_width(25.0);

        cr.set_source_rgba(1.0, 0.0, 0.0, 0.5);
        cr.line_to(0., 0.);
        cr.line_to(100., 100.);
        cr.stroke();

        cr.set_source_rgba(0.0, 0.0, 1.0, 0.5);
        cr.line_to(0., 100.);
        cr.line_to(100., 0.);
        cr.stroke();
    }

    fn draw_in_buffer() -> Vec<u8> {
        let buffer: Vec<u8> = vec![];

        let surface = SvgSurface::for_stream(100., 100., buffer).unwrap();
        draw(&surface);
        *surface.finish_output_stream().unwrap().downcast().unwrap()
    }

    fn assert_len_close_enough(len_a: usize, len_b: usize) {
        // It seems cairo randomizies some element IDs which might make one svg slightly
        // larger than the other. Here we make sure the difference is within ~10%.
        let len_diff = (len_a as isize - len_b as isize).abs() as usize;
        assert!(len_diff < len_b / 10);
    }

    #[test]
    fn versions() {
        assert!(SvgSurface::get_versions().any(|v| v == SvgVersion::_1_1));
    }

    #[test]
    fn version_string() {
        let ver_str = SvgVersion::_1_1.as_str().unwrap();
        assert_eq!(ver_str, "SVG 1.1");
    }

    #[test]
    #[cfg(unix)]
    fn file() {
        let surface = SvgSurface::new(100., 100., "/dev/null").unwrap();
        draw(&surface);
        surface.finish();
    }

    #[test]
    fn writer() {
        let file = tempfile().expect("tempfile failed");
        let surface = SvgSurface::for_stream(100., 100., file).unwrap();

        draw(&surface);
        let stream = surface.finish_output_stream().unwrap();
        let file = stream.downcast::<std::fs::File>().unwrap();

        let buffer = draw_in_buffer();
        let file_size = file.metadata().unwrap().len();

        assert_len_close_enough(file_size as usize, buffer.len());
    }

    #[test]
    fn ref_writer() {
        let mut file = tempfile().expect("tempfile failed");
        let surface = unsafe { SvgSurface::for_raw_stream(100., 100., &mut file).unwrap() };

        draw(&surface);
        surface.finish_output_stream().unwrap();
    }

    #[test]
    fn buffer() {
        let buffer = draw_in_buffer();

        let header = b"<?xml";
        assert_eq!(&buffer[..header.len()], header);
    }

    #[test]
    fn custom_writer() {
        use std::fs;

        struct CustomWriter(usize, fs::File);

        impl io::Write for CustomWriter {
            fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
                self.1.write(buf)?;

                self.0 += buf.len();
                Ok(buf.len())
            }

            fn flush(&mut self) -> io::Result<()> {
                Ok(())
            }
        }

        let file = tempfile().expect("tempfile failed");
        let custom_writer = CustomWriter(0, file);

        let surface = SvgSurface::for_stream(100., 100., custom_writer).unwrap();
        draw(&surface);
        let stream = surface.finish_output_stream().unwrap();
        let custom_writer = stream.downcast::<CustomWriter>().unwrap();

        let buffer = draw_in_buffer();

        assert_len_close_enough(custom_writer.0, buffer.len());
    }

    fn with_panicky_stream() -> SvgSurface {
        struct PanicWriter;

        impl io::Write for PanicWriter {
            fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
                panic!("panic in writer");
            }
            fn flush(&mut self) -> io::Result<()> {
                Ok(())
            }
        }

        let surface = SvgSurface::for_stream(20., 20., PanicWriter).unwrap();
        surface.finish();
        surface
    }

    #[test]
    #[should_panic]
    fn finish_stream_propagates_panic() {
        let _ = with_panicky_stream().finish_output_stream();
    }
}
<commit_msg>SvgSurface: make filename param optional<commit_after>// Copyright 2018-2019, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

#[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))]
use enums::SvgUnit;
use enums::{Status, SurfaceType, SvgVersion};
use ffi;
use std::convert::TryFrom;
use std::ffi::{CStr, CString};
use std::fmt;
use std::io;
use std::mem;
use std::ops::Deref;
#[cfg(not(windows))]
use std::os::unix::prelude::*;
use std::path::Path;
use std::ptr;

use surface::Surface;

#[cfg(feature = "use_glib")]
use glib::translate::*;

impl SvgVersion {
    pub fn as_str(self) -> Option<&'static str> {
        unsafe {
            let res = ffi::cairo_svg_version_to_string(self.into());
            res.as_ref()
                .and_then(|cstr| CStr::from_ptr(cstr as _).to_str().ok())
        }
    }
}

declare_surface!(SvgSurface, SurfaceType::Svg);

impl SvgSurface {
    pub fn new<P: AsRef<Path>>(
        width: f64,
        height: f64,
        path: Option<P>,
    ) -> Result<SvgSurface, Status> {
        #[cfg(not(windows))]
        let path = path.map(|p| {
            CString::new(p.as_ref().as_os_str().as_bytes()).expect("Invalid path with NULL bytes")
        });
        #[cfg(windows)]
        let path = path.map(|p| {
            let path_str = p
                .as_ref()
                .to_str()
                .expect("Path can't be represented as UTF-8")
                .to_owned();
            if path_str.starts_with("\\\\?\\") {
                CString::new(path_str[4..].as_bytes())
            } else {
                CString::new(path_str.as_bytes())
            }
            .expect("Invalid path with NUL bytes")
        });

        unsafe {
            Ok(Self(Surface::from_raw_full(
                ffi::cairo_svg_surface_create(
                    path.as_ref().map(|p| p.as_ptr()).unwrap_or(ptr::null()),
                    width,
                    height,
                ),
            )?))
        }
    }

    for_stream_constructors!(cairo_svg_surface_create_for_stream);

    pub fn get_versions() -> impl Iterator<Item = SvgVersion> {
        let vers_slice = unsafe {
            let mut vers_ptr = ptr::null_mut();
            let mut num_vers = mem::MaybeUninit::uninit();
            ffi::cairo_svg_get_versions(&mut vers_ptr, num_vers.as_mut_ptr());

            std::slice::from_raw_parts(vers_ptr, num_vers.assume_init() as _)
        };

        vers_slice.iter().map(|v| SvgVersion::from(*v))
    }

    pub fn restrict(&self, version: SvgVersion) {
        unsafe {
            ffi::cairo_svg_surface_restrict_to_version(self.0.to_raw_none(), version.into());
        }
    }

    #[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))]
    pub fn set_document_unit(&mut self, unit: SvgUnit) {
        unsafe {
            ffi::cairo_svg_surface_set_document_unit(self.0.to_raw_none(), unit.into());
        }
    }

    #[cfg(any(all(feature = "svg", feature = "v1_16"), feature = "dox"))]
    pub fn get_document_unit(&self) -> SvgUnit {
        unsafe {
            SvgUnit::from(ffi::cairo_svg_surface_get_document_unit(
                self.0.to_raw_none(),
            ))
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use context::*;
    use tempfile::{tempfile, NamedTempFile};

    fn draw(surface: &Surface) {
        let cr = Context::new(surface);

        cr.set_line_width(25.0);

        cr.set_source_rgba(1.0, 0.0, 0.0, 0.5);
        cr.line_to(0., 0.);
        cr.line_to(100., 100.);
        cr.stroke();

        cr.set_source_rgba(0.0, 0.0, 1.0, 0.5);
        cr.line_to(0., 100.);
        cr.line_to(100., 0.);
        cr.stroke();
    }

    fn draw_in_buffer() -> Vec<u8> {
        let buffer: Vec<u8> = vec![];

        let surface = SvgSurface::for_stream(100., 100., buffer).unwrap();
        draw(&surface);
        *surface.finish_output_stream().unwrap().downcast().unwrap()
    }

    fn assert_len_close_enough(len_a: usize, len_b: usize) {
        // It seems cairo randomizies some element IDs which might make one svg slightly
        // larger than the other. Here we make sure the difference is within ~10%.
        let len_diff = (len_a as isize - len_b as isize).abs() as usize;
        assert!(len_diff < len_b / 10);
    }

    #[test]
    fn versions() {
        assert!(SvgSurface::get_versions().any(|v| v == SvgVersion::_1_1));
    }

    #[test]
    fn version_string() {
        let ver_str = SvgVersion::_1_1.as_str().unwrap();
        assert_eq!(ver_str, "SVG 1.1");
    }

    #[test]
    fn without_file() {
        let surface = SvgSurface::new(100., 100., None::<&Path>).unwrap();
        draw(&surface);
        surface.finish();
    }

    #[test]
    fn file() {
        let file = NamedTempFile::new().expect("tempfile failed");
        let surface = SvgSurface::new(100., 100., Some(&file.path())).unwrap();
        draw(&surface);
        surface.finish();
    }

    #[test]
    fn writer() {
        let file = tempfile().expect("tempfile failed");
        let surface = SvgSurface::for_stream(100., 100., file).unwrap();

        draw(&surface);
        let stream = surface.finish_output_stream().unwrap();
        let file = stream.downcast::<std::fs::File>().unwrap();

        let buffer = draw_in_buffer();
        let file_size = file.metadata().unwrap().len();

        assert_len_close_enough(file_size as usize, buffer.len());
    }

    #[test]
    fn ref_writer() {
        let mut file = tempfile().expect("tempfile failed");
        let surface = unsafe { SvgSurface::for_raw_stream(100., 100., &mut file).unwrap() };

        draw(&surface);
        surface.finish_output_stream().unwrap();
    }

    #[test]
    fn buffer() {
        let buffer = draw_in_buffer();

        let header = b"<?xml";
        assert_eq!(&buffer[..header.len()], header);
    }

    #[test]
    fn custom_writer() {
        use std::fs;

        struct CustomWriter(usize, fs::File);

        impl io::Write for CustomWriter {
            fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
                self.1.write(buf)?;

                self.0 += buf.len();
                Ok(buf.len())
            }

            fn flush(&mut self) -> io::Result<()> {
                Ok(())
            }
        }

        let file = tempfile().expect("tempfile failed");
        let custom_writer = CustomWriter(0, file);

        let surface = SvgSurface::for_stream(100., 100., custom_writer).unwrap();
        draw(&surface);
        let stream = surface.finish_output_stream().unwrap();
        let custom_writer = stream.downcast::<CustomWriter>().unwrap();

        let buffer = draw_in_buffer();

        assert_len_close_enough(custom_writer.0, buffer.len());
    }

    fn with_panicky_stream() -> SvgSurface {
        struct PanicWriter;

        impl io::Write for PanicWriter {
            fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
                panic!("panic in writer");
            }
            fn flush(&mut self) -> io::Result<()> {
                Ok(())
            }
        }

        let surface = SvgSurface::for_stream(20., 20., PanicWriter).unwrap();
        surface.finish();
        surface
    }

    #[test]
    #[should_panic]
    fn finish_stream_propagates_panic() {
        let _ = with_panicky_stream().finish_output_stream();
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::collections::hash_map::IterMut;
use std::collections::hash_map::Entry::{Vacant, Occupied};

use self::Sym::*;

use parser::ast::NodeId;

use parser::interner::Name;

pub struct SymTable {
    levels: Vec<SymLevel>
}

impl SymTable {
    pub fn new() -> SymTable {
        SymTable {
            levels: vec![SymLevel::new()]
        }
    }

    pub fn push_level(&mut self) {
        self.levels.push(SymLevel::new());
    }

    pub fn pop_level(&mut self) {
        assert!(self.levels.len() > 1);

        self.levels.pop();
    }

    pub fn get_last(&self, name: Name) -> Option<&Sym> {
        self.levels.last().unwrap().get(name)
    }

    pub fn get(&self, name: Name) -> Option<&Sym> {
        for level in self.levels.iter().rev() {
            if let Some(val) = level.get(name) {
                return Some(val);
            }
        }

        None
    }

    pub fn get_var(&self, name: Name) -> Option<NodeId> {
        self.get(name).and_then(|n| n.to_var())
    }

    pub fn get_type(&self, name: Name) -> Option<BuiltinType> {
        self.get(name).and_then(|n| n.to_type())
    }

    pub fn get_function(&self, name: Name) -> Option<NodeId> {
        self.get(name).and_then(|n| n.to_function())
    }

    pub fn insert(&mut self, name: Name, sym: Sym) -> Option<Sym> {
        self.levels.last_mut().unwrap().insert(name, sym)
    }
}

#[derive(Debug)]
struct SymLevel {
    map: HashMap<Name, Sym>
}

impl SymLevel {
    // creates a new table
    fn new() -> SymLevel {
        SymLevel {
            map: HashMap::new()
        }
    }

    // finds symbol in table
    fn get(&self, name: Name) -> Option<&Sym> {
        self.map.get(&name)
    }

    fn insert(&mut self, name: Name, sym: Sym) -> Option<Sym> {
        self.map.insert(name, sym)
    }
}

#[derive(Debug)]
pub enum Sym {
    SymType(BuiltinType),
    SymFunction(NodeId),
    SymVar(NodeId),
}

impl Sym {
    pub fn is_type(&self) -> bool {
        match *self {
            SymType(_) => true,
            _ => false
        }
    }

    pub fn to_type(&self) -> Option<BuiltinType> {
        match *self {
            SymType(builtin) => Some(builtin),
            _ => None
        }
    }

    pub fn is_function(&self) -> bool {
        match *self {
            SymFunction(_) => true,
            _ => false
        }
    }

    pub fn to_function(&self) -> Option<NodeId> {
        match *self {
            SymFunction(id) => Some(id),
            _ => None
        }
    }

    pub fn is_var(&self) -> bool {
        match *self {
            SymType(_) => true,
            _ => false
        }
    }

    pub fn to_var(&self) -> Option<NodeId> {
        match *self {
            SymVar(id) => Some(id),
            _ => None
        }
    }
}

#[derive(Debug, Copy, Clone)]
pub enum BuiltinType {
    Int,
    Bool,
    Str,
}
<commit_msg>sym: added unit builtin type<commit_after>use std::collections::HashMap;
use std::collections::hash_map::IterMut;
use std::collections::hash_map::Entry::{Vacant, Occupied};

use self::Sym::*;

use parser::ast::NodeId;

use parser::interner::Name;

pub struct SymTable {
    levels: Vec<SymLevel>
}

impl SymTable {
    pub fn new() -> SymTable {
        SymTable {
            levels: vec![SymLevel::new()]
        }
    }

    pub fn push_level(&mut self) {
        self.levels.push(SymLevel::new());
    }

    pub fn pop_level(&mut self) {
        assert!(self.levels.len() > 1);

        self.levels.pop();
    }

    pub fn get_last(&self, name: Name) -> Option<&Sym> {
        self.levels.last().unwrap().get(name)
    }

    pub fn get(&self, name: Name) -> Option<&Sym> {
        for level in self.levels.iter().rev() {
            if let Some(val) = level.get(name) {
                return Some(val);
            }
        }

        None
    }

    pub fn get_var(&self, name: Name) -> Option<NodeId> {
        self.get(name).and_then(|n| n.to_var())
    }

    pub fn get_type(&self, name: Name) -> Option<BuiltinType> {
        self.get(name).and_then(|n| n.to_type())
    }

    pub fn get_function(&self, name: Name) -> Option<NodeId> {
        self.get(name).and_then(|n| n.to_function())
    }

    pub fn insert(&mut self, name: Name, sym: Sym) -> Option<Sym> {
        self.levels.last_mut().unwrap().insert(name, sym)
    }
}

#[derive(Debug)]
struct SymLevel {
    map: HashMap<Name, Sym>
}

impl SymLevel {
    // creates a new table
    fn new() -> SymLevel {
        SymLevel {
            map: HashMap::new()
        }
    }

    // finds symbol in table
    fn get(&self, name: Name) -> Option<&Sym> {
        self.map.get(&name)
    }

    fn insert(&mut self, name: Name, sym: Sym) -> Option<Sym> {
        self.map.insert(name, sym)
    }
}

#[derive(Debug)]
pub enum Sym {
    SymType(BuiltinType),
    SymFunction(NodeId),
    SymVar(NodeId),
}

impl Sym {
    pub fn is_type(&self) -> bool {
        match *self {
            SymType(_) => true,
            _ => false
        }
    }

    pub fn to_type(&self) -> Option<BuiltinType> {
        match *self {
            SymType(builtin) => Some(builtin),
            _ => None
        }
    }

    pub fn is_function(&self) -> bool {
        match *self {
            SymFunction(_) => true,
            _ => false
        }
    }

    pub fn to_function(&self) -> Option<NodeId> {
        match *self {
            SymFunction(id) => Some(id),
            _ => None
        }
    }

    pub fn is_var(&self) -> bool {
        match *self {
            SymType(_) => true,
            _ => false
        }
    }

    pub fn to_var(&self) -> Option<NodeId> {
        match *self {
            SymVar(id) => Some(id),
            _ => None
        }
    }
}

#[derive(Debug, Copy, Clone)]
pub enum BuiltinType {
    Unit,
    Int,
    Bool,
    Str,
}
<|endoftext|>


<commit_before>use crate::rparser::*;
use ntp_parser::*;

pub struct NTPBuilder {}
impl RBuilder for NTPBuilder {
    fn build(&self) -> Box<dyn RParser> {
        Box::new(NtpParser::new(b"NTP"))
    }
    fn get_l4_probe(&self) -> Option<ProbeL4> {
        Some(ntp_probe)
    }
}

pub struct NtpParser<'a> {
    _name: Option<&'a [u8]>,
}

impl<'a> RParser for NtpParser<'a> {
    fn parse_l4(&mut self, data: &[u8], _direction: Direction) -> ParseResult {
        match parse_ntp(data) {
            Ok((rem, ref res)) => {
                debug!("parse_ntp: {:?}", res);
                if !rem.is_empty() {
                    warn!("Extra bytes after NTP data");
                }
            }
            e => warn!("parse_ntp: {:?}", e),
        };
        ParseResult::Ok
    }
}

impl<'a> NtpParser<'a> {
    pub fn new(name: &'a [u8]) -> NtpParser<'a> {
        NtpParser { _name: Some(name) }
    }
}

pub fn ntp_probe(i: &[u8], _l4info: &L4Info) -> ProbeResult {
    if i.len() <= 2 {
        return ProbeResult::Unsure;
    }
    match parse_ntp(i) {
        Ok(_) => true.into(),
        _ => ProbeResult::NotForUs,
    }
}
<commit_msg>NTP: be stricter when probing (test for UDP, and if length matches)<commit_after>use crate::rparser::*;
use ntp_parser::*;

pub struct NTPBuilder {}
impl RBuilder for NTPBuilder {
    fn build(&self) -> Box<dyn RParser> {
        Box::new(NtpParser::new(b"NTP"))
    }
    fn get_l4_probe(&self) -> Option<ProbeL4> {
        Some(ntp_probe)
    }
}

pub struct NtpParser<'a> {
    _name: Option<&'a [u8]>,
}

impl<'a> RParser for NtpParser<'a> {
    fn parse_l4(&mut self, data: &[u8], _direction: Direction) -> ParseResult {
        match parse_ntp(data) {
            Ok((rem, ref res)) => {
                debug!("parse_ntp: {:?}", res);
                if !rem.is_empty() {
                    warn!("Extra bytes after NTP data");
                }
            }
            e => warn!("parse_ntp: {:?}", e),
        };
        ParseResult::Ok
    }
}

impl<'a> NtpParser<'a> {
    pub fn new(name: &'a [u8]) -> NtpParser<'a> {
        NtpParser { _name: Some(name) }
    }
}

pub fn ntp_probe(i: &[u8], l4info: &L4Info) -> ProbeResult {
    if i.len() <= 2 {
        return ProbeResult::Unsure;
    }
    if l4info.l4_proto != 17 {
        return ProbeResult::NotForUs;
    }
    match parse_ntp(i) {
        Ok((rem, _)) => {
            if rem.is_empty() {
                // version was already tested
                ProbeResult::Certain
            } else {
                ProbeResult::Unsure
            }
        }
        _ => ProbeResult::NotForUs,
    }
}
<|endoftext|>


<commit_before>use collections::string::ToString;
use core::ops::*;

use bounded::Bounded;
use to_primitive::ToPrimitive;
use from_primitive::FromPrimitive;
use round::Round;
use one::One;
use sqrt::Sqrt;
use trig::Trig;
use zero::Zero;

pub trait Num:
    Copy + One + Zero
    + Bounded
    + ToPrimitive
    + FromPrimitive
    + Trig
    + Sqrt
    + Round
    + PartialEq
    + PartialOrd
    + ToString

    + Add<Self, Output = Self>
    + Mul<Self, Output = Self>
    + Sub<Self, Output = Self>
    + Div<Self, Output = Self>
    + Rem<Self, Output = Self>

    + AddAssign<Self>
    + MulAssign<Self>
    + SubAssign<Self>
    + DivAssign<Self>
    + RemAssign<Self>
{
    /// # Examples
    /// ~~~
    /// use num::Num;
    ///
    /// assert_eq!(50.min(&100), 50);
    /// assert_eq!(100.min(&50), 50);
    /// ~~~
    #[inline]
    fn min(&self, other: &Self) -> Self {
        if self < other {
            *self
        } else {
            *other
        }
    }
    /// # Examples
    /// ~~~
    /// use num::Num;
    ///
    /// assert_eq!(50.max(&100), 100);
    /// assert_eq!(100.max(&50), 100);
    /// ~~~
    #[inline]
    fn max(&self, other: &Self) -> Self {
        if self > other {
            *self
        } else {
            *other
        }
    }
    /// # Examples
    /// ~~~
    /// use num::Num;
    ///
    /// assert_eq!((-50).clamp(&0, &100), 0);
    /// assert_eq!(50.clamp(&0, &100), 50);
    /// assert_eq!(150.clamp(&0, &100), 100);
    /// ~~~
    #[inline]
    fn clamp(&self, min: &Self, max: &Self) -> Self {
        self.min(max).max(min)
    }
    /// # Examples
    /// ~~~
    /// use num::Num;
    ///
    /// assert_eq!((-0.5).clamp01(), 0.0);
    /// assert_eq!(0.5.clamp01(), 0.5);
    /// assert_eq!(1.50.clamp01(), 1.0);
    /// ~~~
    #[inline(always)]
    fn clamp01(&self) -> Self {
        self.clamp(&Zero::zero(), &One::one())
    }
}

impl<T> Num for T where T:
    Copy + One + Zero
    + Bounded
    + ToPrimitive
    + FromPrimitive
    + Trig
    + Sqrt
    + Round
    + PartialEq
    + PartialOrd
    + ToString

    + Add<T, Output = T>
    + Mul<T, Output = T>
    + Sub<T, Output = T>
    + Div<T, Output = T>
    + Rem<T, Output = T>

    + AddAssign<T>
    + MulAssign<T>
    + SubAssign<T>
    + DivAssign<T>
    + RemAssign<T> {}
<commit_msg>clean up<commit_after>use collections::string::ToString;
use core::ops::*;

use bounded::Bounded;
use to_primitive::ToPrimitive;
use from_primitive::FromPrimitive;
use round::Round;
use one::One;
use sqrt::Sqrt;
use trig::Trig;
use zero::Zero;

pub trait Num:
    Clone + One + Zero
    + Bounded
    + ToPrimitive
    + FromPrimitive
    + Trig
    + Sqrt
    + Round
    + PartialEq
    + PartialOrd
    + ToString

    + Add<Self, Output = Self>
    + Mul<Self, Output = Self>
    + Sub<Self, Output = Self>
    + Div<Self, Output = Self>
    + Rem<Self, Output = Self>

    + AddAssign<Self>
    + MulAssign<Self>
    + SubAssign<Self>
    + DivAssign<Self>
    + RemAssign<Self>
{
    /// # Examples
    /// ~~~
    /// use num::Num;
    ///
    /// assert_eq!(50.min(&100), 50);
    /// assert_eq!(100.min(&50), 50);
    /// ~~~
    #[inline]
    fn min(&self, other: &Self) -> Self {
        if self < other {
            self.clone()
        } else {
            other.clone()
        }
    }
    /// # Examples
    /// ~~~
    /// use num::Num;
    ///
    /// assert_eq!(50.max(&100), 100);
    /// assert_eq!(100.max(&50), 100);
    /// ~~~
    #[inline]
    fn max(&self, other: &Self) -> Self {
        if self > other {
            self.clone()
        } else {
            other.clone()
        }
    }
    /// # Examples
    /// ~~~
    /// use num::Num;
    ///
    /// assert_eq!((-50).clamp(&0, &100), 0);
    /// assert_eq!(50.clamp(&0, &100), 50);
    /// assert_eq!(150.clamp(&0, &100), 100);
    /// ~~~
    #[inline]
    fn clamp(&self, min: &Self, max: &Self) -> Self {
        self.min(max).max(min)
    }
    /// # Examples
    /// ~~~
    /// use num::Num;
    ///
    /// assert_eq!((-0.5).clamp01(), 0.0);
    /// assert_eq!(0.5.clamp01(), 0.5);
    /// assert_eq!(1.50.clamp01(), 1.0);
    /// ~~~
    #[inline(always)]
    fn clamp01(&self) -> Self {
        self.clamp(&Zero::zero(), &One::one())
    }
}

impl<T> Num for T where T:
    Copy + One + Zero
    + Bounded
    + ToPrimitive
    + FromPrimitive
    + Trig
    + Sqrt
    + Round
    + PartialEq
    + PartialOrd
    + ToString

    + Add<T, Output = T>
    + Mul<T, Output = T>
    + Sub<T, Output = T>
    + Div<T, Output = T>
    + Rem<T, Output = T>

    + AddAssign<T>
    + MulAssign<T>
    + SubAssign<T>
    + DivAssign<T>
    + RemAssign<T> {}
<|endoftext|>


<commit_before>type Vx = u8;
type Vy = u8;
type Addr = u16;
type Byte = u8;
type Nibble = u8;

pub struct Op {
    raw: u16
}

impl Op {
    pub fn new(raw: u16) -> Op {
        Op{ raw: raw }
    }

    #[allow(dead_code)]
    pub fn raw(&self) -> u16 {
        self.raw
    }

    pub fn addr(&self) -> Addr {
        self.raw & 0x0FFF
    }

    pub fn x(&self) -> Vx {
        ((self.raw & 0x0F00) >> 8) as u8
    }

    pub fn y(&self) -> Vy {
        ((self.raw & 0x00F0) >> 4) as u8
    }

    pub fn n_high(&self) -> Nibble {
        ((self.raw & 0xF000) >> 12) as u8
    }

    pub fn n_low(&self) -> Nibble {
        (self.raw & 0x000F) as u8
    }

    pub fn k(&self) -> Byte {
        (self.raw & 0x00FF) as u8
    }
}

#[derive(Show)]
pub enum Instruction {
    Sys(Addr),              // 0nnn - SYS addr
    Clear,                  // 00E0 - CLS
    Return,                 // 00EE - RET
    Jump(Addr),             // 1nnn - JP addr
    Call(Addr),             // 2nnn - CALL addr
    SkipEqualK(Vx, Byte),   // 3xkk - SE Vx, byte
    SkipNotEqualK(Vx, Byte),// 4xkk - SNE Vx, byte
    SkipEqual(Vx, Vy),      // 5xy0 - SE Vx, Vy
    SetK(Vx, Byte),         // 6xkk - LD Vx, byte
    AddK(Vx, Byte),         // 7xkk - ADD Vx, byte
    Set(Vx, Vy),            // 8xy0 - LD Vx, Vy
    Or(Vx, Vy),             // 8xy1 - OR Vx, Vy
    And(Vx, Vy),            // 8xy2 - AND Vx, Vy
    XOr(Vx, Vy),            // 8xy3 - XOR Vx, Vy
    Add(Vx, Vy),            // 8xy4 - ADD Vx, Vy
    Sub(Vx, Vy),            // 8xy5 - SUB Vx, Vy
    ShiftRight(Vx, Vy),     // 8xy6 - SHR Vx {, Vy}
    SubInv(Vx, Vy),         // 8xy7 - SUBN Vx, Vy
    ShiftLeft(Vx, Vy),      // 8xyE - SHL Vx {, Vy}
    SkipNotEqual(Vx, Vy),   // 9xy0 - SNE Vx, Vy
    LoadI(Addr),            // Annn - LD I, addr
    LongJump(Addr),         // Bnnn - JP V0, addr
    Rand(Vx, Byte),         // Cxkk - RND Vx, byte
    Draw(Vx, Vy, Nibble),   // Dxyn - DRW Vx, Vy, nibble
    SkipPressed(Vx),        // Ex9E - SKP Vx
    SkipNotPressed(Vx),     // ExA1 - SKNP Vx
    GetTimer(Vx),           // Fx07 - LD Vx, DT
    WaitKey(Vx),            // Fx0A - LD Vx, K
    SetTimer(Vx),           // Fx15 - LD DT, Vx
    SetSoundTimer(Vx),      // Fx18 - LD ST, Vx
    AddToI(Vx),             // Fx1E - ADD I, Vx
    LoadHexGlyph(Vx),       // Fx29 - LD F, Vx
    StoreBCD(Vx),           // Fx33 - LD B, Vx
    StoreRegisters(Vx),     // Fx55 - LD [I], Vx
    LoadRegisters(Vx),      // Fx65 - LD Vx, [I]
    Unknown,
}

impl Instruction {
    pub fn from_op(op: &Op) -> Instruction {
        use ops::Instruction::*;
        match op.n_high() {
            0x0 => {
                match op.k() {
                    0xE0 => Clear,
                    0xEE => Return,
                    _ => Sys(op.addr())
                }
            },
            0x1 => Jump(op.addr()),
            0x2 => Call(op.addr()),
            0x3 => SkipEqualK(op.x(), op.k()),
            0x4 => SkipNotEqualK(op.x(), op.k()),
            0x5 => SkipEqual(op.x(), op.y()),
            0x6 => SetK(op.x(), op.k()),
            0x7 => AddK(op.x(), op.k()),
            0x8 => {
                match op.n_low() {
                    0x0 => Set(op.x(), op.y()),
                    0x1 => Or(op.x(), op.y()),
                    0x2 => And(op.x(), op.y()),
                    0x3 => XOr(op.x(), op.y()),
                    0x4 => Add(op.x(), op.y()),
                    0x5 => Sub(op.x(), op.y()),
                    0x6 => ShiftRight(op.x(), op.y()),
                    0x7 => SubInv(op.x(), op.y()),
                    0xE => ShiftLeft(op.x(), op.y()),
                    _ => Unknown
                }
            },
            0x9 => SkipNotEqual(op.x(), op.y()),
            0xA => LoadI(op.addr()),
            0xB => LongJump(op.addr()),
            0xC => Rand(op.x(), op.k()),
            0xD => Draw(op.x(), op.y(), op.n_low()),
            0xE => {
                match op.k() {
                    0x9E => SkipPressed(op.x()),
                    0xA1 => SkipNotPressed(op.x()),
                    _ => Unknown,
                }
            },
            0xF => {
                match op.k() {
                    0x07 => GetTimer(op.x()),
                    0x0A => WaitKey(op.x()),
                    0x15 => SetTimer(op.x()),
                    0x18 => SetSoundTimer(op.x()),
                    0x1E => AddToI(op.x()),
                    0x29 => LoadHexGlyph(op.x()),
                    0x33 => StoreBCD(op.x()),
                    0x55 => StoreRegisters(op.x()),
                    0x65 => LoadRegisters(op.x()),
                    _ => Unknown,
                }
            }
            _ => Unknown
        }
    }
}
<commit_msg>Derive from Debug instead of Show<commit_after>type Vx = u8;
type Vy = u8;
type Addr = u16;
type Byte = u8;
type Nibble = u8;

pub struct Op {
    raw: u16
}

impl Op {
    pub fn new(raw: u16) -> Op {
        Op{ raw: raw }
    }

    #[allow(dead_code)]
    pub fn raw(&self) -> u16 {
        self.raw
    }

    pub fn addr(&self) -> Addr {
        self.raw & 0x0FFF
    }

    pub fn x(&self) -> Vx {
        ((self.raw & 0x0F00) >> 8) as u8
    }

    pub fn y(&self) -> Vy {
        ((self.raw & 0x00F0) >> 4) as u8
    }

    pub fn n_high(&self) -> Nibble {
        ((self.raw & 0xF000) >> 12) as u8
    }

    pub fn n_low(&self) -> Nibble {
        (self.raw & 0x000F) as u8
    }

    pub fn k(&self) -> Byte {
        (self.raw & 0x00FF) as u8
    }
}

#[derive(Debug)]
pub enum Instruction {
    Sys(Addr),              // 0nnn - SYS addr
    Clear,                  // 00E0 - CLS
    Return,                 // 00EE - RET
    Jump(Addr),             // 1nnn - JP addr
    Call(Addr),             // 2nnn - CALL addr
    SkipEqualK(Vx, Byte),   // 3xkk - SE Vx, byte
    SkipNotEqualK(Vx, Byte),// 4xkk - SNE Vx, byte
    SkipEqual(Vx, Vy),      // 5xy0 - SE Vx, Vy
    SetK(Vx, Byte),         // 6xkk - LD Vx, byte
    AddK(Vx, Byte),         // 7xkk - ADD Vx, byte
    Set(Vx, Vy),            // 8xy0 - LD Vx, Vy
    Or(Vx, Vy),             // 8xy1 - OR Vx, Vy
    And(Vx, Vy),            // 8xy2 - AND Vx, Vy
    XOr(Vx, Vy),            // 8xy3 - XOR Vx, Vy
    Add(Vx, Vy),            // 8xy4 - ADD Vx, Vy
    Sub(Vx, Vy),            // 8xy5 - SUB Vx, Vy
    ShiftRight(Vx, Vy),     // 8xy6 - SHR Vx {, Vy}
    SubInv(Vx, Vy),         // 8xy7 - SUBN Vx, Vy
    ShiftLeft(Vx, Vy),      // 8xyE - SHL Vx {, Vy}
    SkipNotEqual(Vx, Vy),   // 9xy0 - SNE Vx, Vy
    LoadI(Addr),            // Annn - LD I, addr
    LongJump(Addr),         // Bnnn - JP V0, addr
    Rand(Vx, Byte),         // Cxkk - RND Vx, byte
    Draw(Vx, Vy, Nibble),   // Dxyn - DRW Vx, Vy, nibble
    SkipPressed(Vx),        // Ex9E - SKP Vx
    SkipNotPressed(Vx),     // ExA1 - SKNP Vx
    GetTimer(Vx),           // Fx07 - LD Vx, DT
    WaitKey(Vx),            // Fx0A - LD Vx, K
    SetTimer(Vx),           // Fx15 - LD DT, Vx
    SetSoundTimer(Vx),      // Fx18 - LD ST, Vx
    AddToI(Vx),             // Fx1E - ADD I, Vx
    LoadHexGlyph(Vx),       // Fx29 - LD F, Vx
    StoreBCD(Vx),           // Fx33 - LD B, Vx
    StoreRegisters(Vx),     // Fx55 - LD [I], Vx
    LoadRegisters(Vx),      // Fx65 - LD Vx, [I]
    Unknown,
}

impl Instruction {
    pub fn from_op(op: &Op) -> Instruction {
        use ops::Instruction::*;
        match op.n_high() {
            0x0 => {
                match op.k() {
                    0xE0 => Clear,
                    0xEE => Return,
                    _ => Sys(op.addr())
                }
            },
            0x1 => Jump(op.addr()),
            0x2 => Call(op.addr()),
            0x3 => SkipEqualK(op.x(), op.k()),
            0x4 => SkipNotEqualK(op.x(), op.k()),
            0x5 => SkipEqual(op.x(), op.y()),
            0x6 => SetK(op.x(), op.k()),
            0x7 => AddK(op.x(), op.k()),
            0x8 => {
                match op.n_low() {
                    0x0 => Set(op.x(), op.y()),
                    0x1 => Or(op.x(), op.y()),
                    0x2 => And(op.x(), op.y()),
                    0x3 => XOr(op.x(), op.y()),
                    0x4 => Add(op.x(), op.y()),
                    0x5 => Sub(op.x(), op.y()),
                    0x6 => ShiftRight(op.x(), op.y()),
                    0x7 => SubInv(op.x(), op.y()),
                    0xE => ShiftLeft(op.x(), op.y()),
                    _ => Unknown
                }
            },
            0x9 => SkipNotEqual(op.x(), op.y()),
            0xA => LoadI(op.addr()),
            0xB => LongJump(op.addr()),
            0xC => Rand(op.x(), op.k()),
            0xD => Draw(op.x(), op.y(), op.n_low()),
            0xE => {
                match op.k() {
                    0x9E => SkipPressed(op.x()),
                    0xA1 => SkipNotPressed(op.x()),
                    _ => Unknown,
                }
            },
            0xF => {
                match op.k() {
                    0x07 => GetTimer(op.x()),
                    0x0A => WaitKey(op.x()),
                    0x15 => SetTimer(op.x()),
                    0x18 => SetSoundTimer(op.x()),
                    0x1E => AddToI(op.x()),
                    0x29 => LoadHexGlyph(op.x()),
                    0x33 => StoreBCD(op.x()),
                    0x55 => StoreRegisters(op.x()),
                    0x65 => LoadRegisters(op.x()),
                    _ => Unknown,
                }
            }
            _ => Unknown
        }
    }
}
<|endoftext|>