<commit_before>extern crate core;

use self::core::nonzero::NonZero;
use std::fmt;
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};

/// `Raw` is like `Unique`, but even more unsafe. This is specifically meant to be an unsafe
/// wrapper around `*mut T` and should be used extremely carefully. The primary purpose is to make
/// it very easy to work with `*mut T` by implementing `Deref` and `DerefMut` with their targets
/// being &T and `&mut T`.
pub struct Raw<T: ?Sized> {
    ptr: NonZero<*const T>,
    mkr: PhantomData<T>,
}

impl<T: ?Sized> Raw<T> {
    pub const fn new(ptr: *mut T) -> Raw<T> {
        unsafe { Raw { ptr: NonZero::new(ptr), mkr: PhantomData } }
    }

    pub fn ptr(&self) -> *mut T {
        unsafe { mem::transmute(*self.ptr) }
    }

    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
        *this.ptr == *other.ptr
    }
}

impl<T: ?Sized> Clone for Raw<T> {
    fn clone(&self) -> Self {
        *self
    }
}

impl<T: ?Sized> Copy for Raw<T> { }

unsafe impl<T: Send + ?Sized> Send for Raw<T> { }
unsafe impl<T: Sync + ?Sized> Sync for Raw<T> { }

impl<T: ?Sized> Deref for Raw<T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &T {
        unsafe { &**self.ptr }
    }
}

impl<T: ?Sized> DerefMut for Raw<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.ptr() }
    }
}

impl<T> fmt::Pointer for Raw<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Pointer::fmt(&*self.ptr, f)
    }
}

impl<T: ?Sized + fmt::Debug> fmt::Debug for Raw<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&**self, f)
    }
}

impl<T> From<T> for Raw<T> {
	fn from(t: T) -> Raw<T> {
        Raw::new(Box::into_raw(Box::new(t)))
    }
}
<commit_msg>ptr: fix NonZero for nightly changes<commit_after>extern crate core;

use self::core::nonzero::NonZero;
use std::fmt;
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};

/// `Raw` is like `Unique`, but even more unsafe. This is specifically meant to be an unsafe
/// wrapper around `*mut T` and should be used extremely carefully. The primary purpose is to make
/// it very easy to work with `*mut T` by implementing `Deref` and `DerefMut` with their targets
/// being &T and `&mut T`.
pub struct Raw<T: ?Sized> {
    ptr: NonZero<*const T>,
    mkr: PhantomData<T>,
}

impl<T: ?Sized> Raw<T> {
    pub const fn new(ptr: *mut T) -> Raw<T> {
        unsafe { Raw { ptr: NonZero::new(ptr), mkr: PhantomData } }
    }

    pub fn ptr(&self) -> *mut T {
        unsafe { mem::transmute(self.ptr.get()) }
    }

    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
        this.ptr.get() == other.ptr.get()
    }
}

impl<T: ?Sized> Clone for Raw<T> {
    fn clone(&self) -> Self {
        *self
    }
}

impl<T: ?Sized> Copy for Raw<T> { }

unsafe impl<T: Send + ?Sized> Send for Raw<T> { }
unsafe impl<T: Sync + ?Sized> Sync for Raw<T> { }

impl<T: ?Sized> Deref for Raw<T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &T {
        unsafe { &*self.ptr.get() }
    }
}

impl<T: ?Sized> DerefMut for Raw<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.ptr() }
    }
}

impl<T: ?Sized + fmt::Debug> fmt::Debug for Raw<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&**self, f)
    }
}

impl<T> From<T> for Raw<T> {
	fn from(t: T) -> Raw<T> {
        Raw::new(Box::into_raw(Box::new(t)))
    }
}
<|endoftext|>


<commit_before>use super::FLAG;
use super::aligned_vec::*;
use super::error::*;
use super::pair::{Pair, ToPair};
use super::traits::*;

use ffi;
pub use ffi::fftw_r2r_kind as R2R_KIND;

use ndarray::*;
use ndarray_linalg::Scalar;

fn forward(kind: R2R_KIND) -> R2R_KIND {
    match kind {
        R2R_KIND::FFTW_R2HC => R2R_KIND::FFTW_R2HC,
        R2R_KIND::FFTW_HC2R => R2R_KIND::FFTW_R2HC,
        R2R_KIND::FFTW_DHT => R2R_KIND::FFTW_DHT,
        R2R_KIND::FFTW_REDFT00 => R2R_KIND::FFTW_REDFT00,
        R2R_KIND::FFTW_REDFT01 => R2R_KIND::FFTW_REDFT10,
        R2R_KIND::FFTW_REDFT10 => R2R_KIND::FFTW_REDFT10,
        R2R_KIND::FFTW_REDFT11 => R2R_KIND::FFTW_REDFT11,
        R2R_KIND::FFTW_RODFT00 => R2R_KIND::FFTW_RODFT00,
        R2R_KIND::FFTW_RODFT01 => R2R_KIND::FFTW_RODFT10,
        R2R_KIND::FFTW_RODFT10 => R2R_KIND::FFTW_RODFT10,
        R2R_KIND::FFTW_RODFT11 => R2R_KIND::FFTW_RODFT11,
    }
}

fn backward(kind: R2R_KIND) -> R2R_KIND {
    match kind {
        R2R_KIND::FFTW_R2HC => R2R_KIND::FFTW_HC2R,
        R2R_KIND::FFTW_HC2R => R2R_KIND::FFTW_HC2R,
        R2R_KIND::FFTW_DHT => R2R_KIND::FFTW_DHT,
        R2R_KIND::FFTW_REDFT00 => R2R_KIND::FFTW_REDFT00,
        R2R_KIND::FFTW_REDFT01 => R2R_KIND::FFTW_REDFT01,
        R2R_KIND::FFTW_REDFT10 => R2R_KIND::FFTW_REDFT01,
        R2R_KIND::FFTW_REDFT11 => R2R_KIND::FFTW_REDFT11,
        R2R_KIND::FFTW_RODFT00 => R2R_KIND::FFTW_RODFT00,
        R2R_KIND::FFTW_RODFT01 => R2R_KIND::FFTW_RODFT01,
        R2R_KIND::FFTW_RODFT10 => R2R_KIND::FFTW_RODFT01,
        R2R_KIND::FFTW_RODFT11 => R2R_KIND::FFTW_RODFT11,
    }
}

/// see http://www.fftw.org/fftw3_doc/Real_002dto_002dReal-Transform-Kinds.html
fn logical_size(n: usize, kind: R2R_KIND) -> usize {
    match kind {
        R2R_KIND::FFTW_R2HC => n,
        R2R_KIND::FFTW_HC2R => n,
        R2R_KIND::FFTW_DHT => n,
        R2R_KIND::FFTW_REDFT00 => 2 * (n - 1),
        R2R_KIND::FFTW_REDFT01 => 2 * n,
        R2R_KIND::FFTW_REDFT10 => 2 * n,
        R2R_KIND::FFTW_REDFT11 => 2 * n,
        R2R_KIND::FFTW_RODFT00 => 2 * (n + 1),
        R2R_KIND::FFTW_RODFT01 => 2 * n,
        R2R_KIND::FFTW_RODFT10 => 2 * n,
        R2R_KIND::FFTW_RODFT11 => 2 * n,
    }
}

#[derive(Debug, Clone, Copy, new)]
pub struct R2R1D {
    n: usize,
    kind: R2R_KIND,
    flag: FLAG,
}

pub fn r2hc_1d(n: usize) -> R2R1D {
    R2R1D {
        n: n,
        kind: R2R_KIND::FFTW_R2HC,
        flag: ffi::FFTW_MEASURE,
    }
}

impl<T: FFTWReal> ToPair<T, T> for R2R1D {
    type Dim = Ix1;
    fn to_pair(&self) -> Result<Pair<T, T, Ix1>> {
        let mut a = AlignedVec::new(self.n);
        let mut b = AlignedVec::new(self.n);
        let forward = unsafe { T::r2r_1d(self.n, &mut a, &mut b, forward(self.kind), self.flag) };
        let backward = unsafe { T::r2r_1d(self.n, &mut b, &mut a, backward(self.kind), self.flag) };
        Pair {
            a,
            b,
            size: self.n.into_dimension(),
            forward,
            backward,
            factor_f: Some(Scalar::from_f64(1.0 / self.n as f64)),
            factor_b: None,
        }.null_checked()
    }
}
<commit_msg>Drop logical_size<commit_after>use super::FLAG;
use super::aligned_vec::*;
use super::error::*;
use super::pair::{Pair, ToPair};
use super::traits::*;

use ffi;
pub use ffi::fftw_r2r_kind as R2R_KIND;

use ndarray::*;
use ndarray_linalg::Scalar;

fn forward(kind: R2R_KIND) -> R2R_KIND {
    match kind {
        R2R_KIND::FFTW_R2HC => R2R_KIND::FFTW_R2HC,
        R2R_KIND::FFTW_HC2R => R2R_KIND::FFTW_R2HC,
        R2R_KIND::FFTW_DHT => R2R_KIND::FFTW_DHT,
        R2R_KIND::FFTW_REDFT00 => R2R_KIND::FFTW_REDFT00,
        R2R_KIND::FFTW_REDFT01 => R2R_KIND::FFTW_REDFT10,
        R2R_KIND::FFTW_REDFT10 => R2R_KIND::FFTW_REDFT10,
        R2R_KIND::FFTW_REDFT11 => R2R_KIND::FFTW_REDFT11,
        R2R_KIND::FFTW_RODFT00 => R2R_KIND::FFTW_RODFT00,
        R2R_KIND::FFTW_RODFT01 => R2R_KIND::FFTW_RODFT10,
        R2R_KIND::FFTW_RODFT10 => R2R_KIND::FFTW_RODFT10,
        R2R_KIND::FFTW_RODFT11 => R2R_KIND::FFTW_RODFT11,
    }
}

fn backward(kind: R2R_KIND) -> R2R_KIND {
    match kind {
        R2R_KIND::FFTW_R2HC => R2R_KIND::FFTW_HC2R,
        R2R_KIND::FFTW_HC2R => R2R_KIND::FFTW_HC2R,
        R2R_KIND::FFTW_DHT => R2R_KIND::FFTW_DHT,
        R2R_KIND::FFTW_REDFT00 => R2R_KIND::FFTW_REDFT00,
        R2R_KIND::FFTW_REDFT01 => R2R_KIND::FFTW_REDFT01,
        R2R_KIND::FFTW_REDFT10 => R2R_KIND::FFTW_REDFT01,
        R2R_KIND::FFTW_REDFT11 => R2R_KIND::FFTW_REDFT11,
        R2R_KIND::FFTW_RODFT00 => R2R_KIND::FFTW_RODFT00,
        R2R_KIND::FFTW_RODFT01 => R2R_KIND::FFTW_RODFT01,
        R2R_KIND::FFTW_RODFT10 => R2R_KIND::FFTW_RODFT01,
        R2R_KIND::FFTW_RODFT11 => R2R_KIND::FFTW_RODFT11,
    }
}

#[derive(Debug, Clone, Copy, new)]
pub struct R2R1D {
    n: usize,
    kind: R2R_KIND,
    flag: FLAG,
}

pub fn r2hc_1d(n: usize) -> R2R1D {
    R2R1D {
        n: n,
        kind: R2R_KIND::FFTW_R2HC,
        flag: ffi::FFTW_MEASURE,
    }
}

impl<T: FFTWReal> ToPair<T, T> for R2R1D {
    type Dim = Ix1;
    fn to_pair(&self) -> Result<Pair<T, T, Ix1>> {
        let mut a = AlignedVec::new(self.n);
        let mut b = AlignedVec::new(self.n);
        let forward = unsafe { T::r2r_1d(self.n, &mut a, &mut b, forward(self.kind), self.flag) };
        let backward = unsafe { T::r2r_1d(self.n, &mut b, &mut a, backward(self.kind), self.flag) };
        Pair {
            a,
            b,
            size: self.n.into_dimension(),
            forward,
            backward,
            factor_f: Some(Scalar::from_f64(1.0 / self.n as f64)),
            factor_b: None,
        }.null_checked()
    }
}
<|endoftext|>


<commit_before>use std::mem;
use std::raw;
use rand::{Rng, SeedableRng};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
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> Decodable for EncodeRng<T> {
    fn decode<D: Decoder>(d: &mut D) -> Result<EncodeRng<T>, D::Error> {
        let blob: Vec<u8> = try!(Decodable::decode(d));
        unsafe {
            if blob.len() == mem::size_of::<T>() {
                Ok(EncodeRng::new(mem::transmute_copy(&blob[0])))
            } else {
                Err(d.error("Bad RNG blob length"))
            }
        }
    }
}

impl<T: 'static> Encodable for EncodeRng<T> {
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        let blob: &[u8] = unsafe {
            mem::transmute::<raw::Slice<u8>, &[u8]>(raw::Slice {
                data: mem::transmute(&self.inner),
                len: mem::size_of::<T>(),
            })
        };
        blob.encode(s)
    }
}
<commit_msg>Stable EncodeRng<commit_after>use std::mem;
use rand::{Rng, SeedableRng};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
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> Decodable for EncodeRng<T> {
    fn decode<D: Decoder>(d: &mut D) -> Result<EncodeRng<T>, D::Error> {
        let blob: Vec<u8> = try!(Decodable::decode(d));
        unsafe {
            if blob.len() == mem::size_of::<T>() {
                Ok(EncodeRng::new(mem::transmute_copy(&blob[0])))
            } else {
                Err(d.error("Bad RNG blob length"))
            }
        }
    }
}

impl<T: 'static> Encodable for EncodeRng<T> {
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        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.encode(s)
    }
}
<|endoftext|>


<commit_before>#[derive(Debug, Clone)]
pub struct PascalsTriangle {
    _rows: Vec<Vec<u32>>,
}

impl PascalsTriangle {
    pub fn new(row_count: u32) -> Self {
        PascalsTriangle { _rows: create(row_count as usize) }
    }
    pub fn rows(&self) -> Vec<Vec<u32>> {
        self._rows.clone()
    }
}

fn create(row_count: usize) -> Vec<Vec<u32>> {
    if row_count == 0 {
        vec![]
    } else {
        let mut rs: Vec<Vec<u32>> = vec![vec![1]];
        for i in 1..row_count {
            let mut r = rs[i - 1].clone();
            r.insert(0, 1);
            for j in 1..r.len() - 1 {
                r[j] = r[j] + r[j + 1];
            }
            rs.push(r);
        }
        rs
    }
}
<commit_msg>clippy<commit_after>#[derive(Debug, Clone)]
pub struct PascalsTriangle {
    _rows: Vec<Vec<u32>>,
}

impl PascalsTriangle {
    pub fn new(row_count: u32) -> Self {
        PascalsTriangle { _rows: create(row_count as usize) }
    }
    pub fn rows(&self) -> Vec<Vec<u32>> {
        self._rows.clone()
    }
}

fn create(row_count: usize) -> Vec<Vec<u32>> {
    if row_count == 0 {
        vec![]
    } else {
        let mut rs: Vec<Vec<u32>> = vec![vec![1]];
        for i in 1..row_count {
            let mut r = rs[i - 1].clone();
            r.insert(0, 1);
            for j in 1..r.len() - 1 {
                r[j] += r[j + 1];
            }
            rs.push(r);
        }
        rs
    }
}
<|endoftext|>


<commit_before>#![stable(feature = "wake_trait", since = "1.51.0")]
//! Types and Traits for working with asynchronous tasks.
use core::mem::ManuallyDrop;
use core::task::{RawWaker, RawWakerVTable, Waker};

use crate::sync::Arc;

/// The implementation of waking a task on an executor.
///
/// This trait can be used to create a [`Waker`]. An executor can define an
/// implementation of this trait, and use that to construct a Waker to pass
/// to the tasks that are executed on that executor.
///
/// This trait is a memory-safe and ergonomic alternative to constructing a
/// [`RawWaker`]. It supports the common executor design in which the data used
/// to wake up a task is stored in an [`Arc`]. Some executors (especially
/// those for embedded systems) cannot use this API, which is why [`RawWaker`]
/// exists as an alternative for those systems.
///
/// [arc]: ../../std/sync/struct.Arc.html
///
/// # Examples
///
/// A basic `block_on` function that takes a future and runs it to completion on
/// the current thread.
///
/// **Note:** This example trades correctness for simplicity. In order to prevent
/// deadlocks, production-grade implementations will also need to handle
/// intermediate calls to `thread::unpark` as well as nested invocations.
///
/// ```rust
/// use std::future::Future;
/// use std::sync::Arc;
/// use std::task::{Context, Poll, Wake};
/// use std::thread::{self, Thread};
///
/// /// A waker that wakes up the current thread when called.
/// struct ThreadWaker(Thread);
///
/// impl Wake for ThreadWaker {
///     fn wake(self: Arc<Self>) {
///         self.0.unpark();
///     }
/// }
///
/// /// Run a future to completion on the current thread.
/// fn block_on<T>(fut: impl Future<Output = T>) -> T {
///     // Pin the future so it can be polled.
///     let mut fut = Box::pin(fut);
///
///     // Create a new context to be passed to the future.
///     let t = thread::current();
///     let waker = Arc::new(ThreadWaker(t)).into();
///     let mut cx = Context::from_waker(&waker);
///
///     // Run the future to completion.
///     loop {
///         match fut.as_mut().poll(&mut cx) {
///             Poll::Ready(res) => return res,
///             Poll::Pending => thread::park(),
///         }
///     }
/// }
///
/// block_on(async {
///     println!("Hi from inside a future!");
/// });
/// ```
#[stable(feature = "wake_trait", since = "1.51.0")]
pub trait Wake {
    /// Wake this task.
    #[stable(feature = "wake_trait", since = "1.51.0")]
    fn wake(self: Arc<Self>);

    /// Wake this task without consuming the waker.
    ///
    /// If an executor supports a cheaper way to wake without consuming the
    /// waker, it should override this method. By default, it clones the
    /// [`Arc`] and calls [`wake`] on the clone.
    ///
    /// [`wake`]: Wake::wake
    #[stable(feature = "wake_trait", since = "1.51.0")]
    fn wake_by_ref(self: &Arc<Self>) {
        self.clone().wake();
    }
}

#[stable(feature = "wake_trait", since = "1.51.0")]
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
    fn from(waker: Arc<W>) -> Waker {
        // SAFETY: This is safe because raw_waker safely constructs
        // a RawWaker from Arc<W>.
        unsafe { Waker::from_raw(raw_waker(waker)) }
    }
}

#[stable(feature = "wake_trait", since = "1.51.0")]
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
    fn from(waker: Arc<W>) -> RawWaker {
        raw_waker(waker)
    }
}

// NB: This private function for constructing a RawWaker is used, rather than
// inlining this into the `From<Arc<W>> for RawWaker` impl, to ensure that
// the safety of `From<Arc<W>> for Waker` does not depend on the correct
// trait dispatch - instead both impls call this function directly and
// explicitly.
#[inline(always)]
fn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker {
    // Increment the reference count of the arc to clone it.
    unsafe fn clone_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) -> RawWaker {
        unsafe { Arc::increment_strong_count(waker as *const W) };
        RawWaker::new(
            waker as *const (),
            &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
        )
    }

    // Wake by value, moving the Arc into the Wake::wake function
    unsafe fn wake<W: Wake + Send + Sync + 'static>(waker: *const ()) {
        let waker = unsafe { Arc::from_raw(waker as *const W) };
        <W as Wake>::wake(waker);
    }

    // Wake by reference, wrap the waker in ManuallyDrop to avoid dropping it
    unsafe fn wake_by_ref<W: Wake + Send + Sync + 'static>(waker: *const ()) {
        let waker = unsafe { ManuallyDrop::new(Arc::from_raw(waker as *const W)) };
        <W as Wake>::wake_by_ref(&waker);
    }

    // Decrement the reference count of the Arc on drop
    unsafe fn drop_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) {
        unsafe { Arc::decrement_strong_count(waker as *const W) };
    }

    RawWaker::new(
        Arc::into_raw(waker) as *const (),
        &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
    )
}
<commit_msg>Rollup merge of #84453 - notriddle:waker-from-docs, r=cramertj<commit_after>#![stable(feature = "wake_trait", since = "1.51.0")]
//! Types and Traits for working with asynchronous tasks.
use core::mem::ManuallyDrop;
use core::task::{RawWaker, RawWakerVTable, Waker};

use crate::sync::Arc;

/// The implementation of waking a task on an executor.
///
/// This trait can be used to create a [`Waker`]. An executor can define an
/// implementation of this trait, and use that to construct a Waker to pass
/// to the tasks that are executed on that executor.
///
/// This trait is a memory-safe and ergonomic alternative to constructing a
/// [`RawWaker`]. It supports the common executor design in which the data used
/// to wake up a task is stored in an [`Arc`]. Some executors (especially
/// those for embedded systems) cannot use this API, which is why [`RawWaker`]
/// exists as an alternative for those systems.
///
/// [arc]: ../../std/sync/struct.Arc.html
///
/// # Examples
///
/// A basic `block_on` function that takes a future and runs it to completion on
/// the current thread.
///
/// **Note:** This example trades correctness for simplicity. In order to prevent
/// deadlocks, production-grade implementations will also need to handle
/// intermediate calls to `thread::unpark` as well as nested invocations.
///
/// ```rust
/// use std::future::Future;
/// use std::sync::Arc;
/// use std::task::{Context, Poll, Wake};
/// use std::thread::{self, Thread};
///
/// /// A waker that wakes up the current thread when called.
/// struct ThreadWaker(Thread);
///
/// impl Wake for ThreadWaker {
///     fn wake(self: Arc<Self>) {
///         self.0.unpark();
///     }
/// }
///
/// /// Run a future to completion on the current thread.
/// fn block_on<T>(fut: impl Future<Output = T>) -> T {
///     // Pin the future so it can be polled.
///     let mut fut = Box::pin(fut);
///
///     // Create a new context to be passed to the future.
///     let t = thread::current();
///     let waker = Arc::new(ThreadWaker(t)).into();
///     let mut cx = Context::from_waker(&waker);
///
///     // Run the future to completion.
///     loop {
///         match fut.as_mut().poll(&mut cx) {
///             Poll::Ready(res) => return res,
///             Poll::Pending => thread::park(),
///         }
///     }
/// }
///
/// block_on(async {
///     println!("Hi from inside a future!");
/// });
/// ```
#[stable(feature = "wake_trait", since = "1.51.0")]
pub trait Wake {
    /// Wake this task.
    #[stable(feature = "wake_trait", since = "1.51.0")]
    fn wake(self: Arc<Self>);

    /// Wake this task without consuming the waker.
    ///
    /// If an executor supports a cheaper way to wake without consuming the
    /// waker, it should override this method. By default, it clones the
    /// [`Arc`] and calls [`wake`] on the clone.
    ///
    /// [`wake`]: Wake::wake
    #[stable(feature = "wake_trait", since = "1.51.0")]
    fn wake_by_ref(self: &Arc<Self>) {
        self.clone().wake();
    }
}

#[stable(feature = "wake_trait", since = "1.51.0")]
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
    /// Use a `Wake`-able type as a `Waker`.
    ///
    /// No heap allocations or atomic operations are used for this conversion.
    fn from(waker: Arc<W>) -> Waker {
        // SAFETY: This is safe because raw_waker safely constructs
        // a RawWaker from Arc<W>.
        unsafe { Waker::from_raw(raw_waker(waker)) }
    }
}

#[stable(feature = "wake_trait", since = "1.51.0")]
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
    /// Use a `Wake`-able type as a `RawWaker`.
    ///
    /// No heap allocations or atomic operations are used for this conversion.
    fn from(waker: Arc<W>) -> RawWaker {
        raw_waker(waker)
    }
}

// NB: This private function for constructing a RawWaker is used, rather than
// inlining this into the `From<Arc<W>> for RawWaker` impl, to ensure that
// the safety of `From<Arc<W>> for Waker` does not depend on the correct
// trait dispatch - instead both impls call this function directly and
// explicitly.
#[inline(always)]
fn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker {
    // Increment the reference count of the arc to clone it.
    unsafe fn clone_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) -> RawWaker {
        unsafe { Arc::increment_strong_count(waker as *const W) };
        RawWaker::new(
            waker as *const (),
            &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
        )
    }

    // Wake by value, moving the Arc into the Wake::wake function
    unsafe fn wake<W: Wake + Send + Sync + 'static>(waker: *const ()) {
        let waker = unsafe { Arc::from_raw(waker as *const W) };
        <W as Wake>::wake(waker);
    }

    // Wake by reference, wrap the waker in ManuallyDrop to avoid dropping it
    unsafe fn wake_by_ref<W: Wake + Send + Sync + 'static>(waker: *const ()) {
        let waker = unsafe { ManuallyDrop::new(Arc::from_raw(waker as *const W)) };
        <W as Wake>::wake_by_ref(&waker);
    }

    // Decrement the reference count of the Arc on drop
    unsafe fn drop_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) {
        unsafe { Arc::decrement_strong_count(waker as *const W) };
    }

    RawWaker::new(
        Arc::into_raw(waker) as *const (),
        &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),
    )
}
<|endoftext|>


<commit_before>use std::collections::{HashMap, HashSet};
use std::str::FromStr;

/// A shader module.
///
/// A shader module is a container that associates some shading code to several identifiers.
struct ShaderModule {
  symbols: HashMap<Identifier, ShadingCode>
}

/// Spectra Shading Language AST.
#[derive(Clone, Debug, Eq, PartialEq)]
enum SSL {
  /// An `export list_of_identifiers_` statement.
  Export(ExportList),
  /// A `from module use list of identifiers` statement.
  FromUse(ImportList),
  /// A `pipeline { list_of_pipeline_attributes }` statement.
  Pipeline(PipelineStatement),
  /// A yield statement, valid in geometry shaders.
  Yield(GeometryYieldExpression),
  /// Some legacy GLSL code.
  GLSL(ShadingCode),
  /// Some more SSL code.
  SSL(Box<SSL>)
}

/// A module.
type Module = String;
/// An identifier.
type Identifier = String;
/// Some opaque shading code.
type ShadingCode = String;
/// An expression.
type Expression = String;

/// An export non-empty list.
#[derive(Clone, Debug, Eq, PartialEq)]
struct ExportList {
  list: HashSet<Identifier>
}

/// An import non-empty list.
#[derive(Clone, Debug, Eq, PartialEq)]
struct ImportList {
  module: Module,
  list: HashSet<Identifier>
}

/// A pipeline statement.
#[derive(Clone, Debug, Eq, PartialEq)]
struct PipelineStatement {
  attributes: Vec<PipelineAttribute>
}

/// Attributes that can be set in a pipeline.
#[derive(Clone, Debug, Eq, PartialEq)]
enum PipelineAttribute {
  /// Maximum vertices that the geometry shader can output.
  GeometryShaderMaxVertices(u32),
  /// Number of times the geometry shader must be invoked.
  GeometryShaderInvokations(u32)
}

/// Expressions that can be yielded in a geometry shader.
#[derive(Clone, Debug, Eq, PartialEq)]
enum GeometryYieldExpression {
  /// Yield a primitive.
  YieldPrimitive,
  /// Yield a primitive’s vertex (fold vertex).
  YieldFoldVertex(Expression)
}

/// Error that can occur when parsing SSL code.
#[derive(Clone, Debug, Eq, PartialEq)]
enum ParseError {
  ExpressionError(String)
}

impl FromStr for PipelineAttribute {
  type Err = ParseError;

  fn from_str(s: &str) -> Result<Self, Self::Err> {
    let equal_sign_idx = s.find('=').ok_or(ParseError::ExpressionError("cannot find =".into()))?;
    let (key, value) = s.split_at(equal_sign_idx);

    if value.len() <= 1 {
      return Err(ParseError::ExpressionError("no value".into()));
    }

    match key.trim() {
      "geometry_shader_max_vertices" => {
        let value = (&value[1..]).trim();
        let max_vertices = value.parse().map_err(|_| ParseError::ExpressionError(format!("unable to parse geometry_shader_max_vertices, found {}", value)))?;
        Ok(PipelineAttribute::GeometryShaderMaxVertices(max_vertices))
      },
      "geometry_shader_invokations" => {
        let value = (&value[1..]).trim();
        let invokations = value.parse().map_err(|_| ParseError::ExpressionError(format!("unable to parse geometry_shader_invokation, found {}", value)))?;
        Ok(PipelineAttribute::GeometryShaderInvokations(invokations))
      },
      _ => Err(ParseError::ExpressionError(format!("expected a valid pipeline attribute, found {}", key)))
    }
  }
}

impl FromStr for GeometryYieldExpression {
  type Err = ParseError;

  fn from_str(s: &str) -> Result<Self, Self::Err> {
    match s {
      "yieldprim" => Ok(GeometryYieldExpression::YieldPrimitive),
      _ if s.starts_with("yield ") && s.len() > "yield ".len() => {
        let expr = &s["yield ".len() ..];
        Ok(GeometryYieldExpression::YieldFoldVertex(expr.into()))
      },
      _ => {
        Err(ParseError::ExpressionError(format!("expected yield, found {}", s)))
      }
    }
  }
}

// FIXME: move that into a specific module
#[test]
fn parse_pipeline_attribute() {
  let geo_max_vertices  = "geometry_shader_max_vertices = 3";
  let geo_max_vertices1 = "geometry_shader_max_vertices =3";
  let geo_max_vertices2 = "geometry_shader_max_vertices =";
  let geo_max_vertices3 = "geometry_shader_max_vertices = ";
  let geo_invokations  = "geometry_shader_invokations = 1";
  let geo_invokations1 = "geometry_shader_invokations =1";
  let geo_invokations2 = "geometry_shader_invokations =";
  let geo_invokations3 = "geometry_shader_invokations = ";

  assert_eq!(geo_max_vertices.parse::<PipelineAttribute>(), Ok(PipelineAttribute::GeometryShaderMaxVertices(3)));
  assert_eq!(geo_max_vertices1.parse::<PipelineAttribute>(), Ok(PipelineAttribute::GeometryShaderMaxVertices(3)));
  assert!(geo_max_vertices2.parse::<PipelineAttribute>().is_err());
  assert!(geo_max_vertices3.parse::<PipelineAttribute>().is_err());
  assert_eq!(geo_invokations.parse::<PipelineAttribute>(), Ok(PipelineAttribute::GeometryShaderInvokations(1)));
  assert_eq!(geo_invokations1.parse::<PipelineAttribute>(), Ok(PipelineAttribute::GeometryShaderInvokations(1)));
  assert!(geo_invokations2.parse::<PipelineAttribute>().is_err());
  assert!(geo_invokations3.parse::<PipelineAttribute>().is_err());
}

// FIXME: move that into a specific module
#[test]
fn parse_geometry_yield_expression() {
  let yieldprim = "yieldprim";
  let yield_1 = "yield FoldVertex(vertex[i].color)";

  assert_eq!(yieldprim.parse::<GeometryYieldExpression>(), Ok(GeometryYieldExpression::YieldPrimitive));
  assert_eq!(yield_1.parse::<GeometryYieldExpression>(), Ok(GeometryYieldExpression::YieldFoldVertex("FoldVertex(vertex[i].color)".into())));
}
<commit_msg>Simplified SSL AST. #24<commit_after>use std::collections::{HashMap, HashSet};
use std::str::FromStr;

/// A shader module.
///
/// A shader module is a container that associates some shading code to several identifiers.
struct ShaderModule {
  symbols: HashMap<Identifier, ShadingCode>
}

/// Spectra Shading Language AST.
#[derive(Clone, Debug, Eq, PartialEq)]
enum SSL {
  /// An `export list_of_identifiers_` statement.
  Export(ExportList),
  /// A `from module use list of identifiers` statement.
  FromUse(ImportList),
  /// A `pipeline { list_of_pipeline_attributes }` statement.
  Pipeline(PipelineStatement),
  /// A yield statement, valid in geometry shaders.
  Yield(GeometryYieldExpression),
}

/// A module.
type Module = String;
/// An identifier.
type Identifier = String;
/// Some opaque shading code.
type ShadingCode = String;
/// An expression.
type Expression = String;

/// An export non-empty list.
#[derive(Clone, Debug, Eq, PartialEq)]
struct ExportList {
  list: HashSet<Identifier>
}

/// An import non-empty list.
#[derive(Clone, Debug, Eq, PartialEq)]
struct ImportList {
  module: Module,
  list: HashSet<Identifier>
}

/// A pipeline statement.
#[derive(Clone, Debug, Eq, PartialEq)]
struct PipelineStatement {
  attributes: Vec<PipelineAttribute>
}

/// Attributes that can be set in a pipeline.
#[derive(Clone, Debug, Eq, PartialEq)]
enum PipelineAttribute {
  /// Maximum vertices that the geometry shader can output.
  GeometryShaderMaxVertices(u32),
  /// Number of times the geometry shader must be invoked.
  GeometryShaderInvokations(u32)
}

/// Expressions that can be yielded in a geometry shader.
#[derive(Clone, Debug, Eq, PartialEq)]
enum GeometryYieldExpression {
  /// Yield a primitive.
  YieldPrimitive,
  /// Yield a primitive’s vertex (fold vertex).
  YieldFoldVertex(Expression)
}

/// Error that can occur when parsing SSL code.
#[derive(Clone, Debug, Eq, PartialEq)]
enum ParseError {
  ExpressionError(String)
}

impl FromStr for PipelineAttribute {
  type Err = ParseError;

  fn from_str(s: &str) -> Result<Self, Self::Err> {
    let equal_sign_idx = s.find('=').ok_or(ParseError::ExpressionError("cannot find =".into()))?;
    let (key, value) = s.split_at(equal_sign_idx);

    if value.len() <= 1 {
      return Err(ParseError::ExpressionError("no value".into()));
    }

    match key.trim() {
      "geometry_shader_max_vertices" => {
        let value = (&value[1..]).trim();
        let max_vertices = value.parse().map_err(|_| ParseError::ExpressionError(format!("unable to parse geometry_shader_max_vertices, found {}", value)))?;
        Ok(PipelineAttribute::GeometryShaderMaxVertices(max_vertices))
      },
      "geometry_shader_invokations" => {
        let value = (&value[1..]).trim();
        let invokations = value.parse().map_err(|_| ParseError::ExpressionError(format!("unable to parse geometry_shader_invokation, found {}", value)))?;
        Ok(PipelineAttribute::GeometryShaderInvokations(invokations))
      },
      _ => Err(ParseError::ExpressionError(format!("expected a valid pipeline attribute, found {}", key)))
    }
  }
}

impl FromStr for GeometryYieldExpression {
  type Err = ParseError;

  fn from_str(s: &str) -> Result<Self, Self::Err> {
    match s {
      "yieldprim" => Ok(GeometryYieldExpression::YieldPrimitive),
      _ if s.starts_with("yield ") && s.len() > "yield ".len() => {
        let expr = &s["yield ".len() ..];
        Ok(GeometryYieldExpression::YieldFoldVertex(expr.into()))
      },
      _ => {
        Err(ParseError::ExpressionError(format!("expected yield, found {}", s)))
      }
    }
  }
}

// FIXME: move that into a specific module
#[test]
fn parse_pipeline_attribute() {
  let geo_max_vertices  = "geometry_shader_max_vertices = 3";
  let geo_max_vertices1 = "geometry_shader_max_vertices =3";
  let geo_max_vertices2 = "geometry_shader_max_vertices =";
  let geo_max_vertices3 = "geometry_shader_max_vertices = ";
  let geo_invokations  = "geometry_shader_invokations = 1";
  let geo_invokations1 = "geometry_shader_invokations =1";
  let geo_invokations2 = "geometry_shader_invokations =";
  let geo_invokations3 = "geometry_shader_invokations = ";

  assert_eq!(geo_max_vertices.parse::<PipelineAttribute>(), Ok(PipelineAttribute::GeometryShaderMaxVertices(3)));
  assert_eq!(geo_max_vertices1.parse::<PipelineAttribute>(), Ok(PipelineAttribute::GeometryShaderMaxVertices(3)));
  assert!(geo_max_vertices2.parse::<PipelineAttribute>().is_err());
  assert!(geo_max_vertices3.parse::<PipelineAttribute>().is_err());
  assert_eq!(geo_invokations.parse::<PipelineAttribute>(), Ok(PipelineAttribute::GeometryShaderInvokations(1)));
  assert_eq!(geo_invokations1.parse::<PipelineAttribute>(), Ok(PipelineAttribute::GeometryShaderInvokations(1)));
  assert!(geo_invokations2.parse::<PipelineAttribute>().is_err());
  assert!(geo_invokations3.parse::<PipelineAttribute>().is_err());
}

// FIXME: move that into a specific module
#[test]
fn parse_geometry_yield_expression() {
  let yieldprim = "yieldprim";
  let yield_1 = "yield FoldVertex(vertex[i].color)";

  assert_eq!(yieldprim.parse::<GeometryYieldExpression>(), Ok(GeometryYieldExpression::YieldPrimitive));
  assert_eq!(yield_1.parse::<GeometryYieldExpression>(), Ok(GeometryYieldExpression::YieldFoldVertex("FoldVertex(vertex[i].color)".into())));
}
<|endoftext|>


<commit_before>// Aligned to two bytes
const DATA: [u16; 2] = [u16::from_ne_bytes([0x01, 0x23]), u16::from_ne_bytes([0x45, 0x67])];

const fn unaligned_ptr() -> *const u16 {
    // Since DATA.as_ptr() is aligned to two bytes, adding 1 byte to that produces an unaligned *const u16
    unsafe { (DATA.as_ptr() as *const u8).add(1) as *const u16 }
}

#[test]
fn read() {
    use core::ptr;

    const FOO: i32 = unsafe { ptr::read(&42 as *const i32) };
    assert_eq!(FOO, 42);

    const ALIGNED: i32 = unsafe { ptr::read_unaligned(&42 as *const i32) };
    assert_eq!(ALIGNED, 42);

    const UNALIGNED_PTR: *const u16 = unaligned_ptr();

    const UNALIGNED: u16 = unsafe { ptr::read_unaligned(UNALIGNED_PTR) };
    assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
}

#[test]
fn const_ptr_read() {
    const FOO: i32 = unsafe { (&42 as *const i32).read() };
    assert_eq!(FOO, 42);

    const ALIGNED: i32 = unsafe { (&42 as *const i32).read_unaligned() };
    assert_eq!(ALIGNED, 42);

    const UNALIGNED_PTR: *const u16 = unaligned_ptr();

    const UNALIGNED: u16 = unsafe { UNALIGNED_PTR.read_unaligned() };
    assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
}

#[test]
fn mut_ptr_read() {
    const FOO: i32 = unsafe { (&42 as *const i32 as *mut i32).read() };
    assert_eq!(FOO, 42);

    const ALIGNED: i32 = unsafe { (&42 as *const i32 as *mut i32).read_unaligned() };
    assert_eq!(ALIGNED, 42);

    const UNALIGNED_PTR: *mut u16 = unaligned_ptr() as *mut u16;

    const UNALIGNED: u16 = unsafe { UNALIGNED_PTR.read_unaligned() };
    assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
}
<commit_msg>Revert "Revert tests added by PR 81167."<commit_after>// Aligned to two bytes
const DATA: [u16; 2] = [u16::from_ne_bytes([0x01, 0x23]), u16::from_ne_bytes([0x45, 0x67])];

const fn unaligned_ptr() -> *const u16 {
    // Since DATA.as_ptr() is aligned to two bytes, adding 1 byte to that produces an unaligned *const u16
    unsafe { (DATA.as_ptr() as *const u8).add(1) as *const u16 }
}

#[test]
fn read() {
    use core::ptr;

    const FOO: i32 = unsafe { ptr::read(&42 as *const i32) };
    assert_eq!(FOO, 42);

    const ALIGNED: i32 = unsafe { ptr::read_unaligned(&42 as *const i32) };
    assert_eq!(ALIGNED, 42);

    const UNALIGNED_PTR: *const u16 = unaligned_ptr();

    const UNALIGNED: u16 = unsafe { ptr::read_unaligned(UNALIGNED_PTR) };
    assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
}

#[test]
fn const_ptr_read() {
    const FOO: i32 = unsafe { (&42 as *const i32).read() };
    assert_eq!(FOO, 42);

    const ALIGNED: i32 = unsafe { (&42 as *const i32).read_unaligned() };
    assert_eq!(ALIGNED, 42);

    const UNALIGNED_PTR: *const u16 = unaligned_ptr();

    const UNALIGNED: u16 = unsafe { UNALIGNED_PTR.read_unaligned() };
    assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
}

#[test]
fn mut_ptr_read() {
    const FOO: i32 = unsafe { (&42 as *const i32 as *mut i32).read() };
    assert_eq!(FOO, 42);

    const ALIGNED: i32 = unsafe { (&42 as *const i32 as *mut i32).read_unaligned() };
    assert_eq!(ALIGNED, 42);

    const UNALIGNED_PTR: *mut u16 = unaligned_ptr() as *mut u16;

    const UNALIGNED: u16 = unsafe { UNALIGNED_PTR.read_unaligned() };
    assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
}

#[test]
fn write() {
    use core::ptr;

    const fn write_aligned() -> i32 {
        let mut res = 0;
        unsafe {
            ptr::write(&mut res as *mut _, 42);
        }
        res
    }
    const ALIGNED: i32 = write_aligned();
    assert_eq!(ALIGNED, 42);

    const fn write_unaligned() -> [u16; 2] {
        let mut two_aligned = [0u16; 2];
        unsafe {
            let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
            ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45]));
        }
        two_aligned
    }
    const UNALIGNED: [u16; 2] = write_unaligned();
    assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]);
}

#[test]
fn mut_ptr_write() {
    const fn aligned() -> i32 {
        let mut res = 0;
        unsafe {
            (&mut res as *mut i32).write(42);
        }
        res
    }
    const ALIGNED: i32 = aligned();
    assert_eq!(ALIGNED, 42);

    const fn write_unaligned() -> [u16; 2] {
        let mut two_aligned = [0u16; 2];
        unsafe {
            let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
            unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45]));
        }
        two_aligned
    }
    const UNALIGNED: [u16; 2] = write_unaligned();
    assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]);
}
<|endoftext|>


<commit_before>// Copyright:: Copyright (c) 2015-2016 The Habitat Maintainers
//
// The terms of the Evaluation Agreement (Habitat) between Chef Software Inc.
// and the party accessing this file ("Licensee") apply to Licensee's use of
// the Software until such time that the Software is made available under an
// open source license such as the Apache 2.0 License.

/// Default Depot URL
pub const DEFAULT_DEPOT_URL: &'static str = "http://willem.habitat.sh:9632";

/// Default Depot URL environment variable
pub const DEPOT_URL_ENVVAR: &'static str = "HAB_DEPOT_URL";
<commit_msg>prefix API endpoints with /v1<commit_after>// Copyright:: Copyright (c) 2015-2016 The Habitat Maintainers
//
// The terms of the Evaluation Agreement (Habitat) between Chef Software Inc.
// and the party accessing this file ("Licensee") apply to Licensee's use of
// the Software until such time that the Software is made available under an
// open source license such as the Apache 2.0 License.

/// Default Depot URL
pub const DEFAULT_DEPOT_URL: &'static str = "http://willem.habitat.sh:9636/v1/depot";

/// Default Depot URL environment variable
pub const DEPOT_URL_ENVVAR: &'static str = "HAB_DEPOT_URL";
<|endoftext|>


<commit_before>#![ crate_type = "lib" ]
#![ feature(globs) ]
#![ allow(non_snake_case) ]

extern crate libc;
extern crate core;
extern crate sync;

use libusb::*;
use libusb::libusb_transfer_status::*;
use libusb::libusb_transfer_type::*;
use libc::{c_int, c_void, size_t, malloc, free};
use std::intrinsics;
use std::slice;
use std::result::Result;
use std::comm::{Receiver, Sender};
use std::mem::transmute;
use std::mem::size_of;
use std::vec::Vec;
use std::cell::UnsafeCell;

use sync::Arc;
use std::sync::atomic::{SeqCst, AtomicInt};
use std::task;

pub mod libusb;

pub struct ContextData {
	ctx: *mut libusb_context,
	open_device_count: AtomicInt
}

impl Drop for ContextData {
	fn drop(&mut self) {
		unsafe {
			assert!(self.open_device_count.load(SeqCst) == 0);
			// TODO: make sure backend thread is dead if the last device just closed
			libusb_exit(self.ctx);
		}
	}
}

pub struct Context {
	bx: Arc<UnsafeCell<ContextData>>
}

impl Context {
	pub fn new() -> Context {
		unsafe{
			let mut ctx: *mut libusb_context = intrinsics::init();
			let r = libusb_init(&mut ctx);
			assert!(r == 0);

			Context{
				bx: Arc::new(UnsafeCell::new(ContextData{
					ctx: ctx,
					open_device_count: AtomicInt::new(0)
				}))
			}
		}
	}

	pub fn ptr(&self) -> *mut libusb_context {
		unsafe{
			(*self.bx.get()).ctx
		}
	}

	pub fn set_debug(&self, level: int) {
		unsafe{
			libusb_set_debug(self.ptr(), level as c_int);
		}
	}

	pub fn list_devices(&self) -> Vec<Device> {
		unsafe{
			let mut list: *mut *mut libusb_device = intrinsics::init();
			let num_devices = libusb_get_device_list(self.ptr(), &mut list);
			let r = slice::raw::mut_buf_as_slice(list, num_devices as uint, |l|{
				l.iter().map(|i| Device{dev: *i, ctx: (*self).clone()}).collect()
			});

			libusb_free_device_list(list, 0);
			r
		}
	}

	pub fn find_by_vid_pid(&self, vid: uint, pid: uint) -> Option<Device> {
		self.list_devices().into_iter().find(|d| {
			let desc = d.descriptor();
			desc.idVendor as uint == vid && desc.idProduct as uint == pid
		})
	}

	fn device_opened(&self) {
		let count = unsafe { &mut (*self.bx.get()).open_device_count };
		let old_count = count.fetch_add(1, SeqCst);

		if old_count == 0 {
			let bx = self.bx.clone();

			fn threadfn(tbx: &Arc<UnsafeCell<ContextData>>) {
				unsafe {
					let ctx = (*tbx.get()).ctx;
					let count = &(*tbx.get()).open_device_count;

					while count.load(SeqCst) > 0 {
						libusb_handle_events(ctx);
					}
				}
			}

			task::spawn(proc() {threadfn(&bx);});
		}
	}

	fn device_closed(&self) {
		let count = unsafe { &mut (*self.bx.get()).open_device_count };
		count.fetch_sub(1, SeqCst);
	}
}

extern fn rust_usb_callback(transfer: *mut libusb_transfer) {
	unsafe {
		let chan: Box<Sender<()>> = transmute((*transfer).user_data);
		chan.send(());
	}
}

struct TH {
	t: *mut libusb_transfer,
	c: Sender<*mut libusb_transfer>,
}

impl Drop for TH{
	fn drop(&mut self) {
		unsafe {
			free((*self.t).buffer as *mut c_void);
			libusb_free_transfer(self.t);
		}
	}
}

extern fn rust_usb_stream_callback(transfer: *mut libusb_transfer) {
	unsafe {
		let chan: &Sender<*mut libusb_transfer> = transmute((*transfer).user_data);
		chan.send(transfer);
	}
}

impl Clone for Context{
	fn clone(&self) -> Context{
		Context{bx: self.bx.clone()}
	}
}

pub struct Device {
	dev: *mut libusb_device,
	ctx: Context
}

impl Device {
	pub fn descriptor(&self) -> Box<libusb_device_descriptor> {
		unsafe{
			let mut d: Box<libusb_device_descriptor> = box intrinsics::uninit();
			libusb_get_device_descriptor(self.dev, &mut *d as *mut libusb_device_descriptor);
			d
		}
	}

	pub fn bus(&self) -> int {
		unsafe {
			libusb_get_bus_number(self.dev) as int
		}
	}

	pub fn address(&self) -> int {
		unsafe {
			libusb_get_device_address(self.dev) as int
		}
	}

	pub fn open(&self) -> Result<DeviceHandle, int> {
		unsafe {
			let mut handle: *mut libusb_device_handle = intrinsics::uninit();
			let r = libusb_open(self.dev, &mut handle);
			if r == 0 {
				self.ctx.device_opened();
				Ok(DeviceHandle {
					bx: Arc::new(UnsafeCell::new(DeviceHandleData {
						dev: handle,
						ctx: self.ctx.clone()
					}))
				})
			}else{
				Err(r as int)
			}
		}
	}
}

impl Drop for Device {
	fn drop(&mut self) {
		unsafe {
			libusb_unref_device(self.dev);
		}
	}
}

impl Clone for Device {
	fn clone(&self) -> Device {
		unsafe {
			libusb_ref_device(self.dev);
		}
		Device{dev: self.dev, ctx: self.ctx.clone()}
	}
}

struct DeviceHandleData{
	dev: *mut libusb_device_handle,
	ctx: Context
}

impl Drop for DeviceHandleData {
	fn drop(&mut self) {
		unsafe {
			self.ctx.device_closed();
			libusb_close(self.dev);
		}
	}
}

pub struct DeviceHandle {
	bx: Arc<UnsafeCell<DeviceHandleData>>
}

impl DeviceHandle {
	pub fn ptr(&self) -> *mut libusb_device_handle {
		unsafe {
			(*self.bx.get()).dev
		}
	}

	pub fn claim_interface(&self,
		iface_num: uint) {
		unsafe {
		libusb_claim_interface(self.ptr(), iface_num as c_int);
		}
	}

	pub unsafe fn submit_transfer_sync(&self,
		endpoint: u8,
		transfer_type: libusb_transfer_type,
		length: uint,
		buffer: *mut u8) -> (libusb_transfer_status, uint) {

		let (chan, port) : (Sender<()>, Receiver<()>) = channel();

		let t = libusb_alloc_transfer(0);
		(*t).dev_handle = self.ptr();
		(*t).endpoint = endpoint;
		(*t).transfer_type = transfer_type as u8;
		(*t).timeout = 0;
		(*t).length = length as c_int;
		(*t).callback = rust_usb_callback;
		(*t).user_data = transmute(box chan);
		(*t).buffer = buffer;

		libusb_submit_transfer(t);
		port.recv();
		let r = ((*t).get_status(), (*t).actual_length as uint);
		libusb_free_transfer(t);
		return r;
	}

	pub fn read(&self,
			endpoint: u8,
			transfer_type: libusb_transfer_type,
			size: uint
			) -> Result<Vec<u8>, libusb_transfer_status> {
		let mut buf: Vec<u8> = Vec::from_elem(size, 0u8);
		unsafe {
			let ptr = buf.as_mut_ptr();
			let (status, actual_length) = self.submit_transfer_sync(
				endpoint, transfer_type, size, ptr);

			if status == LIBUSB_TRANSFER_COMPLETED {
				buf.truncate(actual_length);
				Ok(buf)
			} else {
				Err(status)
			}
		}
	}

	pub fn write(&self, endpoint: u8, transfer_type: libusb_transfer_type, buf: &[u8]) -> Result<(), libusb_transfer_status> {
		unsafe {
			let ptr = buf.as_ptr() as *mut u8;

			let (status, _) = self.submit_transfer_sync(
				endpoint, transfer_type, buf.len(), ptr);

			if status == LIBUSB_TRANSFER_COMPLETED {
				Ok(())
			} else {
				Err(status)
			}
		}
	}

	pub fn ctrl_read(&self, bmRequestType: u8, bRequest: u8,
		wValue:u16, wIndex: u16, length: uint) -> Result<Vec<u8>, libusb_transfer_status> {

		let setup_length = size_of::<libusb_control_setup>();
		let total_length = setup_length + length as uint;
		let mut buf: Vec<u8> = Vec::from_elem(total_length, 0u8);

		unsafe{
			let ptr = fill_setup_buf(buf.as_mut_slice(), bmRequestType, bRequest, wValue, wIndex, length);

			let (status, actual_length) = self.submit_transfer_sync(
				0, LIBUSB_TRANSFER_TYPE_CONTROL, total_length, ptr);

			if status == LIBUSB_TRANSFER_COMPLETED {
				Ok(buf.slice(setup_length, setup_length+actual_length).to_vec())
			} else {
				Err(status)
			}
		}
	}

	pub fn ctrl_write(&self, bmRequestType: u8, bRequest: u8,
		wValue:u16, wIndex: u16, buf: &[u8]) -> Result<(), libusb_transfer_status> {
		unsafe {
			let mut setup_buf = Vec::from_elem(size_of::<libusb_control_setup>(), 0u8);
			fill_setup_buf(setup_buf.as_mut_slice(), bmRequestType, bRequest, wValue, wIndex, buf.len());
			setup_buf.push_all(buf);
			self.write(0, LIBUSB_TRANSFER_TYPE_CONTROL, setup_buf.slice_from(0))
		}
	}

	unsafe fn stream_transfers(&self, endpoint: u8,
			transfer_type: libusb_transfer_type, size: uint,
			num_transfers: uint) -> (Receiver<*mut libusb_transfer>, Vec<TH>) {

		let (chan, port) = channel();

		let transfers = Vec::from_fn(num_transfers, |_| { TH {
			t: libusb_alloc_transfer(0),
			c: chan.clone(),
		}});

		for th in transfers.iter() {
			(*th.t).dev_handle = self.ptr();
			(*th.t).endpoint = endpoint;
			(*th.t).transfer_type = transfer_type as u8;
			(*th.t).timeout = 0;
			(*th.t).length = size as i32;
			(*th.t).callback = rust_usb_stream_callback;
			(*th.t).buffer = malloc(size as size_t) as *mut u8;
			(*th.t).user_data = transmute(&th.c);
		}

		return (port, transfers);
	}

	pub fn read_stream(&self, endpoint: u8,
			transfer_type: libusb_transfer_type,
			size: uint, mut num_transfers: uint, cb: |Result<&[u8], libusb_transfer_status>| -> bool) {

		unsafe {
			let mut running = true;
			let (port, transfers) = self.stream_transfers(
				endpoint, transfer_type, size, num_transfers);

			for th in transfers.iter() {
				libusb_submit_transfer(th.t);
			}

			while num_transfers > 0 {
				let transfer: *mut libusb_transfer = port.recv();

				if (*transfer).get_status() == LIBUSB_TRANSFER_COMPLETED {
					slice::raw::buf_as_slice((*transfer).buffer as *const u8, size, |b| {
						running &= cb(Ok(b))
					});
				} else {
					running = false;
					running &= cb(Err((*transfer).get_status()));
				}

				if running {
					let r = libusb_submit_transfer(transfer);
					assert!(r == 0);
				} else {
					num_transfers -= 1;
				}
			}
		}
	}

	pub fn write_stream(&self, endpoint: u8,
			transfer_type: libusb_transfer_type,
			size: uint, num_transfers: uint, cb: |Result<(&mut[u8]), libusb_transfer_status>| -> bool) {

		unsafe {
			let mut running = true;
			let mut running_transfers = 0u;
			let (port, transfers) = self.stream_transfers(
				endpoint, transfer_type, size, num_transfers);

			for th in transfers.iter() {
				slice::raw::mut_buf_as_slice((*th.t).buffer, size, |b| {
					running &= cb(Ok(b));
				});
				if running {
					libusb_submit_transfer(th.t);
					running_transfers += 1;
				} else {
					break;
				}
			}

			while running_transfers > 0 {
				let transfer: *mut libusb_transfer = port.recv();

				if (*transfer).get_status() == LIBUSB_TRANSFER_COMPLETED {
					slice::raw::mut_buf_as_slice((*transfer).buffer, size, |b| {
						running &= cb(Ok(b))
					});
				} else {
					running = false;
					running &= cb(Err((*transfer).get_status()));
				}

				if running {
					let r = libusb_submit_transfer(transfer);
					assert!(r == 0);
				} else {
					running_transfers -= 1;
				}
			}
		}
	}
}

unsafe fn fill_setup_buf(buf: &mut [u8], bmRequestType: u8,
	bRequest: u8, wValue:u16, wIndex: u16, length: uint) -> *mut u8 {
	let ptr = buf.as_mut_ptr();
	let setup = ptr as *mut libusb_control_setup;

	// TODO: these are always little-endian
	(*setup).bmRequestType = bmRequestType;
	(*setup).bRequest = bRequest;
	(*setup).wValue = wValue;
	(*setup).wIndex = wIndex;
	(*setup).wLength = length as u16;

	return ptr;
}

impl Clone for DeviceHandle {
	fn clone(&self) -> DeviceHandle {
		DeviceHandle{bx: self.bx.clone()}
	}
}
<commit_msg>rust: libsync moved back into std<commit_after>#![ crate_type = "lib" ]
#![ feature(globs) ]
#![ allow(non_snake_case) ]

extern crate libc;

use libusb::*;
use libusb::libusb_transfer_status::*;
use libusb::libusb_transfer_type::*;
use libc::{c_int, c_void, size_t, malloc, free};
use std::intrinsics;
use std::slice;
use std::result::Result;
use std::comm::{Receiver, Sender};
use std::mem::transmute;
use std::mem::size_of;
use std::vec::Vec;
use std::cell::UnsafeCell;

use std::sync::Arc;
use std::sync::atomic::{SeqCst, AtomicInt};
use std::task;

pub mod libusb;

pub struct ContextData {
	ctx: *mut libusb_context,
	open_device_count: AtomicInt
}

impl Drop for ContextData {
	fn drop(&mut self) {
		unsafe {
			assert!(self.open_device_count.load(SeqCst) == 0);
			// TODO: make sure backend thread is dead if the last device just closed
			libusb_exit(self.ctx);
		}
	}
}

pub struct Context {
	bx: Arc<UnsafeCell<ContextData>>
}

impl Context {
	pub fn new() -> Context {
		unsafe{
			let mut ctx: *mut libusb_context = intrinsics::init();
			let r = libusb_init(&mut ctx);
			assert!(r == 0);

			Context{
				bx: Arc::new(UnsafeCell::new(ContextData{
					ctx: ctx,
					open_device_count: AtomicInt::new(0)
				}))
			}
		}
	}

	pub fn ptr(&self) -> *mut libusb_context {
		unsafe{
			(*self.bx.get()).ctx
		}
	}

	pub fn set_debug(&self, level: int) {
		unsafe{
			libusb_set_debug(self.ptr(), level as c_int);
		}
	}

	pub fn list_devices(&self) -> Vec<Device> {
		unsafe{
			let mut list: *mut *mut libusb_device = intrinsics::init();
			let num_devices = libusb_get_device_list(self.ptr(), &mut list);
			let r = slice::raw::mut_buf_as_slice(list, num_devices as uint, |l|{
				l.iter().map(|i| Device{dev: *i, ctx: (*self).clone()}).collect()
			});

			libusb_free_device_list(list, 0);
			r
		}
	}

	pub fn find_by_vid_pid(&self, vid: uint, pid: uint) -> Option<Device> {
		self.list_devices().into_iter().find(|d| {
			let desc = d.descriptor();
			desc.idVendor as uint == vid && desc.idProduct as uint == pid
		})
	}

	fn device_opened(&self) {
		let count = unsafe { &mut (*self.bx.get()).open_device_count };
		let old_count = count.fetch_add(1, SeqCst);

		if old_count == 0 {
			let bx = self.bx.clone();

			fn threadfn(tbx: &Arc<UnsafeCell<ContextData>>) {
				unsafe {
					let ctx = (*tbx.get()).ctx;
					let count = &(*tbx.get()).open_device_count;

					while count.load(SeqCst) > 0 {
						libusb_handle_events(ctx);
					}
				}
			}

			task::spawn(proc() {threadfn(&bx);});
		}
	}

	fn device_closed(&self) {
		let count = unsafe { &mut (*self.bx.get()).open_device_count };
		count.fetch_sub(1, SeqCst);
	}
}

extern fn rust_usb_callback(transfer: *mut libusb_transfer) {
	unsafe {
		let chan: Box<Sender<()>> = transmute((*transfer).user_data);
		chan.send(());
	}
}

struct TH {
	t: *mut libusb_transfer,
	c: Sender<*mut libusb_transfer>,
}

impl Drop for TH{
	fn drop(&mut self) {
		unsafe {
			free((*self.t).buffer as *mut c_void);
			libusb_free_transfer(self.t);
		}
	}
}

extern fn rust_usb_stream_callback(transfer: *mut libusb_transfer) {
	unsafe {
		let chan: &Sender<*mut libusb_transfer> = transmute((*transfer).user_data);
		chan.send(transfer);
	}
}

impl Clone for Context{
	fn clone(&self) -> Context{
		Context{bx: self.bx.clone()}
	}
}

pub struct Device {
	dev: *mut libusb_device,
	ctx: Context
}

impl Device {
	pub fn descriptor(&self) -> Box<libusb_device_descriptor> {
		unsafe{
			let mut d: Box<libusb_device_descriptor> = box intrinsics::uninit();
			libusb_get_device_descriptor(self.dev, &mut *d as *mut libusb_device_descriptor);
			d
		}
	}

	pub fn bus(&self) -> int {
		unsafe {
			libusb_get_bus_number(self.dev) as int
		}
	}

	pub fn address(&self) -> int {
		unsafe {
			libusb_get_device_address(self.dev) as int
		}
	}

	pub fn open(&self) -> Result<DeviceHandle, int> {
		unsafe {
			let mut handle: *mut libusb_device_handle = intrinsics::uninit();
			let r = libusb_open(self.dev, &mut handle);
			if r == 0 {
				self.ctx.device_opened();
				Ok(DeviceHandle {
					bx: Arc::new(UnsafeCell::new(DeviceHandleData {
						dev: handle,
						ctx: self.ctx.clone()
					}))
				})
			}else{
				Err(r as int)
			}
		}
	}
}

impl Drop for Device {
	fn drop(&mut self) {
		unsafe {
			libusb_unref_device(self.dev);
		}
	}
}

impl Clone for Device {
	fn clone(&self) -> Device {
		unsafe {
			libusb_ref_device(self.dev);
		}
		Device{dev: self.dev, ctx: self.ctx.clone()}
	}
}

struct DeviceHandleData{
	dev: *mut libusb_device_handle,
	ctx: Context
}

impl Drop for DeviceHandleData {
	fn drop(&mut self) {
		unsafe {
			self.ctx.device_closed();
			libusb_close(self.dev);
		}
	}
}

pub struct DeviceHandle {
	bx: Arc<UnsafeCell<DeviceHandleData>>
}

impl DeviceHandle {
	pub fn ptr(&self) -> *mut libusb_device_handle {
		unsafe {
			(*self.bx.get()).dev
		}
	}

	pub fn claim_interface(&self,
		iface_num: uint) {
		unsafe {
		libusb_claim_interface(self.ptr(), iface_num as c_int);
		}
	}

	pub unsafe fn submit_transfer_sync(&self,
		endpoint: u8,
		transfer_type: libusb_transfer_type,
		length: uint,
		buffer: *mut u8) -> (libusb_transfer_status, uint) {

		let (chan, port) : (Sender<()>, Receiver<()>) = channel();

		let t = libusb_alloc_transfer(0);
		(*t).dev_handle = self.ptr();
		(*t).endpoint = endpoint;
		(*t).transfer_type = transfer_type as u8;
		(*t).timeout = 0;
		(*t).length = length as c_int;
		(*t).callback = rust_usb_callback;
		(*t).user_data = transmute(box chan);
		(*t).buffer = buffer;

		libusb_submit_transfer(t);
		port.recv();
		let r = ((*t).get_status(), (*t).actual_length as uint);
		libusb_free_transfer(t);
		return r;
	}

	pub fn read(&self,
			endpoint: u8,
			transfer_type: libusb_transfer_type,
			size: uint
			) -> Result<Vec<u8>, libusb_transfer_status> {
		let mut buf: Vec<u8> = Vec::from_elem(size, 0u8);
		unsafe {
			let ptr = buf.as_mut_ptr();
			let (status, actual_length) = self.submit_transfer_sync(
				endpoint, transfer_type, size, ptr);

			if status == LIBUSB_TRANSFER_COMPLETED {
				buf.truncate(actual_length);
				Ok(buf)
			} else {
				Err(status)
			}
		}
	}

	pub fn write(&self, endpoint: u8, transfer_type: libusb_transfer_type, buf: &[u8]) -> Result<(), libusb_transfer_status> {
		unsafe {
			let ptr = buf.as_ptr() as *mut u8;

			let (status, _) = self.submit_transfer_sync(
				endpoint, transfer_type, buf.len(), ptr);

			if status == LIBUSB_TRANSFER_COMPLETED {
				Ok(())
			} else {
				Err(status)
			}
		}
	}

	pub fn ctrl_read(&self, bmRequestType: u8, bRequest: u8,
		wValue:u16, wIndex: u16, length: uint) -> Result<Vec<u8>, libusb_transfer_status> {

		let setup_length = size_of::<libusb_control_setup>();
		let total_length = setup_length + length as uint;
		let mut buf: Vec<u8> = Vec::from_elem(total_length, 0u8);

		unsafe{
			let ptr = fill_setup_buf(buf.as_mut_slice(), bmRequestType, bRequest, wValue, wIndex, length);

			let (status, actual_length) = self.submit_transfer_sync(
				0, LIBUSB_TRANSFER_TYPE_CONTROL, total_length, ptr);

			if status == LIBUSB_TRANSFER_COMPLETED {
				Ok(buf.slice(setup_length, setup_length+actual_length).to_vec())
			} else {
				Err(status)
			}
		}
	}

	pub fn ctrl_write(&self, bmRequestType: u8, bRequest: u8,
		wValue:u16, wIndex: u16, buf: &[u8]) -> Result<(), libusb_transfer_status> {
		unsafe {
			let mut setup_buf = Vec::from_elem(size_of::<libusb_control_setup>(), 0u8);
			fill_setup_buf(setup_buf.as_mut_slice(), bmRequestType, bRequest, wValue, wIndex, buf.len());
			setup_buf.push_all(buf);
			self.write(0, LIBUSB_TRANSFER_TYPE_CONTROL, setup_buf.slice_from(0))
		}
	}

	unsafe fn stream_transfers(&self, endpoint: u8,
			transfer_type: libusb_transfer_type, size: uint,
			num_transfers: uint) -> (Receiver<*mut libusb_transfer>, Vec<TH>) {

		let (chan, port) = channel();

		let transfers = Vec::from_fn(num_transfers, |_| { TH {
			t: libusb_alloc_transfer(0),
			c: chan.clone(),
		}});

		for th in transfers.iter() {
			(*th.t).dev_handle = self.ptr();
			(*th.t).endpoint = endpoint;
			(*th.t).transfer_type = transfer_type as u8;
			(*th.t).timeout = 0;
			(*th.t).length = size as i32;
			(*th.t).callback = rust_usb_stream_callback;
			(*th.t).buffer = malloc(size as size_t) as *mut u8;
			(*th.t).user_data = transmute(&th.c);
		}

		return (port, transfers);
	}

	pub fn read_stream(&self, endpoint: u8,
			transfer_type: libusb_transfer_type,
			size: uint, mut num_transfers: uint, cb: |Result<&[u8], libusb_transfer_status>| -> bool) {

		unsafe {
			let mut running = true;
			let (port, transfers) = self.stream_transfers(
				endpoint, transfer_type, size, num_transfers);

			for th in transfers.iter() {
				libusb_submit_transfer(th.t);
			}

			while num_transfers > 0 {
				let transfer: *mut libusb_transfer = port.recv();

				if (*transfer).get_status() == LIBUSB_TRANSFER_COMPLETED {
					slice::raw::buf_as_slice((*transfer).buffer as *const u8, size, |b| {
						running &= cb(Ok(b))
					});
				} else {
					running = false;
					running &= cb(Err((*transfer).get_status()));
				}

				if running {
					let r = libusb_submit_transfer(transfer);
					assert!(r == 0);
				} else {
					num_transfers -= 1;
				}
			}
		}
	}

	pub fn write_stream(&self, endpoint: u8,
			transfer_type: libusb_transfer_type,
			size: uint, num_transfers: uint, cb: |Result<(&mut[u8]), libusb_transfer_status>| -> bool) {

		unsafe {
			let mut running = true;
			let mut running_transfers = 0u;
			let (port, transfers) = self.stream_transfers(
				endpoint, transfer_type, size, num_transfers);

			for th in transfers.iter() {
				slice::raw::mut_buf_as_slice((*th.t).buffer, size, |b| {
					running &= cb(Ok(b));
				});
				if running {
					libusb_submit_transfer(th.t);
					running_transfers += 1;
				} else {
					break;
				}
			}

			while running_transfers > 0 {
				let transfer: *mut libusb_transfer = port.recv();

				if (*transfer).get_status() == LIBUSB_TRANSFER_COMPLETED {
					slice::raw::mut_buf_as_slice((*transfer).buffer, size, |b| {
						running &= cb(Ok(b))
					});
				} else {
					running = false;
					running &= cb(Err((*transfer).get_status()));
				}

				if running {
					let r = libusb_submit_transfer(transfer);
					assert!(r == 0);
				} else {
					running_transfers -= 1;
				}
			}
		}
	}
}

unsafe fn fill_setup_buf(buf: &mut [u8], bmRequestType: u8,
	bRequest: u8, wValue:u16, wIndex: u16, length: uint) -> *mut u8 {
	let ptr = buf.as_mut_ptr();
	let setup = ptr as *mut libusb_control_setup;

	// TODO: these are always little-endian
	(*setup).bmRequestType = bmRequestType;
	(*setup).bRequest = bRequest;
	(*setup).wValue = wValue;
	(*setup).wIndex = wIndex;
	(*setup).wLength = length as u16;

	return ptr;
}

impl Clone for DeviceHandle {
	fn clone(&self) -> DeviceHandle {
		DeviceHandle{bx: self.bx.clone()}
	}
}
<|endoftext|>


<commit_before>use std::iter;
use std::io;
use std::cmp;

use std::io::Read;
use std::io::BufRead;

use ParseResult;
use Input;
use buffer::ParseError;
use buffer::Source;
use internal::input;
use internal::State;
use internal::ParseResultModify;
use internal::InputModify;

const DEFAULT_BUFFER_SIZE: usize = 6 * 1024;

bitflags!{
    flags BufferState: u64 {
        const INCOMPLETE   = 1,
        const END_OF_INPUT = 2,
    }
}

// TODO: More general variants of the buffer
#[derive(Debug)]
pub struct Buffer<R: Read> {
    /// Source reader
    source: R,
    /// Internal buffer
    buffer: Vec<u8>,
    /// The requested amount of bytes to be available for reading from the buffer
    chunk:  usize,
    /// The number of bytes from the start of the buffer which has been consumed
    used:   usize,
    /// The number of bytes from the start of the buffer which have been populated
    size:   usize,
    /// Input state, if end has been reached
    state:  BufferState,
}

impl<R: Read> Buffer<R> {
    pub fn new(source: R) -> Self {
        Self::with_size(source, DEFAULT_BUFFER_SIZE)
    }

    pub fn with_size(source: R, bufsize: usize) -> Self {
        Self::with_size_and_chunk(source, bufsize, bufsize / 4)
    }

    /// Creates a new buffer with the given ``chunksize`` and ``bufsize``
    pub fn with_size_and_chunk(source: R, bufsize: usize, chunksize: usize) -> Self {
        assert!(bufsize > 0);
        assert!(bufsize > chunksize);

        Buffer {
            source: source,
            buffer: iter::repeat(0).take(bufsize).collect(),
            chunk:  cmp::max(chunksize, 1),
            used:   0,
            size:   0,
            state:  INCOMPLETE,
        }
    }

    /// Removes used data and moves the unused remainder to the front of self.buffer.
    fn drop_used(&mut self) {
        use std::ptr;

        assert!(self.size >= self.used);

        unsafe {
            ptr::copy(self.buffer.as_ptr().offset(self.used as isize), self.buffer.as_mut_ptr(), self.size - self.used);
        }

        self.size = self.size - self.used;
        self.used = 0;
    }

    /// Attempts to fill this buffer so it contains at least ``chunksize`` bytes.
    pub fn fill(&mut self) -> io::Result<usize> {
        let mut read = 0;

        if self.size < self.used + self.chunk {
            self.drop_used();
        }

        while self.size + read < self.chunk {
            match try!(self.source.read(&mut self.buffer[self.size + read..])) {
                0 => break,
                n => read = read + n,
            }
        }

        self.size = self.size + read;

        Ok(read)
    }

    /// Returns the number of bytes left in the buffer.
    pub fn len(&self) -> usize {
        self.size - self.used
    }

    /// Borrows the remainder of the buffer.
    pub fn buffer(&self) -> &[u8] {
        &self.buffer[self.used..self.size]
    }

    /// Resets the buffer state, keeping the current buffer contents and cursor position.
    pub fn reset(&mut self) {
        self.state = BufferState::empty();
    }
}

impl<R: Read> Read for Buffer<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if buf.len() > self.size - self.used {
            try!(self.fill());
        }

        return (&self.buffer[self.used..self.size]).read(buf).map(|n| {
            self.used = self.used + n;

            n
        });
    }
}

impl<R: Read> BufRead for Buffer<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        try!(self.fill());

        Ok(self.buffer())
    }

    fn consume(&mut self, num: usize) {
        self.used = self.used + num
    }
}

impl<'a, R: Read> Source<'a, 'a, u8> for Buffer<R> {
    fn parse<F, T, E>(&'a mut self, f: F) -> Result<T, ParseError<'a, u8, E>>
      where F: FnOnce(Input<'a, u8>) -> ParseResult<'a, u8, T, E>,
            T: 'a,
            E: 'a {
        if self.state.contains(INCOMPLETE) {
            match self.fill() {
                Ok(0)    => self.state.insert(END_OF_INPUT),
                Ok(_)    => self.state.remove(END_OF_INPUT),
                Err(err) => return Err(ParseError::IoError(err)),
            }

            self.state.remove(INCOMPLETE)
        }

        if self.state.contains(END_OF_INPUT) && self.len() == 0 {
            return Err(ParseError::EndOfInput);
        }

        let input_state = if self.state.contains(END_OF_INPUT) { input::END_OF_INPUT } else { input::DEFAULT };
        // Inline version of self.buffer() to satisfy borrowck
        let buffer      = &self.buffer[self.used..self.size];

        match f(input::new(input_state, buffer)).internal() {
            State::Data(remainder, data) => {
                // TODO: Do something neater with the remainder
                self.used += buffer.len() - remainder.buffer().len();

                Ok(data)
            },
            State::Error(remainder, err) => {
                // TODO: Do something neater with the remainder
                self.used += buffer.len() - remainder.len();

                Err(ParseError::ParseError(remainder, err))
            },
            State::Incomplete(n) => if self.state.contains(END_OF_INPUT) {
                // TODO: Use the number here to at least inform the next read of how much data is
                // needed.
                Err(ParseError::Incomplete(n))
            } else {
                self.state.insert(INCOMPLETE);

                Err(ParseError::Retry)
            },
        }
    }
}

#[cfg(test)]
mod test {
    use std::io;
    use {any, take};
    use {ParseError, Error, Source};

    use super::*;

    #[test]
    #[should_panic]
    fn bufsize_lt_chunksize() {
        let _ = Buffer::with_size_and_chunk(io::Cursor::new(&b"this is a test"[..]), 64, 128);
    }

    #[test]
    fn empty_buf() {
        let mut n = 0;
        let mut b = Buffer::new(io::Cursor::new(&b""[..]));

        let r = b.parse(|i| {
            n += 1;

            take(i, 1).bind(|i, _| i.ret::<_, Error<_>>(true))
        });

        assert_eq!(r, Err(ParseError::EndOfInput));
        assert_eq!(n, 0);
    }

    #[test]
    fn fill() {
        let mut n = 0; // Times it has entered the parsing function
        let mut m = 0; // Times it has managed to get past the request for data
        let mut b = Buffer::with_size(io::Cursor::new(&b"test"[..]), 1);

        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Ok(b't'));
        assert_eq!(n, 1);
        assert_eq!(m, 1);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::Retry));
        assert_eq!(n, 2);
        assert_eq!(m, 1);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Ok(b'e'));
        assert_eq!(n, 3);
        assert_eq!(m, 2);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::Retry));
        assert_eq!(n, 4);
        assert_eq!(m, 2);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Ok(b's'));
        assert_eq!(n, 5);
        assert_eq!(m, 3);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::Retry));
        assert_eq!(n, 6);
        assert_eq!(m, 3);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Ok(b't'));
        assert_eq!(n, 7);
        assert_eq!(m, 4);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::Retry));
        assert_eq!(n, 8);
        assert_eq!(m, 4);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::EndOfInput));
        assert_eq!(n, 8);
        assert_eq!(m, 4);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::EndOfInput));
        assert_eq!(n, 8);
        assert_eq!(m, 4);
    }
}
<commit_msg>Buffer: Moved out the storage logic and simplified some state management<commit_after>use std::io;

use std::io::Read;
use std::io::BufRead;

use ParseResult;
use Input;
use buffer::ParseError;
use buffer::Source;
use internal::input;
use internal::State;
use internal::ParseResultModify;
use internal::InputModify;

mod inner {
    use std::iter;
    use std::ops;

    use std::cell::Cell;

    #[derive(Debug, Eq, PartialEq)]
    pub struct Storage {
        buffer:    Vec<u8>,
        populated: usize,
        /// The number of bytes from the start of the buffer which are used.
        ///
        /// As long as used <= populated it is safe.
        used:      Cell<usize>,
    }

    impl Storage {
        pub fn new(size: usize) -> Self {
            Storage {
                buffer:    iter::repeat(0).take(size).collect(),
                populated: 0,
                used:      Cell::new(0),
            }
        }

        /// Removes used data and moves the unused remainder to the front of self.buffer.
        pub fn drop_used(&mut self) {
            use std::ptr;

            assert!(self.populated >= self.used.get());

            unsafe {
                ptr::copy(self.buffer.as_ptr().offset(self.used.get() as isize), self.buffer.as_mut_ptr(), self.populated - self.used.get());
            }

            self.populated -= self.used.get();
            self.used.set(0);
        }

        /// Attempts to fill the buffer using the closure `F`, the successful return from `F`
        /// should contain the number of bytes successfully written to the slice.
        ///
        /// # Note
        ///
        /// The returned value must *NOT* be larger than the length of the given slice.
        pub fn fill<F, E>(&mut self, f: F) -> Result<usize, E>
          where F: FnOnce(&mut [u8]) -> Result<usize, E> {
            f(&mut self.buffer[self.populated..]).map(|n| {
                self.populated += n;

                n
            })
        }

        /// Consumes the given amount of bytes, must be less than or equal to len.
        ///
        /// Does not invalidate any borrow of data from self.
        pub fn consume(&self, items: usize) {
            debug_assert!(self.used.get() + items <= self.populated);

            self.used.set(self.used.get() + items)
        }

        /// Returns the number of bytes left in the buffer.
        pub fn len(&self) -> usize {
            self.populated - self.used.get()
        }

        /// Returns the maximum amount of data which can be stored
        pub fn capacity(&self) -> usize {
            self.buffer.len()
        }
    }

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

        fn deref(&self) -> &[u8] {
            &self.buffer[self.used.get()..self.populated]
        }
    }

    impl ops::DerefMut for Storage {
        fn deref_mut(&mut self) -> &mut [u8] {
            &mut self.buffer[self.used.get()..self.populated]
        }
    }
}

use self::inner::Storage;

const DEFAULT_BUFFER_SIZE: usize = 6 * 1024;

bitflags!{
    flags BufferState: u64 {
        const INCOMPLETE   = 1,
        const END_OF_INPUT = 2,
    }
}

// TODO: More general variants of the buffer
#[derive(Debug)]
pub struct Buffer<R: Read> {
    /// Source reader
    source:  R,
    storage: Storage,
    /// The requested amount of bytes to be available for reading from the buffer
    request: usize,
    /// Input state, if end has been reached
    state:   BufferState,
}

impl<R: Read> Buffer<R> {
    pub fn new(source: R) -> Self {
        Self::with_size(source, DEFAULT_BUFFER_SIZE)
    }

    pub fn with_size(source: R, bufsize: usize) -> Self {
        assert!(bufsize > 0);

        Buffer {
            source:  source,
            storage: Storage::new(bufsize),
            request: 1,
            state:   INCOMPLETE,
        }
    }

    /// Attempts to fill this buffer so it contains at least ``request`` bytes.
    pub fn fill(&mut self, request: usize) -> io::Result<usize> {
        let mut read = 0;

        let mut storage = &mut self.storage;
        let     source  = &mut self.source;

        if storage.len() < request {
            storage.drop_used();

            while storage.len() < request {
                match try!(storage.fill(|b| source.read(b))) {
                    0 => break,
                    n => read = read + n,
                }
            }
        }

        self.state.remove(INCOMPLETE);

        Ok(read)
    }

    /// Returns the number of bytes left in the buffer.
    pub fn len(&self) -> usize {
        self.storage.len()
    }

    /// Borrows the remainder of the buffer.
    pub fn buffer(&self) -> &[u8] {
        &self.storage
    }

    /// Resets the buffer state, keeping the current buffer contents and cursor position.
    pub fn reset(&mut self) {
        self.state = BufferState::empty();
    }
}

impl<R: Read> Read for Buffer<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if buf.len() > self.len() {
            try!(self.fill(buf.len()));
        }

        return (&self.storage[..]).read(buf).map(|n| {
            self.storage.consume(n);

            n
        });
    }
}

impl<R: Read> BufRead for Buffer<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        let cap = self.storage.capacity();

        try!(self.fill(cap));

        Ok(self.buffer())
    }

    fn consume(&mut self, num: usize) {
        self.storage.consume(num)
    }
}

impl<'a, R: Read> Source<'a, 'a, u8> for Buffer<R> {
    fn parse<F, T, E>(&'a mut self, f: F) -> Result<T, ParseError<'a, u8, E>>
      where F: FnOnce(Input<'a, u8>) -> ParseResult<'a, u8, T, E>,
            T: 'a,
            E: 'a {
        if self.state.contains(INCOMPLETE) {
            let req = self.request;

            match self.fill(req) {
                Ok(n) if n >= req => self.state.remove(END_OF_INPUT),
                Ok(_)             => self.state.insert(END_OF_INPUT),
                Err(err)          => return Err(ParseError::IoError(err)),
            }
        }

        if self.state.contains(END_OF_INPUT) && self.len() == 0 {
            return Err(ParseError::EndOfInput);
        }

        let input_state = if self.state.contains(END_OF_INPUT) { input::END_OF_INPUT } else { input::DEFAULT };

        match f(input::new(input_state, &self.storage)).internal() {
            State::Data(remainder, data) => {
                // TODO: Do something neater with the remainder
                self.storage.consume(self.storage.len() - remainder.buffer().len());

                Ok(data)
            },
            State::Error(remainder, err) => {
                // TODO: Do something neater with the remainder
                self.storage.consume(self.storage.len() - remainder.len());

                Err(ParseError::ParseError(remainder, err))
            },
            State::Incomplete(n) => {
                self.request = self.storage.len() + n;

                if self.state.contains(END_OF_INPUT) {
                    Err(ParseError::Incomplete(self.request))
                } else {
                    self.state.insert(INCOMPLETE);

                    Err(ParseError::Retry)
                }
            },
        }
    }
}

#[cfg(test)]
mod test {
    use std::io;
    use {any, take};
    use {ParseError, Error, Source};

    use super::*;

    #[test]
    #[should_panic]
    fn bufsize_lt_chunksize() {
        let _ = Buffer::with_size(io::Cursor::new(&b"this is a test"[..]), 0);
    }

    #[test]
    fn empty_buf() {
        let mut n = 0;
        let mut b = Buffer::new(io::Cursor::new(&b""[..]));

        let r = b.parse(|i| {
            n += 1;

            take(i, 1).bind(|i, _| i.ret::<_, Error<_>>(true))
        });

        assert_eq!(r, Err(ParseError::EndOfInput));
        assert_eq!(n, 0);
    }

    #[test]
    fn fill() {
        let mut n = 0; // Times it has entered the parsing function
        let mut m = 0; // Times it has managed to get past the request for data
        let mut b = Buffer::with_size(io::Cursor::new(&b"test"[..]), 1);

        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Ok(b't'));
        assert_eq!(n, 1);
        assert_eq!(m, 1);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::Retry));
        assert_eq!(n, 2);
        assert_eq!(m, 1);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Ok(b'e'));
        assert_eq!(n, 3);
        assert_eq!(m, 2);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::Retry));
        assert_eq!(n, 4);
        assert_eq!(m, 2);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Ok(b's'));
        assert_eq!(n, 5);
        assert_eq!(m, 3);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::Retry));
        assert_eq!(n, 6);
        assert_eq!(m, 3);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Ok(b't'));
        assert_eq!(n, 7);
        assert_eq!(m, 4);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::Retry));
        assert_eq!(n, 8);
        assert_eq!(m, 4);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::EndOfInput));
        assert_eq!(n, 8);
        assert_eq!(m, 4);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::EndOfInput));
        assert_eq!(n, 8);
        assert_eq!(m, 4);
    }

    #[test]
    fn fill2() {
        let mut n = 0; // Times it has entered the parsing function
        let mut m = 0; // Times it has managed to get past the request for data
        let mut b = Buffer::with_size(io::Cursor::new(&b"test"[..]), 2);

        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Ok(b't'));
        assert_eq!(n, 1);
        assert_eq!(m, 1);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Ok(b'e'));
        assert_eq!(n, 2);
        assert_eq!(m, 2);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::Retry));
        assert_eq!(n, 3);
        assert_eq!(m, 2);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Ok(b's'));
        assert_eq!(n, 4);
        assert_eq!(m, 3);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Ok(b't'));
        assert_eq!(n, 5);
        assert_eq!(m, 4);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::Retry));
        assert_eq!(n, 6);
        assert_eq!(m, 4);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::EndOfInput));
        assert_eq!(n, 6);
        assert_eq!(m, 4);
        assert_eq!(b.parse(|i| { n += 1; any(i).inspect(|_| m += 1) }), Err(ParseError::EndOfInput));
        assert_eq!(n, 6);
        assert_eq!(m, 4);
    }

    #[test]
    fn fill3() {
        let mut n = 0; // Times it has entered the parsing function
        let mut m = 0; // Times it has managed to get past the request for data
        let mut b = Buffer::with_size(io::Cursor::new(&b"test"[..]), 3);

        assert_eq!(b.parse(|i| { n += 1; take(i, 2).inspect(|_| m += 1) }), Ok(&b"te"[..]));
        assert_eq!(n, 1);
        assert_eq!(m, 1);
        assert_eq!(b.parse(|i| { n += 1; take(i, 2).inspect(|_| m += 1) }), Err(ParseError::Retry));
        assert_eq!(n, 2);
        assert_eq!(m, 1);
        assert_eq!(b.parse(|i| { n += 1; take(i, 2).inspect(|_| m += 1) }), Ok(&b"st"[..]));
        assert_eq!(n, 3);
        assert_eq!(m, 2);
        assert_eq!(b.parse(|i| { n += 1; take(i, 2).inspect(|_| m += 1) }), Err(ParseError::EndOfInput));
        assert_eq!(n, 3);
        assert_eq!(m, 2);
        assert_eq!(b.parse(|i| { n += 1; take(i, 2).inspect(|_| m += 1) }), Err(ParseError::EndOfInput));
        assert_eq!(n, 3);
        assert_eq!(m, 2);
    }

    #[test]
    fn incomplete() {
        let mut n = 0; // Times it has entered the parsing function
        let mut m = 0; // Times it has managed to get past the request for data
        let mut b = Buffer::with_size(io::Cursor::new(&b"tes"[..]), 2);

        assert_eq!(b.parse(|i| { n += 1; take(i, 2).inspect(|_| m += 1) }), Ok(&b"te"[..]));
        assert_eq!(n, 1);
        assert_eq!(m, 1);
        assert_eq!(b.parse(|i| { n += 1; take(i, 2).inspect(|_| m += 1) }), Err(ParseError::Retry));
        assert_eq!(n, 2);
        assert_eq!(m, 1);
        assert_eq!(b.parse(|i| { n += 1; take(i, 2).inspect(|_| m += 1) }), Err(ParseError::Incomplete(2)));
        assert_eq!(n, 3);
        assert_eq!(m, 1);
        assert_eq!(b.parse(|i| { n += 1; take(i, 2).inspect(|_| m += 1) }), Err(ParseError::Incomplete(2)));
        assert_eq!(n, 4);
        assert_eq!(m, 1);
    }
}
<|endoftext|>


<commit_before>#[derive(Copy, Clone, PartialEq, PartialOrd)]
struct CacheTableEntry<T: Copy + Clone + PartialEq + PartialOrd > {
    hash: u64,
    entry: T
}

pub struct CacheTable<T: Copy + Clone + PartialEq + PartialOrd> {
    table: Vec<CacheTableEntry<T>>,
    mask: usize
}

impl <T: Copy + Clone + PartialEq + PartialOrd> CacheTable<T> {
    pub fn new(size: usize, default: T) -> CacheTable<T> {
        if size.count_ones() != 1 {
            panic!("You cannot create a CacheTable with a non-binary number.");
        }
        let mut res = CacheTable::<T> { table: Vec::with_capacity(size),
                                        mask: size - 1 };
        for _ in 0..size {
            res.table.push(CacheTableEntry { hash: 0, entry: default });
        }
        res
    }

    pub fn get(&self, hash: u64) -> Option<T> {
        let entry = unsafe { *self.table.get_unchecked((hash as usize) & self.mask) };
        if entry.hash == hash {
            Some(entry.entry)
        } else {
            None
        }
    }

    pub fn add(&mut self, hash: u64, entry: T) {
        let mut e = unsafe { self.table.get_unchecked_mut((hash as usize) & self.mask) };
        *e = CacheTableEntry { hash: hash, entry: entry };
    }
}
<commit_msg>Updated documentation.<commit_after>#[derive(Copy, Clone, PartialEq, PartialOrd)]
struct CacheTableEntry<T: Copy + Clone + PartialEq + PartialOrd > {
    hash: u64,
    entry: T
}

/// Store a cache of entries, each with an associated hash.
pub struct CacheTable<T: Copy + Clone + PartialEq + PartialOrd> {
    table: Vec<CacheTableEntry<T>>,
    mask: usize
}

impl <T: Copy + Clone + PartialEq + PartialOrd> CacheTable<T> {
    /// Create a new `CacheTable` with each associated entry initialized with a hash of '0'
    /// Note: Y ou must pass in a size where only 1 bit is set. (AKA: 2, 4, 8, 16, 1024, 65536,
    /// etc.)
    /// Panics when size is invalid.
    pub fn new(size: usize, default: T) -> CacheTable<T> {
        if size.count_ones() != 1 {
            panic!("You cannot create a CacheTable with a non-binary number.");
        }
        let mut res = CacheTable::<T> { table: Vec::with_capacity(size),
                                        mask: size - 1 };
        for _ in 0..size {
            res.table.push(CacheTableEntry { hash: 0, entry: default });
        }
        res
    }

    /// Get a particular entry with the hash specified
    pub fn get(&self, hash: u64) -> Option<T> {
        let entry = unsafe { *self.table.get_unchecked((hash as usize) & self.mask) };
        if entry.hash == hash {
            Some(entry.entry)
        } else {
            None
        }
    }

    /// Add (or overwrite) an entry with the associated hash
    pub fn add(&mut self, hash: u64, entry: T) {
        let mut e = unsafe { self.table.get_unchecked_mut((hash as usize) & self.mask) };
        *e = CacheTableEntry { hash: hash, entry: entry };
    }
}
<|endoftext|>


<commit_before>//
// zhttpto.rs
//
// Starting code for PS1
// Running on Rust 0.9
//
// Note that this code has serious security risks!  You should not run it
// on any system with access to sensitive files.
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu and David Evans
// Version 0.3

#[feature(globs)];
use std::io::*;
use std::io::net::ip::{SocketAddr};
use std::{str};

static IP: &'static str = "127.0.0.1";
static PORT:        int = 4414;

fn main() {
    let addr = from_str::<SocketAddr>(format!("{:s}:{:d}", IP, PORT)).unwrap();
    let mut acceptor = net::tcp::TcpListener::bind(addr).listen();
    let mut visitor_count = 0;

    println(format!("Listening on [{:s}] ...", addr.to_str()));

    for stream in acceptor.incoming() {
        // Spawn a task to handle the connection

	visitor_count += 1;
	let count: int = visitor_count;
        println!("Visitor count: {}", visitor_count);

	do spawn {
            let mut stream = stream;

            match stream {
                Some(ref mut s) => {
                             match s.peer_name() {
                                Some(pn) => {println(format!("Received connection from: [{:s}]", pn.to_str()));},
                                None => ()
                             }
                           },
                None => ()
            }

            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);
            println(format!("Received request :\n{:s}", request_str));
	    let wordvec: ~[&str] = request_str.split(' ').collect();
	    let magic_word = &"GET";
	    let magic_word2 = &"/";
	    if   wordvec[0].eq(&magic_word) && !wordvec[1].eq(&magic_word2) {
		let filepath = &Path::new("/home/robert/cs4414/ps1/"+ wordvec[1]);
		if filepath.exists() {
		    let mut file = File::open(filepath);
		    let response: ~str = ~"HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream;\r\nContent-Disposition: attachment; filename*=UTF-8''";
		    let filename = wordvec[1].slice_from(1);

		    let temp = response + filename + "\r\n\r\n" + file.read_to_str();
		    stream.write(temp.as_bytes());
		}
		else if !filepath.exists() {
		    let response: ~str =
		        ~"HTTP/1.1 404 NOT FOUND\r\nContent-Type: text/html; charset=UTF-8\r\n
		    <doctype !html><title>Hello, Rust!</title>

Sorry bud, that page can't be found!

		    \r\n";

		    stream.write(response.as_bytes());
		}

	    }
	    else {

                let response: ~str =
                    ~"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                 <doctype !html><title>Hello, Rust!</title>

Greetings, visitor $$!

                 \r\n";
	        let new_response = std::str::replace(response, "$$", count.to_str());
                stream.write(new_response.as_bytes());
            }
	    println!("Connection terminates.");
	    println!("Count: {}", count);
        }
    }
}
<commit_msg>Heavily reworked problem. Solves 5 and is much clearer and easier to maintain.<commit_after>//
// zhttpto.rs
//
// Starting code for PS1
// Running on Rust 0.9
//
// Note that this code has serious security risks!  You should not run it
// on any system with access to sensitive files.
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu and David Evans
// Version 0.3

#[feature(globs)];
use std::io::*;
use std::io::net::ip::{SocketAddr};
use std::{str};

static IP: &'static str = "127.0.0.1";
static PORT:        int = 4414;

fn main() {
    let addr = from_str::<SocketAddr>(format!("{:s}:{:d}", IP, PORT)).unwrap();
    let mut acceptor = net::tcp::TcpListener::bind(addr).listen();
    let mut visitor_count = 0;

    println(format!("Listening on [{:s}] ...", addr.to_str()));

    for stream in acceptor.incoming() {
        // Spawn a task to handle the connection

	visitor_count += 1;
	let count: int = visitor_count;

	do spawn {
            let mut stream = stream;

            match stream {
                Some(ref mut s) => {
                             match s.peer_name() {
                                Some(pn) => {println(format!("Received connection from: [{:s}]", pn.to_str()));},
                                None => ()
                             }
                           },
                None => ()
            }

            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);
            println(format!("Received request :\n{:s}", request_str));
	    println!("Visitor count: {}", count);

	    let wordvec: ~[&str] = request_str.split(' ').collect();
	    let current_dir = std::os::getcwd();
	    let filepath = Path::new(current_dir.as_str().unwrap() + wordvec[1]);
	    let response = open_file(filepath, current_dir, count);

	    stream.write(response.as_bytes());

	    println!("Connection terminates.\n");
        }
    }
}

fn open_file(filepath: Path, current_dir: Path, counter: int) -> ~str {

  match (filepath.exists()) {
    true => {
	      let filestring = filepath.as_str().unwrap();

	      if filestring.ends_with(".html") {
		let mut file = File::open(&filepath);

		let temp = ~"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n";
		let response = temp + file.read_to_str();

		return response;
	      }
	      else if filepath != current_dir {
		let response: ~str =
		        ~"HTTP/1.1 403 FORBIDDEN\r\nContent-Type: text/html; charset=UTF-8\r\n
			<doctype !html><title>Nope. Not allowed!</title>

ERROR 403

Sorry bud, you don't have permission for that

			\r\n";
		return response;
	      }
	    },
    false => println("File doesn't exist, so we display the homepage!")
  };
  let temp = ~"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
	      <doctype !html><title>Hello, Rust!</title>

Greetings, visitor $$!

	    \r\n";

  let response = std::str::replace(temp, "$$", counter.to_str());
  return response;
}
<|endoftext|>