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

/*!
Sampling from random distributions.

This is a generalization of `Rand` to allow parameters to control the
exact properties of the generated values, e.g. the mean and standard
deviation of a normal distribution. The `Sample` trait is the most
general, and allows for generating values that change some state
internally. The `IndependentSample` trait is for generating values
that do not need to record state.

*/

#![experimental]

use core::prelude::*;
use core::num::Int;

use {Rng, Rand};

pub use self::range::Range;
pub use self::gamma::{Gamma, ChiSquared, FisherF, StudentT};
pub use self::normal::{Normal, LogNormal};
pub use self::exponential::Exp;

pub mod range;
pub mod gamma;
pub mod normal;
pub mod exponential;

/// Types that can be used to create a random instance of `Support`.
pub trait Sample<Support> {
    /// Generate a random value of `Support`, using `rng` as the
    /// source of randomness.
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Support;
}

/// `Sample`s that do not require keeping track of state.
///
/// Since no state is recorded, each sample is (statistically)
/// independent of all others, assuming the `Rng` used has this
/// property.
// FIXME maybe having this separate is overkill (the only reason is to
// take &self rather than &mut self)? or maybe this should be the
// trait called `Sample` and the other should be `DependentSample`.
pub trait IndependentSample<Support>: Sample<Support> {
    /// Generate a random value.
    fn ind_sample<R: Rng>(&self, &mut R) -> Support;
}

/// A wrapper for generating types that implement `Rand` via the
/// `Sample` & `IndependentSample` traits.
pub struct RandSample<Sup>;

impl<Sup: Rand> Sample<Sup> for RandSample<Sup> {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
}

impl<Sup: Rand> IndependentSample<Sup> for RandSample<Sup> {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
        rng.gen()
    }
}

/// A value with a particular weight for use with `WeightedChoice`.
pub struct Weighted<T> {
    /// The numerical weight of this item
    pub weight: uint,
    /// The actual item which is being weighted
    pub item: T,
}

/// A distribution that selects from a finite collection of weighted items.
///
/// Each item has an associated weight that influences how likely it
/// is to be chosen: higher weight is more likely.
///
/// The `Clone` restriction is a limitation of the `Sample` and
/// `IndependentSample` traits. Note that `&T` is (cheaply) `Clone` for
/// all `T`, as is `uint`, so one can store references or indices into
/// another vector.
///
/// # Example
///
/// ```rust
/// use std::rand;
/// use std::rand::distributions::{Weighted, WeightedChoice, IndependentSample};
///
/// let mut items = vec!(Weighted { weight: 2, item: 'a' },
///                      Weighted { weight: 4, item: 'b' },
///                      Weighted { weight: 1, item: 'c' });
/// let wc = WeightedChoice::new(items.as_mut_slice());
/// let mut rng = rand::task_rng();
/// for _ in range(0u, 16) {
///      // on average prints 'a' 4 times, 'b' 8 and 'c' twice.
///      println!("{}", wc.ind_sample(&mut rng));
/// }
/// ```
pub struct WeightedChoice<'a, T:'a> {
    items: &'a mut [Weighted<T>],
    weight_range: Range<uint>
}

impl<'a, T: Clone> WeightedChoice<'a, T> {
    /// Create a new `WeightedChoice`.
    ///
    /// Fails if:
    /// - `v` is empty
    /// - the total weight is 0
    /// - the total weight is larger than a `uint` can contain.
    pub fn new<'a>(items: &'a mut [Weighted<T>]) -> WeightedChoice<'a, T> {
        // strictly speaking, this is subsumed by the total weight == 0 case
        assert!(!items.is_empty(), "WeightedChoice::new called with no items");

        let mut running_total = 0u;

        // we convert the list from individual weights to cumulative
        // weights so we can binary search. This *could* drop elements
        // with weight == 0 as an optimisation.
        for item in items.iter_mut() {
            running_total = match running_total.checked_add(item.weight) {
                Some(n) => n,
                None => panic!("WeightedChoice::new called with a total weight \
                               larger than a uint can contain")
            };

            item.weight = running_total;
        }
        assert!(running_total != 0, "WeightedChoice::new called with a total weight of 0");

        WeightedChoice {
            items: items,
            // we're likely to be generating numbers in this range
            // relatively often, so might as well cache it
            weight_range: Range::new(0, running_total)
        }
    }
}

impl<'a, T: Clone> Sample<T> for WeightedChoice<'a, T> {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> T { self.ind_sample(rng) }
}

impl<'a, T: Clone> IndependentSample<T> for WeightedChoice<'a, T> {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> T {
        // we want to find the first element that has cumulative
        // weight > sample_weight, which we do by binary since the
        // cumulative weights of self.items are sorted.

        // choose a weight in [0, total_weight)
        let sample_weight = self.weight_range.ind_sample(rng);

        // short circuit when it's the first item
        if sample_weight < self.items[0].weight {
            return self.items[0].item.clone();
        }

        let mut idx = 0;
        let mut modifier = self.items.len();

        // now we know that every possibility has an element to the
        // left, so we can just search for the last element that has
        // cumulative weight <= sample_weight, then the next one will
        // be "it". (Note that this greatest element will never be the
        // last element of the vector, since sample_weight is chosen
        // in [0, total_weight) and the cumulative weight of the last
        // one is exactly the total weight.)
        while modifier > 1 {
            let i = idx + modifier / 2;
            if self.items[i].weight <= sample_weight {
                // we're small, so look to the right, but allow this
                // exact element still.
                idx = i;
                // we need the `/ 2` to round up otherwise we'll drop
                // the trailing elements when `modifier` is odd.
                modifier += 1;
            } else {
                // otherwise we're too big, so go left. (i.e. do
                // nothing)
            }
            modifier /= 2;
        }
        return self.items[idx + 1].item.clone();
    }
}

mod ziggurat_tables;

/// Sample a random number using the Ziggurat method (specifically the
/// ZIGNOR variant from Doornik 2005). Most of the arguments are
/// directly from the paper:
///
/// * `rng`: source of randomness
/// * `symmetric`: whether this is a symmetric distribution, or one-sided with P(x < 0) = 0.
/// * `X`: the $x_i$ abscissae.
/// * `F`: precomputed values of the PDF at the $x_i$, (i.e. $f(x_i)$)
/// * `F_DIFF`: precomputed values of $f(x_i) - f(x_{i+1})$
/// * `pdf`: the probability density function
/// * `zero_case`: manual sampling from the tail when we chose the
///    bottom box (i.e. i == 0)

// the perf improvement (25-50%) is definitely worth the extra code
// size from force-inlining.
#[inline(always)]
fn ziggurat<R:Rng>(
            rng: &mut R,
            symmetric: bool,
            x_tab: ziggurat_tables::ZigTable,
            f_tab: ziggurat_tables::ZigTable,
            pdf: |f64|: 'static -> f64,
            zero_case: |&mut R, f64|: 'static -> f64)
            -> f64 {
    static SCALE: f64 = (1u64 << 53) as f64;
    loop {
        // reimplement the f64 generation as an optimisation suggested
        // by the Doornik paper: we have a lot of precision-space
        // (i.e. there are 11 bits of the 64 of a u64 to use after
        // creating a f64), so we might as well reuse some to save
        // generating a whole extra random number. (Seems to be 15%
        // faster.)
        //
        // This unfortunately misses out on the benefits of direct
        // floating point generation if an RNG like dSMFT is
        // used. (That is, such RNGs create floats directly, highly
        // efficiently and overload next_f32/f64, so by not calling it
        // this may be slower than it would be otherwise.)
        // FIXME: investigate/optimise for the above.
        let bits: u64 = rng.gen();
        let i = (bits & 0xff) as uint;
        let f = (bits >> 11) as f64 / SCALE;

        // u is either U(-1, 1) or U(0, 1) depending on if this is a
        // symmetric distribution or not.
        let u = if symmetric {2.0 * f - 1.0} else {f};
        let x = u * x_tab[i];

        let test_x = if symmetric { x.abs() } else {x};

        // algebraically equivalent to |u| < x_tab[i+1]/x_tab[i] (or u < x_tab[i+1]/x_tab[i])
        if test_x < x_tab[i + 1] {
            return x;
        }
        if i == 0 {
            return zero_case(rng, u);
        }
        // algebraically equivalent to f1 + DRanU()*(f0 - f1) < 1
        if f_tab[i + 1] + (f_tab[i] - f_tab[i + 1]) * rng.gen() < pdf(x) {
            return x;
        }
    }
}

#[cfg(test)]
mod tests {
    use std::prelude::*;

    use {Rng, Rand};
    use super::{RandSample, WeightedChoice, Weighted, Sample, IndependentSample};

    #[deriving(PartialEq, Show)]
    struct ConstRand(uint);
    impl Rand for ConstRand {
        fn rand<R: Rng>(_: &mut R) -> ConstRand {
            ConstRand(0)
        }
    }

    // 0, 1, 2, 3, ...
    struct CountingRng { i: u32 }
    impl Rng for CountingRng {
        fn next_u32(&mut self) -> u32 {
            self.i += 1;
            self.i - 1
        }
        fn next_u64(&mut self) -> u64 {
            self.next_u32() as u64
        }
    }

    #[test]
    fn test_rand_sample() {
        let mut rand_sample = RandSample::<ConstRand>;

        assert_eq!(rand_sample.sample(&mut ::test::rng()), ConstRand(0));
        assert_eq!(rand_sample.ind_sample(&mut ::test::rng()), ConstRand(0));
    }
    #[test]
    fn test_weighted_choice() {
        // this makes assumptions about the internal implementation of
        // WeightedChoice, specifically: it doesn't reorder the items,
        // it doesn't do weird things to the RNG (so 0 maps to 0, 1 to
        // 1, internally; modulo a modulo operation).

        macro_rules! t (
            ($items:expr, $expected:expr) => {{
                let mut items = $items;
                let wc = WeightedChoice::new(items.as_mut_slice());
                let expected = $expected;

                let mut rng = CountingRng { i: 0 };

                for &val in expected.iter() {
                    assert_eq!(wc.ind_sample(&mut rng), val)
                }
            }}
        );

        t!(vec!(Weighted { weight: 1, item: 10i}), [10]);

        // skip some
        t!(vec!(Weighted { weight: 0, item: 20i},
                Weighted { weight: 2, item: 21i},
                Weighted { weight: 0, item: 22i},
                Weighted { weight: 1, item: 23i}),
           [21,21, 23]);

        // different weights
        t!(vec!(Weighted { weight: 4, item: 30i},
                Weighted { weight: 3, item: 31i}),
           [30,30,30,30, 31,31,31]);

        // check that we're binary searching
        // correctly with some vectors of odd
        // length.
        t!(vec!(Weighted { weight: 1, item: 40i},
                Weighted { weight: 1, item: 41i},
                Weighted { weight: 1, item: 42i},
                Weighted { weight: 1, item: 43i},
                Weighted { weight: 1, item: 44i}),
           [40, 41, 42, 43, 44]);
        t!(vec!(Weighted { weight: 1, item: 50i},
                Weighted { weight: 1, item: 51i},
                Weighted { weight: 1, item: 52i},
                Weighted { weight: 1, item: 53i},
                Weighted { weight: 1, item: 54i},
                Weighted { weight: 1, item: 55i},
                Weighted { weight: 1, item: 56i}),
           [50, 51, 52, 53, 54, 55, 56]);
    }

    #[test] #[should_fail]
    fn test_weighted_choice_no_items() {
        WeightedChoice::<int>::new([]);
    }
    #[test] #[should_fail]
    fn test_weighted_choice_zero_weight() {
        WeightedChoice::new(&mut [Weighted { weight: 0, item: 0i},
                                  Weighted { weight: 0, item: 1i}]);
    }
    #[test] #[should_fail]
    fn test_weighted_choice_weight_overflows() {
        let x = (-1) as uint / 2; // x + x + 2 is the overflow
        WeightedChoice::new(&mut [Weighted { weight: x, item: 0i },
                                  Weighted { weight: 1, item: 1i },
                                  Weighted { weight: x, item: 2i },
                                  Weighted { weight: 1, item: 3i }]);
    }
}
<commit_msg>Remove Signed trait and add SignedInt trait<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
Sampling from random distributions.

This is a generalization of `Rand` to allow parameters to control the
exact properties of the generated values, e.g. the mean and standard
deviation of a normal distribution. The `Sample` trait is the most
general, and allows for generating values that change some state
internally. The `IndependentSample` trait is for generating values
that do not need to record state.

*/

#![experimental]

use core::prelude::*;
use core::num::{Float, Int};

use {Rng, Rand};

pub use self::range::Range;
pub use self::gamma::{Gamma, ChiSquared, FisherF, StudentT};
pub use self::normal::{Normal, LogNormal};
pub use self::exponential::Exp;

pub mod range;
pub mod gamma;
pub mod normal;
pub mod exponential;

/// Types that can be used to create a random instance of `Support`.
pub trait Sample<Support> {
    /// Generate a random value of `Support`, using `rng` as the
    /// source of randomness.
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Support;
}

/// `Sample`s that do not require keeping track of state.
///
/// Since no state is recorded, each sample is (statistically)
/// independent of all others, assuming the `Rng` used has this
/// property.
// FIXME maybe having this separate is overkill (the only reason is to
// take &self rather than &mut self)? or maybe this should be the
// trait called `Sample` and the other should be `DependentSample`.
pub trait IndependentSample<Support>: Sample<Support> {
    /// Generate a random value.
    fn ind_sample<R: Rng>(&self, &mut R) -> Support;
}

/// A wrapper for generating types that implement `Rand` via the
/// `Sample` & `IndependentSample` traits.
pub struct RandSample<Sup>;

impl<Sup: Rand> Sample<Sup> for RandSample<Sup> {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
}

impl<Sup: Rand> IndependentSample<Sup> for RandSample<Sup> {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
        rng.gen()
    }
}

/// A value with a particular weight for use with `WeightedChoice`.
pub struct Weighted<T> {
    /// The numerical weight of this item
    pub weight: uint,
    /// The actual item which is being weighted
    pub item: T,
}

/// A distribution that selects from a finite collection of weighted items.
///
/// Each item has an associated weight that influences how likely it
/// is to be chosen: higher weight is more likely.
///
/// The `Clone` restriction is a limitation of the `Sample` and
/// `IndependentSample` traits. Note that `&T` is (cheaply) `Clone` for
/// all `T`, as is `uint`, so one can store references or indices into
/// another vector.
///
/// # Example
///
/// ```rust
/// use std::rand;
/// use std::rand::distributions::{Weighted, WeightedChoice, IndependentSample};
///
/// let mut items = vec!(Weighted { weight: 2, item: 'a' },
///                      Weighted { weight: 4, item: 'b' },
///                      Weighted { weight: 1, item: 'c' });
/// let wc = WeightedChoice::new(items.as_mut_slice());
/// let mut rng = rand::task_rng();
/// for _ in range(0u, 16) {
///      // on average prints 'a' 4 times, 'b' 8 and 'c' twice.
///      println!("{}", wc.ind_sample(&mut rng));
/// }
/// ```
pub struct WeightedChoice<'a, T:'a> {
    items: &'a mut [Weighted<T>],
    weight_range: Range<uint>
}

impl<'a, T: Clone> WeightedChoice<'a, T> {
    /// Create a new `WeightedChoice`.
    ///
    /// Fails if:
    /// - `v` is empty
    /// - the total weight is 0
    /// - the total weight is larger than a `uint` can contain.
    pub fn new<'a>(items: &'a mut [Weighted<T>]) -> WeightedChoice<'a, T> {
        // strictly speaking, this is subsumed by the total weight == 0 case
        assert!(!items.is_empty(), "WeightedChoice::new called with no items");

        let mut running_total = 0u;

        // we convert the list from individual weights to cumulative
        // weights so we can binary search. This *could* drop elements
        // with weight == 0 as an optimisation.
        for item in items.iter_mut() {
            running_total = match running_total.checked_add(item.weight) {
                Some(n) => n,
                None => panic!("WeightedChoice::new called with a total weight \
                               larger than a uint can contain")
            };

            item.weight = running_total;
        }
        assert!(running_total != 0, "WeightedChoice::new called with a total weight of 0");

        WeightedChoice {
            items: items,
            // we're likely to be generating numbers in this range
            // relatively often, so might as well cache it
            weight_range: Range::new(0, running_total)
        }
    }
}

impl<'a, T: Clone> Sample<T> for WeightedChoice<'a, T> {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> T { self.ind_sample(rng) }
}

impl<'a, T: Clone> IndependentSample<T> for WeightedChoice<'a, T> {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> T {
        // we want to find the first element that has cumulative
        // weight > sample_weight, which we do by binary since the
        // cumulative weights of self.items are sorted.

        // choose a weight in [0, total_weight)
        let sample_weight = self.weight_range.ind_sample(rng);

        // short circuit when it's the first item
        if sample_weight < self.items[0].weight {
            return self.items[0].item.clone();
        }

        let mut idx = 0;
        let mut modifier = self.items.len();

        // now we know that every possibility has an element to the
        // left, so we can just search for the last element that has
        // cumulative weight <= sample_weight, then the next one will
        // be "it". (Note that this greatest element will never be the
        // last element of the vector, since sample_weight is chosen
        // in [0, total_weight) and the cumulative weight of the last
        // one is exactly the total weight.)
        while modifier > 1 {
            let i = idx + modifier / 2;
            if self.items[i].weight <= sample_weight {
                // we're small, so look to the right, but allow this
                // exact element still.
                idx = i;
                // we need the `/ 2` to round up otherwise we'll drop
                // the trailing elements when `modifier` is odd.
                modifier += 1;
            } else {
                // otherwise we're too big, so go left. (i.e. do
                // nothing)
            }
            modifier /= 2;
        }
        return self.items[idx + 1].item.clone();
    }
}

mod ziggurat_tables;

/// Sample a random number using the Ziggurat method (specifically the
/// ZIGNOR variant from Doornik 2005). Most of the arguments are
/// directly from the paper:
///
/// * `rng`: source of randomness
/// * `symmetric`: whether this is a symmetric distribution, or one-sided with P(x < 0) = 0.
/// * `X`: the $x_i$ abscissae.
/// * `F`: precomputed values of the PDF at the $x_i$, (i.e. $f(x_i)$)
/// * `F_DIFF`: precomputed values of $f(x_i) - f(x_{i+1})$
/// * `pdf`: the probability density function
/// * `zero_case`: manual sampling from the tail when we chose the
///    bottom box (i.e. i == 0)

// the perf improvement (25-50%) is definitely worth the extra code
// size from force-inlining.
#[inline(always)]
fn ziggurat<R:Rng>(
            rng: &mut R,
            symmetric: bool,
            x_tab: ziggurat_tables::ZigTable,
            f_tab: ziggurat_tables::ZigTable,
            pdf: |f64|: 'static -> f64,
            zero_case: |&mut R, f64|: 'static -> f64)
            -> f64 {
    static SCALE: f64 = (1u64 << 53) as f64;
    loop {
        // reimplement the f64 generation as an optimisation suggested
        // by the Doornik paper: we have a lot of precision-space
        // (i.e. there are 11 bits of the 64 of a u64 to use after
        // creating a f64), so we might as well reuse some to save
        // generating a whole extra random number. (Seems to be 15%
        // faster.)
        //
        // This unfortunately misses out on the benefits of direct
        // floating point generation if an RNG like dSMFT is
        // used. (That is, such RNGs create floats directly, highly
        // efficiently and overload next_f32/f64, so by not calling it
        // this may be slower than it would be otherwise.)
        // FIXME: investigate/optimise for the above.
        let bits: u64 = rng.gen();
        let i = (bits & 0xff) as uint;
        let f = (bits >> 11) as f64 / SCALE;

        // u is either U(-1, 1) or U(0, 1) depending on if this is a
        // symmetric distribution or not.
        let u = if symmetric {2.0 * f - 1.0} else {f};
        let x = u * x_tab[i];

        let test_x = if symmetric { x.abs() } else {x};

        // algebraically equivalent to |u| < x_tab[i+1]/x_tab[i] (or u < x_tab[i+1]/x_tab[i])
        if test_x < x_tab[i + 1] {
            return x;
        }
        if i == 0 {
            return zero_case(rng, u);
        }
        // algebraically equivalent to f1 + DRanU()*(f0 - f1) < 1
        if f_tab[i + 1] + (f_tab[i] - f_tab[i + 1]) * rng.gen() < pdf(x) {
            return x;
        }
    }
}

#[cfg(test)]
mod tests {
    use std::prelude::*;

    use {Rng, Rand};
    use super::{RandSample, WeightedChoice, Weighted, Sample, IndependentSample};

    #[deriving(PartialEq, Show)]
    struct ConstRand(uint);
    impl Rand for ConstRand {
        fn rand<R: Rng>(_: &mut R) -> ConstRand {
            ConstRand(0)
        }
    }

    // 0, 1, 2, 3, ...
    struct CountingRng { i: u32 }
    impl Rng for CountingRng {
        fn next_u32(&mut self) -> u32 {
            self.i += 1;
            self.i - 1
        }
        fn next_u64(&mut self) -> u64 {
            self.next_u32() as u64
        }
    }

    #[test]
    fn test_rand_sample() {
        let mut rand_sample = RandSample::<ConstRand>;

        assert_eq!(rand_sample.sample(&mut ::test::rng()), ConstRand(0));
        assert_eq!(rand_sample.ind_sample(&mut ::test::rng()), ConstRand(0));
    }
    #[test]
    fn test_weighted_choice() {
        // this makes assumptions about the internal implementation of
        // WeightedChoice, specifically: it doesn't reorder the items,
        // it doesn't do weird things to the RNG (so 0 maps to 0, 1 to
        // 1, internally; modulo a modulo operation).

        macro_rules! t (
            ($items:expr, $expected:expr) => {{
                let mut items = $items;
                let wc = WeightedChoice::new(items.as_mut_slice());
                let expected = $expected;

                let mut rng = CountingRng { i: 0 };

                for &val in expected.iter() {
                    assert_eq!(wc.ind_sample(&mut rng), val)
                }
            }}
        );

        t!(vec!(Weighted { weight: 1, item: 10i}), [10]);

        // skip some
        t!(vec!(Weighted { weight: 0, item: 20i},
                Weighted { weight: 2, item: 21i},
                Weighted { weight: 0, item: 22i},
                Weighted { weight: 1, item: 23i}),
           [21,21, 23]);

        // different weights
        t!(vec!(Weighted { weight: 4, item: 30i},
                Weighted { weight: 3, item: 31i}),
           [30,30,30,30, 31,31,31]);

        // check that we're binary searching
        // correctly with some vectors of odd
        // length.
        t!(vec!(Weighted { weight: 1, item: 40i},
                Weighted { weight: 1, item: 41i},
                Weighted { weight: 1, item: 42i},
                Weighted { weight: 1, item: 43i},
                Weighted { weight: 1, item: 44i}),
           [40, 41, 42, 43, 44]);
        t!(vec!(Weighted { weight: 1, item: 50i},
                Weighted { weight: 1, item: 51i},
                Weighted { weight: 1, item: 52i},
                Weighted { weight: 1, item: 53i},
                Weighted { weight: 1, item: 54i},
                Weighted { weight: 1, item: 55i},
                Weighted { weight: 1, item: 56i}),
           [50, 51, 52, 53, 54, 55, 56]);
    }

    #[test] #[should_fail]
    fn test_weighted_choice_no_items() {
        WeightedChoice::<int>::new([]);
    }
    #[test] #[should_fail]
    fn test_weighted_choice_zero_weight() {
        WeightedChoice::new(&mut [Weighted { weight: 0, item: 0i},
                                  Weighted { weight: 0, item: 1i}]);
    }
    #[test] #[should_fail]
    fn test_weighted_choice_weight_overflows() {
        let x = (-1) as uint / 2; // x + x + 2 is the overflow
        WeightedChoice::new(&mut [Weighted { weight: x, item: 0i },
                                  Weighted { weight: 1, item: 1i },
                                  Weighted { weight: x, item: 2i },
                                  Weighted { weight: 1, item: 3i }]);
    }
}
<|endoftext|>


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

//! Traits for the built-in operators

#[allow(missing_doc)];

#[lang="drop"]
pub trait Drop {
    fn drop(&mut self);
}

#[lang="add"]
pub trait Add<RHS,Result> {
    fn add(&self, rhs: &RHS) -> Result;
}

#[lang="sub"]
pub trait Sub<RHS,Result> {
    fn sub(&self, rhs: &RHS) -> Result;
}

#[lang="mul"]
pub trait Mul<RHS,Result> {
    fn mul(&self, rhs: &RHS) -> Result;
}

#[lang="div"]
pub trait Div<RHS,Result> {
    fn div(&self, rhs: &RHS) -> Result;
}

#[lang="rem"]
pub trait Rem<RHS,Result> {
    fn rem(&self, rhs: &RHS) -> Result;
}

#[lang="neg"]
pub trait Neg<Result> {
    fn neg(&self) -> Result;
}

#[lang="not"]
pub trait Not<Result> {
    fn not(&self) -> Result;
}

#[lang="bitand"]
pub trait BitAnd<RHS,Result> {
    fn bitand(&self, rhs: &RHS) -> Result;
}

#[lang="bitor"]
pub trait BitOr<RHS,Result> {
    fn bitor(&self, rhs: &RHS) -> Result;
}

#[lang="bitxor"]
pub trait BitXor<RHS,Result> {
    fn bitxor(&self, rhs: &RHS) -> Result;
}

#[lang="shl"]
pub trait Shl<RHS,Result> {
    fn shl(&self, rhs: &RHS) -> Result;
}

#[lang="shr"]
pub trait Shr<RHS,Result> {
    fn shr(&self, rhs: &RHS) -> Result;
}

#[lang="index"]
pub trait Index<Index,Result> {
    fn index(&self, index: &Index) -> Result;
}

#[cfg(test)]
mod bench {

    use extra::test::BenchHarness;
    use ops::Drop;

    // Overhead of dtors

    struct HasDtor {
        x: int
    }

    impl Drop for HasDtor {
        fn drop(&mut self) {
        }
    }

    #[bench]
    fn alloc_obj_with_dtor(bh: &mut BenchHarness) {
        do bh.iter {
            HasDtor { x : 10 };
        }
    }
}
<commit_msg>auto merge of #9522 : steveklabnik/rust/doc_std_opts, r=alexcrichton<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// So we don't have to document the actual methods on the traits.
#[allow(missing_doc)];

/*!
 *
 * Traits for the built-in operators. Implementing these traits allows you to get
 * an effect similar to oveloading operators.
 *
 * The values for the right hand side of an operator are automatically
 * borrowed, so `a + b` is sugar for `a.add(&b)`.
 *
 * All of these traits are imported by the prelude, so they are available in
 * every Rust program.
 *
 * # Example
 *
 * This example creates a `Point` struct that implements `Add` and `Sub`, and then
 * demonstrates adding and subtracting two `Point`s.
 *
 * ```rust
 * struct Point {
 *     x: int,
 *     y: int
 * }
 *
 * impl Add<Point, Point> for Point {
 *     fn add(&self, other: &Point) -> Point {
 *         Point {x: self.x + other.x, y: self.y + other.y}
 *     }
 * }
 *
 * impl Sub<Point, Point> for Point {
 *     fn sub(&self, other: &Point) -> Point {
 *         Point {x: self.x - other.x, y: self.y - other.y}
 *     }
 * }
 * fn main() {
 *     println(format!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3}));
 *     println(format!("{:?}", Point {x: 1, y: 0} - Point {x: 2, y: 3}));
 * }
 * ```
 *
 * See the documentation for each trait for a minimum implementation that prints
 * something to the screen.
 *
 */

/**
 *
 * The `Drop` trait is used to run some code when a value goes out of scope. This
 * is sometimes called a 'destructor'.
 *
 * # Example
 *
 * A trivial implementation of `Drop`. The `drop` method is called when `_x` goes
 * out of scope, and therefore `main` prints `Dropping!`.
 *
 * ```rust
 * struct HasDrop;
 *
 * impl Drop for HasDrop {
 *   fn drop(&mut self) {
 *       println("Dropping!");
 *   }
 * }
 *
 * fn main() {
 *   let _x = HasDrop;
 * }
 * ```
 */
#[lang="drop"]
pub trait Drop {
    fn drop(&mut self);
}

/**
 *
 * The `Add` trait is used to specify the functionality of `+`.
 *
 * # Example
 *
 * A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up
 * calling `add`, and therefore, `main` prints `Adding!`.
 *
 * ```rust
 * struct Foo;
 *
 * impl Add<Foo, Foo> for Foo {
 *     fn add(&self, _rhs: &Foo) -> Foo {
 *       println("Adding!");
 *       *self
 *   }
 * }
 *
 * fn main() {
 *   Foo + Foo;
 * }
 * ```
 */
#[lang="add"]
pub trait Add<RHS,Result> {
    fn add(&self, rhs: &RHS) -> Result;
}

/**
 *
 * The `Sub` trait is used to specify the functionality of `-`.
 *
 * # Example
 *
 * A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up
 * calling `sub`, and therefore, `main` prints `Subtracting!`.
 *
 * ```rust
 * struct Foo;
 *
 * impl Sub<Foo, Foo> for Foo {
 *     fn sub(&self, _rhs: &Foo) -> Foo {
 *         println("Subtracting!");
 *         *self
 *     }
 * }
 *
 * fn main() {
 *     Foo - Foo;
 * }
 * ```
 */
#[lang="sub"]
pub trait Sub<RHS,Result> {
    fn sub(&self, rhs: &RHS) -> Result;
}

/**
 *
 * The `Mul` trait is used to specify the functionality of `*`.
 *
 * # Example
 *
 * A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
 * calling `mul`, and therefore, `main` prints `Multiplying!`.
 *
 * ```rust
 * struct Foo;
 *
 * impl Mul<Foo, Foo> for Foo {
 *     fn mul(&self, _rhs: &Foo) -> Foo {
 *         println("Multiplying!");
 *         *self
 *     }
 * }
 *
 * fn main() {
 *     Foo * Foo;
 * }
 * ```
 */
#[lang="mul"]
pub trait Mul<RHS,Result> {
    fn mul(&self, rhs: &RHS) -> Result;
}

/**
 *
 * The `Div` trait is used to specify the functionality of `/`.
 *
 * # Example
 *
 * A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up
 * calling `div`, and therefore, `main` prints `Dividing!`.
 *
 * ```
 * struct Foo;
 *
 * impl Div<Foo, Foo> for Foo {
 *     fn div(&self, _rhs: &Foo) -> Foo {
 *         println("Dividing!");
 *         *self
 *     }
 * }
 *
 * fn main() {
 *     Foo / Foo;
 * }
 * ```
 */
#[lang="div"]
pub trait Div<RHS,Result> {
    fn div(&self, rhs: &RHS) -> Result;
}

/**
 *
 * The `Rem` trait is used to specify the functionality of `%`.
 *
 * # Example
 *
 * A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
 * calling `rem`, and therefore, `main` prints `Remainder-ing!`.
 *
 * ```
 * struct Foo;
 *
 * impl Rem<Foo, Foo> for Foo {
 *     fn rem(&self, _rhs: &Foo) -> Foo {
 *         println("Remainder-ing!");
 *         *self
 *     }
 * }
 *
 * fn main() {
 *     Foo % Foo;
 * }
 * ```
 */
#[lang="rem"]
pub trait Rem<RHS,Result> {
    fn rem(&self, rhs: &RHS) -> Result;
}

/**
 *
 * The `Neg` trait is used to specify the functionality of unary `-`.
 *
 * # Example
 *
 * A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling
 * `neg`, and therefore, `main` prints `Negating!`.
 *
 * ```
 * struct Foo;
 *
 * impl Neg<Foo> for Foo {
 *     fn neg(&self) -> Foo {
 *         println("Negating!");
 *         *self
 *     }
 * }
 *
 * fn main() {
 *     -Foo;
 * }
 * ```
 */
#[lang="neg"]
pub trait Neg<Result> {
    fn neg(&self) -> Result;
}

/**
 *
 * The `Not` trait is used to specify the functionality of unary `!`.
 *
 * # Example
 *
 * A trivial implementation of `Not`. When `!Foo` happens, it ends up calling
 * `not`, and therefore, `main` prints `Not-ing!`.
 *
 * ```
 * struct Foo;
 *
 * impl Not<Foo> for Foo {
 *     fn not(&self) -> Foo {
 *         println("Not-ing!");
 *         *self
 *     }
 * }
 *
 * fn main() {
 *     !Foo;
 * }
 * ```
 */
#[lang="not"]
pub trait Not<Result> {
    fn not(&self) -> Result;
}

/**
 *
 * The `BitAnd` trait is used to specify the functionality of `&`.
 *
 * # Example
 *
 * A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
 * calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
 *
 * ```
 * struct Foo;
 *
 * impl BitAnd<Foo, Foo> for Foo {
 *     fn bitand(&self, _rhs: &Foo) -> Foo {
 *         println("Bitwise And-ing!");
 *         *self
 *     }
 * }
 *
 * fn main() {
 *     Foo & Foo;
 * }
 * ```
 */
#[lang="bitand"]
pub trait BitAnd<RHS,Result> {
    fn bitand(&self, rhs: &RHS) -> Result;
}

/**
 *
 * The `BitOr` trait is used to specify the functionality of `|`.
 *
 * # Example
 *
 * A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
 * calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
 *
 * ```
 * struct Foo;
 *
 * impl BitOr<Foo, Foo> for Foo {
 *     fn bitor(&self, _rhs: &Foo) -> Foo {
 *         println("Bitwise Or-ing!");
 *         *self
 *     }
 * }
 *
 * fn main() {
 *     Foo | Foo;
 * }
 * ```
 */
#[lang="bitor"]
pub trait BitOr<RHS,Result> {
    fn bitor(&self, rhs: &RHS) -> Result;
}

/**
 *
 * The `BitXor` trait is used to specify the functionality of `^`.
 *
 * # Example
 *
 * A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
 * calling `bixtor`, and therefore, `main` prints `Bitwise Xor-ing!`.
 *
 * ```
 * struct Foo;
 *
 * impl BitXor<Foo, Foo> for Foo {
 *     fn bitxor(&self, _rhs: &Foo) -> Foo {
 *         println("Bitwise Xor-ing!");
 *         *self
 *     }
 * }
 *
 * fn main() {
 *     Foo ^ Foo;
 * }
 * ```
 */
#[lang="bitxor"]
pub trait BitXor<RHS,Result> {
    fn bitxor(&self, rhs: &RHS) -> Result;
}

/**
 *
 * The `Shl` trait is used to specify the functionality of `<<`.
 *
 * # Example
 *
 * A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up
 * calling `shl`, and therefore, `main` prints `Shifting left!`.
 *
 * ```
 * struct Foo;
 *
 * impl Shl<Foo, Foo> for Foo {
 *     fn shl(&self, _rhs: &Foo) -> Foo {
 *         println("Shifting left!");
 *         *self
 *     }
 * }
 *
 * fn main() {
 *     Foo << Foo;
 * }
 * ```
 */
#[lang="shl"]
pub trait Shl<RHS,Result> {
    fn shl(&self, rhs: &RHS) -> Result;
}

/**
 *
 * The `Shr` trait is used to specify the functionality of `>>`.
 *
 * # Example
 *
 * A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up
 * calling `shr`, and therefore, `main` prints `Shifting right!`.
 *
 * ```
 * struct Foo;
 *
 * impl Shr<Foo, Foo> for Foo {
 *     fn shr(&self, _rhs: &Foo) -> Foo {
 *         println("Shifting right!");
 *         *self
 *     }
 * }
 *
 * fn main() {
 *     Foo >> Foo;
 * }
 * ```
 */
#[lang="shr"]
pub trait Shr<RHS,Result> {
    fn shr(&self, rhs: &RHS) -> Result;
}

/**
 *
 * The `Index` trait is used to specify the functionality of indexing operations
 * like `arr[idx]`.
 *
 * # Example
 *
 * A trivial implementation of `Index`. When `Foo[Foo]` happens, it ends up
 * calling `index`, and therefore, `main` prints `Indexing!`.
 *
 * ```
 * struct Foo;
 *
 * impl Index<Foo, Foo> for Foo {
 *     fn index(&self, _rhs: &Foo) -> Foo {
 *         println("Indexing!");
 *         *self
 *     }
 * }
 *
 * fn main() {
 *     Foo[Foo];
 * }
 * ```
 */
#[lang="index"]
pub trait Index<Index,Result> {
    fn index(&self, index: &Index) -> Result;
}

#[cfg(test)]
mod bench {

    use extra::test::BenchHarness;
    use ops::Drop;

    // Overhead of dtors

    struct HasDtor {
        x: int
    }

    impl Drop for HasDtor {
        fn drop(&mut self) {
        }
    }

    #[bench]
    fn alloc_obj_with_dtor(bh: &mut BenchHarness) {
        do bh.iter {
            HasDtor { x : 10 };
        }
    }
}
<|endoftext|>


<commit_before>#[derive(Debug)]
#[repr(C)]
pub struct MemoryMapTag {
    typ: u32,
    size: u32,
    entry_size: u32,
    entry_version: u32,
    first_area: MemoryArea,
}

impl MemoryMapTag {
    pub fn memory_areas(&self) -> MemoryAreaIter {
        let self_ptr = self as *const MemoryMapTag;
        let start_area = (&self.first_area) as *const MemoryArea;
        MemoryAreaIter {
            current_area: start_area as u64,
            last_area: (self_ptr as u64 + (self.size - self.entry_size) as u64),
            entry_size: self.entry_size,
        }
    }
}

#[derive(Debug)]
#[repr(C)]
pub struct MemoryArea {
    base_addr: u64,
    length: u64,
    typ: u32,
    _reserved: u32,
}

impl MemoryArea {
    pub fn start_address(&self) -> u64 {
        self.base_addr
    }

    pub fn end_address(&self) -> u64 {
        (self.base_addr + self.length)
    }

    pub fn size(&self) -> usize {
        self.length as usize
    }
}

#[derive(Clone, Debug)]
pub struct MemoryAreaIter {
    current_area: u64,
    last_area: u64,
    entry_size: u32,
}

impl Iterator for MemoryAreaIter {
    type Item = &'static MemoryArea;
    fn next(&mut self) -> Option<&'static MemoryArea> {
        if self.current_area > self.last_area {
            None
        } else {
            let area = unsafe{&*(self.current_area as *const MemoryArea)};
            self.current_area = self.current_area + (self.entry_size as u64);
            if area.typ == 1 {
                Some(area)
            } else {self.next()}
        }
    }
}
<commit_msg>Return u64 from MemoryArea::size<commit_after>#[derive(Debug)]
#[repr(C)]
pub struct MemoryMapTag {
    typ: u32,
    size: u32,
    entry_size: u32,
    entry_version: u32,
    first_area: MemoryArea,
}

impl MemoryMapTag {
    pub fn memory_areas(&self) -> MemoryAreaIter {
        let self_ptr = self as *const MemoryMapTag;
        let start_area = (&self.first_area) as *const MemoryArea;
        MemoryAreaIter {
            current_area: start_area as u64,
            last_area: (self_ptr as u64 + (self.size - self.entry_size) as u64),
            entry_size: self.entry_size,
        }
    }
}

#[derive(Debug)]
#[repr(C)]
pub struct MemoryArea {
    base_addr: u64,
    length: u64,
    typ: u32,
    _reserved: u32,
}

impl MemoryArea {
    pub fn start_address(&self) -> u64 {
        self.base_addr
    }

    pub fn end_address(&self) -> u64 {
        (self.base_addr + self.length)
    }

    pub fn size(&self) -> u64 {
        self.length
    }
}

#[derive(Clone, Debug)]
pub struct MemoryAreaIter {
    current_area: u64,
    last_area: u64,
    entry_size: u32,
}

impl Iterator for MemoryAreaIter {
    type Item = &'static MemoryArea;
    fn next(&mut self) -> Option<&'static MemoryArea> {
        if self.current_area > self.last_area {
            None
        } else {
            let area = unsafe{&*(self.current_area as *const MemoryArea)};
            self.current_area = self.current_area + (self.entry_size as u64);
            if area.typ == 1 {
                Some(area)
            } else {self.next()}
        }
    }
}
<|endoftext|>


<commit_before>//! Constant-time comparison of fixed-size vecs
use ffi;

/// `verify_16()` returns `true` if `x[0]`, `x[1]`, ..., `x[15]` are the
/// same as `y[0]`, `y[1]`, ..., `y[15]`. Otherwise it returns `false`.
///
/// This functions is safe to use for secrets `x[0]`, `x[1]`, ..., `x[15]`,
/// `y[0]`, `y[1]`, ..., `y[15]`. The time taken by `verify_16` is independent
/// of the contents of `x[0]`, `x[1]`, ..., `x[15]`, `y[0]`, `y[1]`, ..., `y[15]`.
/// In contrast, the standard C comparison function `memcmp(x,y,16)` takes time
/// that depends on the longest matching prefix of `x` and `y`, often allowing easy
/// timing attacks.
pub fn verify_16(x: &[u8; 16], y: &[u8; 16]) -> bool {
    unsafe {
        ffi::crypto_verify_16(x.as_ptr(), y.as_ptr()) == 0
    }
}

/// `verify_32()` returns true if `x[0]`, `x[1]`, ..., `x[31]` are the
/// same as `y[0]`, `y[1]`, ..., `y[31]`. Otherwise it returns `false`.
///
/// This functions is safe to use for secrets `x[0]`, `x[1]`, ..., `x[31]`,
/// `y[0]`, `y[1]`, ..., `y[31]`. The time taken by `verify_32` is independent
/// of the contents of `x[0]`, `x[1]`, ..., `x[31]`, `y[0]`, `y[1]`, ..., `y[31]`.
/// In contrast, the standard C comparison function `memcmp(x,y,32)` takes time
/// that depends on the longest matching prefix of `x` and `y`, often allowing easy
/// timing attacks.
pub fn verify_32(x: &[u8; 32], y: &[u8; 32]) -> bool {
    unsafe {
        ffi::crypto_verify_32(x.as_ptr(), y.as_ptr()) == 0
    }
}

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

    #[test]
    fn test_verify_16() {
        use randombytes::randombytes_into;

        for _ in (0usize..256) {
            let mut x = [0; 16];
            let mut y = [0; 16];
            assert!(verify_16(&x, &y));
            randombytes_into(&mut x);
            randombytes_into(&mut y);
            if x == y {
                assert!(verify_16(&x, &y))
            } else {
                assert!(!verify_16(&x, &y))
            }
        }
    }

    #[test]
    fn test_verify_32() {
        use randombytes::randombytes_into;

        for _ in (0usize..256) {
            let mut x = [0; 32];
            let mut y = [0; 32];
            assert!(verify_32(&x, &y));
            randombytes_into(&mut x);
            randombytes_into(&mut y);
            if x == y {
                assert!(verify_32(&x, &y))
            } else {
                assert!(!verify_32(&x, &y))
            }
        }
    }
}
<commit_msg>Fixes for changes in crypto_verify_16/32 definitons<commit_after>//! Constant-time comparison of fixed-size vecs
use ffi;

/// `verify_16()` returns `true` if `x[0]`, `x[1]`, ..., `x[15]` are the
/// same as `y[0]`, `y[1]`, ..., `y[15]`. Otherwise it returns `false`.
///
/// This functions is safe to use for secrets `x[0]`, `x[1]`, ..., `x[15]`,
/// `y[0]`, `y[1]`, ..., `y[15]`. The time taken by `verify_16` is independent
/// of the contents of `x[0]`, `x[1]`, ..., `x[15]`, `y[0]`, `y[1]`, ..., `y[15]`.
/// In contrast, the standard C comparison function `memcmp(x,y,16)` takes time
/// that depends on the longest matching prefix of `x` and `y`, often allowing easy
/// timing attacks.
pub fn verify_16(x: &[u8; 16], y: &[u8; 16]) -> bool {
    unsafe {
        ffi::crypto_verify_16(x, y) == 0
    }
}

/// `verify_32()` returns true if `x[0]`, `x[1]`, ..., `x[31]` are the
/// same as `y[0]`, `y[1]`, ..., `y[31]`. Otherwise it returns `false`.
///
/// This functions is safe to use for secrets `x[0]`, `x[1]`, ..., `x[31]`,
/// `y[0]`, `y[1]`, ..., `y[31]`. The time taken by `verify_32` is independent
/// of the contents of `x[0]`, `x[1]`, ..., `x[31]`, `y[0]`, `y[1]`, ..., `y[31]`.
/// In contrast, the standard C comparison function `memcmp(x,y,32)` takes time
/// that depends on the longest matching prefix of `x` and `y`, often allowing easy
/// timing attacks.
pub fn verify_32(x: &[u8; 32], y: &[u8; 32]) -> bool {
    unsafe {
        ffi::crypto_verify_32(x, y) == 0
    }
}

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

    #[test]
    fn test_verify_16() {
        use randombytes::randombytes_into;

        for _ in (0usize..256) {
            let mut x = [0; 16];
            let mut y = [0; 16];
            assert!(verify_16(&x, &y));
            randombytes_into(&mut x);
            randombytes_into(&mut y);
            if x == y {
                assert!(verify_16(&x, &y))
            } else {
                assert!(!verify_16(&x, &y))
            }
        }
    }

    #[test]
    fn test_verify_32() {
        use randombytes::randombytes_into;

        for _ in (0usize..256) {
            let mut x = [0; 32];
            let mut y = [0; 32];
            assert!(verify_32(&x, &y));
            randombytes_into(&mut x);
            randombytes_into(&mut y);
            if x == y {
                assert!(verify_32(&x, &y))
            } else {
                assert!(!verify_32(&x, &y))
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::net;

struct Listner{
    clientAddr: net::SocketAddr,
    reqType: str,
    reqFile: str,
    httpProto: str,
    userAgent: str,
    rawReq: str,
}

impl Listner {
    fn listen () {

    }
}<commit_msg>Commit loop<commit_after>use std::net;
use std::str;

struct Listner{
    clientAddr: net::SocketAddr,
    reqType: str,
    reqFile: str,
    httpProto: str,
    userAgent: str,
    rawReq: str,
}

impl Listner {
    fn listen () {

    }

    fn ParseRequestStr(self, req_str: str) {
        //Populate the fields of the listener struct
        //http://www.trevisrothwell.com/2015/01/string-tokenization-in-rust/
        //Now StrExt doesn't exist. Part of std:str

        let mut term = str::Split(req_str, " ");

        loop {
            match term.next() {
                "GET" => {self.reqType = "GET"},
                path @ _ => {self.reqFile = path},
                "HTTP /1.1" => {self.httpProto = "HTTP /1.1"}
            }
        }
    }
}<|endoftext|>


<commit_before>fn insertiong_sort(nl: Vec<i32>, f: &Fn(&i32, &i32) -> bool) -> Vec<i32> {
    let mut head = vec![nl[0]];
    for i in &nl[1..] {
        let thisInd = head.iter().position(|&r| f(r,i)).unwrap();
        if thisInd
    }
}

fn large(a: &i32, b: &i32) -> bool {
    return a > b;
}

fn small(a: &i32, b: &i32) -> bool {
    return a < b;
}
<commit_msg>finish<commit_after>fn insertiong_sort(nl: &Vec<i32>, f: &Fn(&i32, &i32) -> bool) -> Vec<i32> {
    let mut head = vec![nl[0]];
    for i in &nl[1..] {
        if let Some(thisInd) = head.iter().position(|&r| f(&r, i)) {
            head.insert(thisInd, *i);
        } else {
            head.push(*i);
        }
        println!("{:?}", head);
    }
    return head;
}

fn large(a: &i32, b: &i32) -> bool {
    return a > b;
}

fn small(a: &i32, b: &i32) -> bool {
    return a < b;
}

fn main() {
    let test = vec![3, 7, 4, 9, 5, 2, 6, 1];
    insertiong_sort(&test, &large);
    insertiong_sort(&test, &small);
}
<|endoftext|>


<commit_before>// Syntax: master_server [ip address (0.0.0.0 by default)]
// This was created for HaloMD.

// If the server does not respond in at least this many seconds, it will be dropped from the list.
const DROP_TIME : i64 = 60;

// Blacklist for blocking IPs. Separate with newlines.
// Blacklisting IPs ignores heartbeat and keepalive packets from an IP address.
// That means that servers that are banned will not be immediately removed, but will time out, instead.
const BLACKLIST_FILE : &'static str = "blacklist.txt";

// Read the blacklist every x amount of seconds.
const BLACKLIST_UPDATE_TIME : u32 = 60;

// Note: The master server must have TCP 29920 open and UDP 27900 open.

use std::net::{UdpSocket,TcpListener};
use std::io::{Write,BufReader,BufRead};
use std::env;
use std::fs::File;
use std::thread;
use std::sync::{Arc, Mutex};

extern crate time;

mod halo_server;
use halo_server::HaloServer;

mod heartbeat_packet;
use heartbeat_packet::HeartbeatPacket;

fn main() {
    let count = env::args().count();
    let ip = if count == 2 {
        let j : Vec<_> = env::args().collect();
        j[1].to_string()
    }
    else if count == 1 {
        "0.0.0.0".to_string()
    }
    else {
        println!("Only one argument is allowed: the IP to bind to.");
        return;
    };

    // We need to bind on two different ports. If it failed to bind (invalid IP, port is taken), then we must make sure this is known.
    let halo_socket = match UdpSocket::bind((&ip as &str,27900)) {
        Err(_) => {
            println!("Error creating a UDP socket at {}:27900.",ip);
            return;
        },
        Ok(halo_socket) => halo_socket
    };

    let client_socket = match TcpListener::bind((&ip as &str,29920)) {
        Err(_) => {
            println!("Error listening to TCP at {}:29920.",ip);
            return;
        },
        Ok(client_socket) => client_socket
    };

    // Mutex for thread safety.
    let servers_halo: Vec<HaloServer> = Vec::new();
    let servers_mut_udp = Arc::new(Mutex::new(servers_halo));
    let servers_mut_tcp = servers_mut_udp.clone();
    let servers_mut_destruction = servers_mut_udp.clone();

    // Destruction thread. This will remove servers that have not broadcasted their presence in a while.
    thread::spawn(move || {
        loop {
            thread::sleep_ms(10 * 1000);
            let mut servers = servers_mut_destruction.lock().unwrap();
            let timenow = time::now().to_timespec().sec;
            servers.retain(|x| x.last_alive + DROP_TIME > timenow);
        }
    });

    // Blacklist mutex. Concurrency needs to be safe, my friend.
    let blacklist: Vec<String> = Vec::new();
    let blacklist_update = Arc::new(Mutex::new(blacklist));
    let blacklist_udp = blacklist_update.clone();

    // Blacklist read thread.
    thread::spawn(move || {
        loop {
            // Placed in a block so blacklist is unlocked before sleeping to prevent threads from being locked for too long.
            {
                let mut blacklist_ref = blacklist_update.lock().unwrap();
                match File::open(BLACKLIST_FILE) {
                    Ok(file) => {
                        let reader = BufReader::new(&file);
                        match reader.lines().collect() {
                            Err(_) => {
                                blacklist_ref.clear();
                            },
                            Ok(t) => {
                                *blacklist_ref = t;
                            }
                        }
                    },
                    Err(_) => {}
                };
            }
            thread::sleep_ms(BLACKLIST_UPDATE_TIME * 1000);
        }
    });

    // TCP server thread. This is for the HaloMD application.
    thread::spawn(move || {
        loop {
            for stream in client_socket.incoming() {
                let mut client = match stream {
                    Err(_) => continue,
                    Ok(the_stream) => the_stream
                };
                // Unwrap the IP.
                let ip = match client.peer_addr() {
                    Err(_) => continue,
                    Ok(ip) => ip.to_string().split(":").next().unwrap().to_string()
                };

                let mut ips = String::new();

                let servers_ref = servers_mut_tcp.lock().unwrap();
                let servers = (*servers_ref).iter();

                for j in servers {
                    ips = ips + &(j.to_string()) + "\n";
                }

                // Some number placed after the requester's IP. If you ask me, the source code was abducted by aliens, and this is a tracking number. Regardless, it's needed.
                ips = ips + &ip + ":49149:3425";
                let _ = client.write_all(ips.as_bytes());
            }
        }
    });

    // UDP server is run on the main thread. Servers broadcast their presence here.

    // These are the allowed game versions. HaloMD and Halo PC 1.09 uses 01.00.09.0620, while Halo PC servers on 1.10 use 01.00.10.0621 (these are also joinable).
    let game_versions = [ "01.00.09.0620".to_string(), "01.00.10.0621".to_string() ];

    let mut buffer = [0; 2048];
    loop {
        let (length, source) = match halo_socket.recv_from(&mut buffer) {
            Err(_) => continue,
            Ok((length, source)) => (length,source)
        };
        if length == 0 {
            continue;
        }
        let client_ip = source.to_string().split(":").next().unwrap().to_string();

        if buffer[0] == 3 || buffer[0] == 8 {
            let blacklist_ref = blacklist_udp.lock().unwrap();
            if blacklist_ref.contains(&client_ip) {
                continue;
            }

            // Heartbeat packet.
            if buffer[0] == 3 {

                let mut servers = servers_mut_udp.lock().unwrap();

                let packet = HeartbeatPacket::from_buffer(&buffer, length);

                if packet.localport != 0 && length > 5 && game_versions.contains(&packet.gamever) {
                    let updatetime = time::now().to_timespec().sec;
                    match servers.iter_mut().position(|x| x.ip == client_ip.clone() && x.port == packet.localport) {
                        None => {
                            let serverness = HaloServer { ip:client_ip.clone(), port: packet.localport, last_alive: updatetime };
                            (*servers).push(serverness);
                            continue;
                        }
                        Some(k) => {
                            servers[k].last_alive = updatetime;
                            if packet.statechanged == 2 {
                                servers.remove(k);
                            }
                        }
                    };
                }
            }

            // Keepalive packet. We need to rely on the origin's port for this, unfortunately.
            else if buffer[0] == 8 {
                let mut servers_ref = servers_mut_udp.lock().unwrap();
                let servers = (*servers_ref).iter_mut();

                for i in servers {
                    if i.ip == client_ip && i.port == source.port() {
                        i.last_alive = time::now().to_timespec().sec;
                        break;
                    }
                }
            }
        }
    }
}
<commit_msg>Shutdown heartbeats don't have game version in them<commit_after>// Syntax: master_server [ip address (0.0.0.0 by default)]
// This was created for HaloMD.

// If the server does not respond in at least this many seconds, it will be dropped from the list.
const DROP_TIME : i64 = 60;

// Blacklist for blocking IPs. Separate with newlines.
// Blacklisting IPs ignores heartbeat and keepalive packets from an IP address.
// That means that servers that are banned will not be immediately removed, but will time out, instead.
const BLACKLIST_FILE : &'static str = "blacklist.txt";

// Read the blacklist every x amount of seconds.
const BLACKLIST_UPDATE_TIME : u32 = 60;

// Note: The master server must have TCP 29920 open and UDP 27900 open.

use std::net::{UdpSocket,TcpListener};
use std::io::{Write,BufReader,BufRead};
use std::env;
use std::fs::File;
use std::thread;
use std::sync::{Arc, Mutex};

extern crate time;

mod halo_server;
use halo_server::HaloServer;

mod heartbeat_packet;
use heartbeat_packet::HeartbeatPacket;

fn main() {
    let count = env::args().count();
    let ip = if count == 2 {
        let j : Vec<_> = env::args().collect();
        j[1].to_string()
    }
    else if count == 1 {
        "0.0.0.0".to_string()
    }
    else {
        println!("Only one argument is allowed: the IP to bind to.");
        return;
    };

    // We need to bind on two different ports. If it failed to bind (invalid IP, port is taken), then we must make sure this is known.
    let halo_socket = match UdpSocket::bind((&ip as &str,27900)) {
        Err(_) => {
            println!("Error creating a UDP socket at {}:27900.",ip);
            return;
        },
        Ok(halo_socket) => halo_socket
    };

    let client_socket = match TcpListener::bind((&ip as &str,29920)) {
        Err(_) => {
            println!("Error listening to TCP at {}:29920.",ip);
            return;
        },
        Ok(client_socket) => client_socket
    };

    // Mutex for thread safety.
    let servers_halo: Vec<HaloServer> = Vec::new();
    let servers_mut_udp = Arc::new(Mutex::new(servers_halo));
    let servers_mut_tcp = servers_mut_udp.clone();
    let servers_mut_destruction = servers_mut_udp.clone();

    // Destruction thread. This will remove servers that have not broadcasted their presence in a while.
    thread::spawn(move || {
        loop {
            thread::sleep_ms(10 * 1000);
            let mut servers = servers_mut_destruction.lock().unwrap();
            let timenow = time::now().to_timespec().sec;
            servers.retain(|x| x.last_alive + DROP_TIME > timenow);
        }
    });

    // Blacklist mutex. Concurrency needs to be safe, my friend.
    let blacklist: Vec<String> = Vec::new();
    let blacklist_update = Arc::new(Mutex::new(blacklist));
    let blacklist_udp = blacklist_update.clone();

    // Blacklist read thread.
    thread::spawn(move || {
        loop {
            // Placed in a block so blacklist is unlocked before sleeping to prevent threads from being locked for too long.
            {
                let mut blacklist_ref = blacklist_update.lock().unwrap();
                match File::open(BLACKLIST_FILE) {
                    Ok(file) => {
                        let reader = BufReader::new(&file);
                        match reader.lines().collect() {
                            Err(_) => {
                                blacklist_ref.clear();
                            },
                            Ok(t) => {
                                *blacklist_ref = t;
                            }
                        }
                    },
                    Err(_) => {}
                };
            }
            thread::sleep_ms(BLACKLIST_UPDATE_TIME * 1000);
        }
    });

    // TCP server thread. This is for the HaloMD application.
    thread::spawn(move || {
        loop {
            for stream in client_socket.incoming() {
                let mut client = match stream {
                    Err(_) => continue,
                    Ok(the_stream) => the_stream
                };
                // Unwrap the IP.
                let ip = match client.peer_addr() {
                    Err(_) => continue,
                    Ok(ip) => ip.to_string().split(":").next().unwrap().to_string()
                };

                let mut ips = String::new();

                let servers_ref = servers_mut_tcp.lock().unwrap();
                let servers = (*servers_ref).iter();

                for j in servers {
                    ips = ips + &(j.to_string()) + "\n";
                }

                // Some number placed after the requester's IP. If you ask me, the source code was abducted by aliens, and this is a tracking number. Regardless, it's needed.
                ips = ips + &ip + ":49149:3425";
                let _ = client.write_all(ips.as_bytes());
            }
        }
    });

    // UDP server is run on the main thread. Servers broadcast their presence here.

    // These are the allowed game versions. HaloMD and Halo PC 1.09 uses 01.00.09.0620, while Halo PC servers on 1.10 use 01.00.10.0621 (these are also joinable).
    let game_versions = [ "01.00.09.0620".to_string(), "01.00.10.0621".to_string() ];

    let mut buffer = [0; 2048];
    loop {
        let (length, source) = match halo_socket.recv_from(&mut buffer) {
            Err(_) => continue,
            Ok((length, source)) => (length,source)
        };
        if length == 0 {
            continue;
        }
        let client_ip = source.to_string().split(":").next().unwrap().to_string();

        if buffer[0] == 3 || buffer[0] == 8 {
            let blacklist_ref = blacklist_udp.lock().unwrap();
            if blacklist_ref.contains(&client_ip) {
                continue;
            }

            // Heartbeat packet.
            if buffer[0] == 3 {

                let mut servers = servers_mut_udp.lock().unwrap();

                let packet = HeartbeatPacket::from_buffer(&buffer, length);

                if packet.localport != 0 && length > 1 {
                    let updatetime = time::now().to_timespec().sec;
                    match servers.iter_mut().position(|x| x.ip == client_ip.clone() && x.port == packet.localport) {
                        None => {
                            if game_versions.contains(&packet.gamever) && &packet.gamever == "halor" {
                                let serverness = HaloServer { ip:client_ip.clone(), port: packet.localport, last_alive: updatetime };
                                (*servers).push(serverness);
                            }
                            continue;
                        }
                        Some(k) => {
                            servers[k].last_alive = updatetime;
                            if packet.statechanged == 2 {
                                servers.remove(k);
                            }
                        }
                    };
                }
            }

            // Keepalive packet. We need to rely on the origin's port for this, unfortunately.
            else if buffer[0] == 8 {
                let mut servers_ref = servers_mut_udp.lock().unwrap();
                let servers = (*servers_ref).iter_mut();

                for i in servers {
                    if i.ip == client_ip && i.port == source.port() {
                        i.last_alive = time::now().to_timespec().sec;
                        break;
                    }
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Form extractor

use std::rc::Rc;
use std::{fmt, ops};

use actix_http::{Error, HttpMessage, Payload};
use bytes::BytesMut;
use encoding_rs::{Encoding, UTF_8};
use futures::{Future, Poll, Stream};
use serde::de::DeserializeOwned;

use crate::dev::Decompress;
use crate::error::UrlencodedError;
use crate::extract::FromRequest;
use crate::http::header::CONTENT_LENGTH;
use crate::request::HttpRequest;

#[derive(PartialEq, Eq, PartialOrd, Ord)]
/// Extract typed information from the request's body.
///
/// To extract typed information from request's body, the type `T` must
/// implement the `Deserialize` trait from *serde*.
///
/// [**FormConfig**](struct.FormConfig.html) allows to configure extraction
/// process.
///
/// ## Example
///
/// ```rust
/// # extern crate actix_web;
/// #[macro_use] extern crate serde_derive;
/// use actix_web::{web, App};
///
/// #[derive(Deserialize)]
/// struct FormData {
///     username: String,
/// }
///
/// /// Extract form data using serde.
/// /// This handler get called only if content type is *x-www-form-urlencoded*
/// /// and content of the request could be deserialized to a `FormData` struct
/// fn index(form: web::Form<FormData>) -> String {
///     format!("Welcome {}!", form.username)
/// }
/// # fn main() {}
/// ```
pub struct Form<T>(pub T);

impl<T> Form<T> {
    /// Deconstruct to an inner value
    pub fn into_inner(self) -> T {
        self.0
    }
}

impl<T> ops::Deref for Form<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<T> ops::DerefMut for Form<T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.0
    }
}

impl<T> FromRequest for Form<T>
where
    T: DeserializeOwned + 'static,
{
    type Config = FormConfig;
    type Error = Error;
    type Future = Box<dyn Future<Item = Self, Error = Error>>;

    #[inline]
    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
        let req2 = req.clone();
        let (limit, err) = req
            .app_data::<FormConfig>()
            .map(|c| (c.limit, c.ehandler.clone()))
            .unwrap_or((16384, None));

        Box::new(
            UrlEncoded::new(req, payload)
                .limit(limit)
                .map_err(move |e| {
                    if let Some(err) = err {
                        (*err)(e, &req2)
                    } else {
                        e.into()
                    }
                })
                .map(Form),
        )
    }
}

impl<T: fmt::Debug> fmt::Debug for Form<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<T: fmt::Display> fmt::Display for Form<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// Form extractor configuration
///
/// ```rust
/// #[macro_use] extern crate serde_derive;
/// use actix_web::{web, App, FromRequest, Result};
///
/// #[derive(Deserialize)]
/// struct FormData {
///     username: String,
/// }
///
/// /// Extract form data using serde.
/// /// Custom configuration is used for this handler, max payload size is 4k
/// fn index(form: web::Form<FormData>) -> Result<String> {
///     Ok(format!("Welcome {}!", form.username))
/// }
///
/// fn main() {
///     let app = App::new().service(
///         web::resource("/index.html")
///             // change `Form` extractor configuration
///             .data(
///                 web::Form::<FormData>::configure(|cfg| cfg.limit(4097))
///             )
///             .route(web::get().to(index))
///     );
/// }
/// ```
#[derive(Clone)]
pub struct FormConfig {
    limit: usize,
    ehandler: Option<Rc<dyn Fn(UrlencodedError, &HttpRequest) -> Error>>,
}

impl FormConfig {
    /// Change max size of payload. By default max size is 16Kb
    pub fn limit(mut self, limit: usize) -> Self {
        self.limit = limit;
        self
    }

    /// Set custom error handler
    pub fn error_handler<F>(mut self, f: F) -> Self
    where
        F: Fn(UrlencodedError, &HttpRequest) -> Error + 'static,
    {
        self.ehandler = Some(Rc::new(f));
        self
    }
}

impl Default for FormConfig {
    fn default() -> Self {
        FormConfig {
            limit: 16384,
            ehandler: None,
        }
    }
}

/// Future that resolves to a parsed urlencoded values.
///
/// Parse `application/x-www-form-urlencoded` encoded request's body.
/// Return `UrlEncoded` future. Form can be deserialized to any type that
/// implements `Deserialize` trait from *serde*.
///
/// Returns error:
///
/// * content type is not `application/x-www-form-urlencoded`
/// * content-length is greater than 32k
///
pub struct UrlEncoded<U> {
    stream: Option<Decompress<Payload>>,
    limit: usize,
    length: Option<usize>,
    encoding: &'static Encoding,
    err: Option<UrlencodedError>,
    fut: Option<Box<dyn Future<Item = U, Error = UrlencodedError>>>,
}

impl<U> UrlEncoded<U> {
    /// Create a new future to URL encode a request
    pub fn new(req: &HttpRequest, payload: &mut Payload) -> UrlEncoded<U> {
        // check content type
        if req.content_type().to_lowercase() != "application/x-www-form-urlencoded" {
            return Self::err(UrlencodedError::ContentType);
        }
        let encoding = match req.encoding() {
            Ok(enc) => enc,
            Err(_) => return Self::err(UrlencodedError::ContentType),
        };

        let mut len = None;
        if let Some(l) = req.headers().get(&CONTENT_LENGTH) {
            if let Ok(s) = l.to_str() {
                if let Ok(l) = s.parse::<usize>() {
                    len = Some(l)
                } else {
                    return Self::err(UrlencodedError::UnknownLength);
                }
            } else {
                return Self::err(UrlencodedError::UnknownLength);
            }
        };

        let payload = Decompress::from_headers(payload.take(), req.headers());
        UrlEncoded {
            encoding,
            stream: Some(payload),
            limit: 32_768,
            length: len,
            fut: None,
            err: None,
        }
    }

    fn err(e: UrlencodedError) -> Self {
        UrlEncoded {
            stream: None,
            limit: 32_768,
            fut: None,
            err: Some(e),
            length: None,
            encoding: UTF_8,
        }
    }

    /// Change max size of payload. By default max size is 256Kb
    pub fn limit(mut self, limit: usize) -> Self {
        self.limit = limit;
        self
    }
}

impl<U> Future for UrlEncoded<U>
where
    U: DeserializeOwned + 'static,
{
    type Item = U;
    type Error = UrlencodedError;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        if let Some(ref mut fut) = self.fut {
            return fut.poll();
        }

        if let Some(err) = self.err.take() {
            return Err(err);
        }

        // payload size
        let limit = self.limit;
        if let Some(len) = self.length.take() {
            if len > limit {
                return Err(UrlencodedError::Overflow);
            }
        }

        // future
        let encoding = self.encoding;
        let fut = self
            .stream
            .take()
            .unwrap()
            .from_err()
            .fold(BytesMut::with_capacity(8192), move |mut body, chunk| {
                if (body.len() + chunk.len()) > limit {
                    Err(UrlencodedError::Overflow)
                } else {
                    body.extend_from_slice(&chunk);
                    Ok(body)
                }
            })
            .and_then(move |body| {
                if encoding == UTF_8 {
                    serde_urlencoded::from_bytes::<U>(&body)
                        .map_err(|_| UrlencodedError::Parse)
                } else {
                    let body = encoding
                        .decode_without_bom_handling_and_without_replacement(&body)
                        .map(|s| s.into_owned())
                        .ok_or(UrlencodedError::Parse)?;
                    serde_urlencoded::from_str::<U>(&body)
                        .map_err(|_| UrlencodedError::Parse)
                }
            });
        self.fut = Some(Box::new(fut));
        self.poll()
    }
}

#[cfg(test)]
mod tests {
    use bytes::Bytes;
    use serde::Deserialize;

    use super::*;
    use crate::http::header::CONTENT_TYPE;
    use crate::test::{block_on, TestRequest};

    #[derive(Deserialize, Debug, PartialEq)]
    struct Info {
        hello: String,
    }

    #[test]
    fn test_form() {
        let (req, mut pl) =
            TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
                .header(CONTENT_LENGTH, "11")
                .set_payload(Bytes::from_static(b"hello=world"))
                .to_http_parts();

        let s = block_on(Form::<Info>::from_request(&req, &mut pl)).unwrap();
        assert_eq!(s.hello, "world");
    }

    fn eq(err: UrlencodedError, other: UrlencodedError) -> bool {
        match err {
            UrlencodedError::Overflow => match other {
                UrlencodedError::Overflow => true,
                _ => false,
            },
            UrlencodedError::UnknownLength => match other {
                UrlencodedError::UnknownLength => true,
                _ => false,
            },
            UrlencodedError::ContentType => match other {
                UrlencodedError::ContentType => true,
                _ => false,
            },
            _ => false,
        }
    }

    #[test]
    fn test_urlencoded_error() {
        let (req, mut pl) =
            TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
                .header(CONTENT_LENGTH, "xxxx")
                .to_http_parts();
        let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
        assert!(eq(info.err().unwrap(), UrlencodedError::UnknownLength));

        let (req, mut pl) =
            TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
                .header(CONTENT_LENGTH, "1000000")
                .to_http_parts();
        let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
        assert!(eq(info.err().unwrap(), UrlencodedError::Overflow));

        let (req, mut pl) = TestRequest::with_header(CONTENT_TYPE, "text/plain")
            .header(CONTENT_LENGTH, "10")
            .to_http_parts();
        let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
        assert!(eq(info.err().unwrap(), UrlencodedError::ContentType));
    }

    #[test]
    fn test_urlencoded() {
        let (req, mut pl) =
            TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
                .header(CONTENT_LENGTH, "11")
                .set_payload(Bytes::from_static(b"hello=world"))
                .to_http_parts();

        let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl)).unwrap();
        assert_eq!(
            info,
            Info {
                hello: "world".to_owned()
            }
        );

        let (req, mut pl) = TestRequest::with_header(
            CONTENT_TYPE,
            "application/x-www-form-urlencoded; charset=utf-8",
        )
        .header(CONTENT_LENGTH, "11")
        .set_payload(Bytes::from_static(b"hello=world"))
        .to_http_parts();

        let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl)).unwrap();
        assert_eq!(
            info,
            Info {
                hello: "world".to_owned()
            }
        );
    }
}
<commit_msg>impl Responder for Form<commit_after>//! Form extractor

use std::rc::Rc;
use std::{fmt, ops};

use actix_http::{Error, HttpMessage, Payload, Response};
use bytes::BytesMut;
use encoding_rs::{Encoding, UTF_8};
use futures::{Future, Poll, Stream};
use serde::de::DeserializeOwned;
use serde::Serialize;

use crate::dev::Decompress;
use crate::error::UrlencodedError;
use crate::extract::FromRequest;
use crate::http::{
    header::{ContentType, CONTENT_LENGTH},
    StatusCode,
};
use crate::request::HttpRequest;
use crate::responder::Responder;

/// Form data helper (`application/x-www-form-urlencoded`)
///
/// Can be use to extract url-encoded data from the request body,
/// or send url-encoded data as the response.
///
/// ## Extract
///
/// To extract typed information from request's body, the type `T` must
/// implement the `Deserialize` trait from *serde*.
///
/// [**FormConfig**](struct.FormConfig.html) allows to configure extraction
/// process.
///
/// ### Example
/// ```rust
/// # extern crate actix_web;
/// #[macro_use] extern crate serde_derive;
/// use actix_web::{web, App};
///
/// #[derive(Deserialize)]
/// struct FormData {
///     username: String,
/// }
///
/// /// Extract form data using serde.
/// /// This handler get called only if content type is *x-www-form-urlencoded*
/// /// and content of the request could be deserialized to a `FormData` struct
/// fn index(form: web::Form<FormData>) -> String {
///     format!("Welcome {}!", form.username)
/// }
/// # fn main() {}
/// ```
///
/// ## Respond
///
/// The `Form` type also allows you to respond with well-formed url-encoded data:
/// simply return a value of type Form<T> where T is the type to be url-encoded.
/// The type  must implement `serde::Serialize`;
///
/// ### Example
/// ```rust
/// # #[macro_use] extern crate serde_derive;
/// # use actix_web::*;
/// #
/// #[derive(Serialize)]
/// struct SomeForm {
///     name: String,
///     age: u8
/// }
///
/// // Will return a 200 response with header
/// // `Content-Type: application/x-www-form-urlencoded`
/// // and body "name=actix&age=123"
/// fn index() -> web::Form<SomeForm> {
///     web::Form(SomeForm {
///         name: "actix".into(),
///         age: 123
///     })
/// }
/// # fn main() {}
/// ```
#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub struct Form<T>(pub T);

impl<T> Form<T> {
    /// Deconstruct to an inner value
    pub fn into_inner(self) -> T {
        self.0
    }
}

impl<T> ops::Deref for Form<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<T> ops::DerefMut for Form<T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.0
    }
}

impl<T> FromRequest for Form<T>
where
    T: DeserializeOwned + 'static,
{
    type Config = FormConfig;
    type Error = Error;
    type Future = Box<dyn Future<Item = Self, Error = Error>>;

    #[inline]
    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
        let req2 = req.clone();
        let (limit, err) = req
            .app_data::<FormConfig>()
            .map(|c| (c.limit, c.ehandler.clone()))
            .unwrap_or((16384, None));

        Box::new(
            UrlEncoded::new(req, payload)
                .limit(limit)
                .map_err(move |e| {
                    if let Some(err) = err {
                        (*err)(e, &req2)
                    } else {
                        e.into()
                    }
                })
                .map(Form),
        )
    }
}

impl<T: fmt::Debug> fmt::Debug for Form<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<T: fmt::Display> fmt::Display for Form<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<T: Serialize> Responder for Form<T> {
    type Error = Error;
    type Future = Result<Response, Error>;

    fn respond_to(self, _: &HttpRequest) -> Self::Future {
        let body = match serde_urlencoded::to_string(&self.0) {
            Ok(body) => body,
            Err(e) => return Err(e.into()),
        };

        Ok(Response::build(StatusCode::OK)
            .set(ContentType::form_url_encoded())
            .body(body))
    }
}

/// Form extractor configuration
///
/// ```rust
/// #[macro_use] extern crate serde_derive;
/// use actix_web::{web, App, FromRequest, Result};
///
/// #[derive(Deserialize)]
/// struct FormData {
///     username: String,
/// }
///
/// /// Extract form data using serde.
/// /// Custom configuration is used for this handler, max payload size is 4k
/// fn index(form: web::Form<FormData>) -> Result<String> {
///     Ok(format!("Welcome {}!", form.username))
/// }
///
/// fn main() {
///     let app = App::new().service(
///         web::resource("/index.html")
///             // change `Form` extractor configuration
///             .data(
///                 web::Form::<FormData>::configure(|cfg| cfg.limit(4097))
///             )
///             .route(web::get().to(index))
///     );
/// }
/// ```
#[derive(Clone)]
pub struct FormConfig {
    limit: usize,
    ehandler: Option<Rc<dyn Fn(UrlencodedError, &HttpRequest) -> Error>>,
}

impl FormConfig {
    /// Change max size of payload. By default max size is 16Kb
    pub fn limit(mut self, limit: usize) -> Self {
        self.limit = limit;
        self
    }

    /// Set custom error handler
    pub fn error_handler<F>(mut self, f: F) -> Self
    where
        F: Fn(UrlencodedError, &HttpRequest) -> Error + 'static,
    {
        self.ehandler = Some(Rc::new(f));
        self
    }
}

impl Default for FormConfig {
    fn default() -> Self {
        FormConfig {
            limit: 16384,
            ehandler: None,
        }
    }
}

/// Future that resolves to a parsed urlencoded values.
///
/// Parse `application/x-www-form-urlencoded` encoded request's body.
/// Return `UrlEncoded` future. Form can be deserialized to any type that
/// implements `Deserialize` trait from *serde*.
///
/// Returns error:
///
/// * content type is not `application/x-www-form-urlencoded`
/// * content-length is greater than 32k
///
pub struct UrlEncoded<U> {
    stream: Option<Decompress<Payload>>,
    limit: usize,
    length: Option<usize>,
    encoding: &'static Encoding,
    err: Option<UrlencodedError>,
    fut: Option<Box<dyn Future<Item = U, Error = UrlencodedError>>>,
}

impl<U> UrlEncoded<U> {
    /// Create a new future to URL encode a request
    pub fn new(req: &HttpRequest, payload: &mut Payload) -> UrlEncoded<U> {
        // check content type
        if req.content_type().to_lowercase() != "application/x-www-form-urlencoded" {
            return Self::err(UrlencodedError::ContentType);
        }
        let encoding = match req.encoding() {
            Ok(enc) => enc,
            Err(_) => return Self::err(UrlencodedError::ContentType),
        };

        let mut len = None;
        if let Some(l) = req.headers().get(&CONTENT_LENGTH) {
            if let Ok(s) = l.to_str() {
                if let Ok(l) = s.parse::<usize>() {
                    len = Some(l)
                } else {
                    return Self::err(UrlencodedError::UnknownLength);
                }
            } else {
                return Self::err(UrlencodedError::UnknownLength);
            }
        };

        let payload = Decompress::from_headers(payload.take(), req.headers());
        UrlEncoded {
            encoding,
            stream: Some(payload),
            limit: 32_768,
            length: len,
            fut: None,
            err: None,
        }
    }

    fn err(e: UrlencodedError) -> Self {
        UrlEncoded {
            stream: None,
            limit: 32_768,
            fut: None,
            err: Some(e),
            length: None,
            encoding: UTF_8,
        }
    }

    /// Change max size of payload. By default max size is 256Kb
    pub fn limit(mut self, limit: usize) -> Self {
        self.limit = limit;
        self
    }
}

impl<U> Future for UrlEncoded<U>
where
    U: DeserializeOwned + 'static,
{
    type Item = U;
    type Error = UrlencodedError;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        if let Some(ref mut fut) = self.fut {
            return fut.poll();
        }

        if let Some(err) = self.err.take() {
            return Err(err);
        }

        // payload size
        let limit = self.limit;
        if let Some(len) = self.length.take() {
            if len > limit {
                return Err(UrlencodedError::Overflow);
            }
        }

        // future
        let encoding = self.encoding;
        let fut = self
            .stream
            .take()
            .unwrap()
            .from_err()
            .fold(BytesMut::with_capacity(8192), move |mut body, chunk| {
                if (body.len() + chunk.len()) > limit {
                    Err(UrlencodedError::Overflow)
                } else {
                    body.extend_from_slice(&chunk);
                    Ok(body)
                }
            })
            .and_then(move |body| {
                if encoding == UTF_8 {
                    serde_urlencoded::from_bytes::<U>(&body)
                        .map_err(|_| UrlencodedError::Parse)
                } else {
                    let body = encoding
                        .decode_without_bom_handling_and_without_replacement(&body)
                        .map(|s| s.into_owned())
                        .ok_or(UrlencodedError::Parse)?;
                    serde_urlencoded::from_str::<U>(&body)
                        .map_err(|_| UrlencodedError::Parse)
                }
            });
        self.fut = Some(Box::new(fut));
        self.poll()
    }
}

#[cfg(test)]
mod tests {
    use bytes::Bytes;
    use serde::{Deserialize, Serialize};

    use super::*;
    use crate::http::header::{HeaderValue, CONTENT_TYPE};
    use crate::test::{block_on, TestRequest};

    #[derive(Deserialize, Serialize, Debug, PartialEq)]
    struct Info {
        hello: String,
        counter: i64,
    }

    #[test]
    fn test_form() {
        let (req, mut pl) =
            TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
                .header(CONTENT_LENGTH, "11")
                .set_payload(Bytes::from_static(b"hello=world&counter=123"))
                .to_http_parts();

        let Form(s) = block_on(Form::<Info>::from_request(&req, &mut pl)).unwrap();
        assert_eq!(
            s,
            Info {
                hello: "world".into(),
                counter: 123
            }
        );
    }

    fn eq(err: UrlencodedError, other: UrlencodedError) -> bool {
        match err {
            UrlencodedError::Overflow => match other {
                UrlencodedError::Overflow => true,
                _ => false,
            },
            UrlencodedError::UnknownLength => match other {
                UrlencodedError::UnknownLength => true,
                _ => false,
            },
            UrlencodedError::ContentType => match other {
                UrlencodedError::ContentType => true,
                _ => false,
            },
            _ => false,
        }
    }

    #[test]
    fn test_urlencoded_error() {
        let (req, mut pl) =
            TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
                .header(CONTENT_LENGTH, "xxxx")
                .to_http_parts();
        let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
        assert!(eq(info.err().unwrap(), UrlencodedError::UnknownLength));

        let (req, mut pl) =
            TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
                .header(CONTENT_LENGTH, "1000000")
                .to_http_parts();
        let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
        assert!(eq(info.err().unwrap(), UrlencodedError::Overflow));

        let (req, mut pl) = TestRequest::with_header(CONTENT_TYPE, "text/plain")
            .header(CONTENT_LENGTH, "10")
            .to_http_parts();
        let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
        assert!(eq(info.err().unwrap(), UrlencodedError::ContentType));
    }

    #[test]
    fn test_urlencoded() {
        let (req, mut pl) =
            TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
                .header(CONTENT_LENGTH, "11")
                .set_payload(Bytes::from_static(b"hello=world&counter=123"))
                .to_http_parts();

        let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl)).unwrap();
        assert_eq!(
            info,
            Info {
                hello: "world".to_owned(),
                counter: 123
            }
        );

        let (req, mut pl) = TestRequest::with_header(
            CONTENT_TYPE,
            "application/x-www-form-urlencoded; charset=utf-8",
        )
        .header(CONTENT_LENGTH, "11")
        .set_payload(Bytes::from_static(b"hello=world&counter=123"))
        .to_http_parts();

        let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl)).unwrap();
        assert_eq!(
            info,
            Info {
                hello: "world".to_owned(),
                counter: 123
            }
        );
    }

    #[test]
    fn test_responder() {
        let req = TestRequest::default().to_http_request();

        let form = Form(Info {
            hello: "world".to_string(),
            counter: 123,
        });
        let resp = form.respond_to(&req).unwrap();
        assert_eq!(resp.status(), StatusCode::OK);
        assert_eq!(
            resp.headers().get(CONTENT_TYPE).unwrap(),
            HeaderValue::from_static("application/x-www-form-urlencoded")
        );

        use crate::responder::tests::BodyTest;
        assert_eq!(resp.body().bin_ref(), b"hello=world&counter=123");
    }

}
<|endoftext|>


<commit_before>use std::iter::Iterator;
use parser::Parser;

pub use self::UserReply::{
   TakeFile,
   MoveToTrash,
   ShowDiff,
   ShowDiffWith,
   ShowDiffBetween,
   Skip,
   Quit,
   Help
};

pub type FileNum = uint;

#[deriving(Show, PartialEq, Eq)]
pub enum UserReply
{
   TakeFile(FileNum),
   MoveToTrash,
   ShowDiff,
   ShowDiffWith(FileNum),
   ShowDiffBetween(FileNum, FileNum),
   Skip,
   Quit,
   Help
}

pub fn parse(input: &String, num_conf_files: uint) -> Option<UserReply>
{
   if input.is_empty() || num_conf_files == 0 {
      return None;
   }

   let lowercase_input: String = input.chars()
                                      .map(|c| c.to_lowercase())
                                      .collect();

   let mut parser = Parser::new(lowercase_input.as_slice());
   parser.skip_whitespace();
   match parser.take_char() {
      Err(..) => None,

      Ok(c)   => {
         parser.skip_whitespace();
         let nothing_left = parser.eof();
         let uints = take_uints(&mut parser);
         match c {
            't' => {
               match uints.len() {
                  1 if valid_file_num(uints[0], num_conf_files)
                  => Some(TakeFile(uints[0])),

                  _ => None
               }
            }

            'd' => {
               match uints.len() {
                  0 => Some(ShowDiff),

                  1 if valid_file_num(uints[0], num_conf_files)
                  => Some(ShowDiffWith(uints[0])),

                  2 if valid_file_num(uints[0], num_conf_files) && valid_file_num(uints[1], num_conf_files)
                  => Some(ShowDiffBetween(uints[0], uints[1])),

                  _ => None
               }
            }

            'm'      if nothing_left => Some(MoveToTrash),
            's'      if nothing_left => Some(Skip),
            'q'      if nothing_left => Some(Quit),
            'h' |'?' if nothing_left => Some(Help),

            _ => None,
         }
      }
   }
}

fn valid_file_num(file_num: uint, num_confs: uint) -> bool
{
   file_num > 0 && file_num <= num_confs
}

fn take_uints(parser: &mut Parser) -> Vec<uint>
{
   let mut uints  = Vec::new();
   while ! parser.eof() {
      parser.skip_whitespace();
      match parser.take_uint() {
         Ok(uint) => uints.push(uint),
         Err(..)  => break
      }
   }

   uints
}

#[test]
fn tests()
{
   test_str("t"       , None);
   test_str("t1"      , Some(TakeFile(1)));
   test_str(" t1"     , Some(TakeFile(1)));
   test_str(" t  1"   , Some(TakeFile(1)));
   test_str(" t  1  " , Some(TakeFile(1)));
   test_str(" t  1  2", None);
   test_str("d12"     , Some(ShowDiffWith(12)));
   test_str("d13"     , None);
   test_str("d"       , Some(ShowDiff));
   test_str("d1 2"    , Some(ShowDiffBetween(1, 2)));
   test_str("d1    2" , Some(ShowDiffBetween(1, 2)));
   test_str("d  1  2" , Some(ShowDiffBetween(1, 2)));
   test_str("D  1  2" , Some(ShowDiffBetween(1, 2)));
   test_str("  m  "   , Some(MoveToTrash));
   test_str("m  "     , Some(MoveToTrash));
   test_str("M  "     , Some(MoveToTrash));
   test_str("M  1"    , None);
   test_str("s"       , Some(Skip));
   test_str("q"       , Some(Quit));
   test_str("qq"      , None);
   test_str("h"       , Some(Help));
   test_str("?"       , Some(Help));
}

#[cfg(test)]
fn test_str(input: &str, reply: Option<UserReply>)
{
   println!("test: {}", input);
   assert_eq!(parse(&input.to_string(), 12), reply);
}
<commit_msg>Fix handling of show diff case<commit_after>use std::iter::Iterator;
use parser::Parser;

pub use self::UserReply::{
   TakeFile,
   MoveToTrash,
   ShowDiff,
   ShowDiffWith,
   ShowDiffBetween,
   Skip,
   Quit,
   Help
};

pub type FileNum = uint;

#[deriving(Show, PartialEq, Eq)]
pub enum UserReply
{
   TakeFile(FileNum),
   MoveToTrash,
   ShowDiff,
   ShowDiffWith(FileNum),
   ShowDiffBetween(FileNum, FileNum),
   Skip,
   Quit,
   Help
}

pub fn parse(input: &String, num_conf_files: uint) -> Option<UserReply>
{
   if input.is_empty() || num_conf_files == 0 {
      return None;
   }

   let lowercase_input: String = input.chars()
                                      .map(|c| c.to_lowercase())
                                      .collect();

   let mut parser = Parser::new(lowercase_input.as_slice());
   parser.skip_whitespace();
   match parser.take_char() {
      Err(..) => None,

      Ok(c)   => {
         parser.skip_whitespace();
         let nothing_left = parser.eof();
         let uints = take_uints(&mut parser);
         match c {
            't' => {
               match uints.len() {
                  1 if valid_file_num(uints[0], num_conf_files)
                  => Some(TakeFile(uints[0])),

                  _ => None
               }
            }

            'd' => {
               match uints.len() {
                  0 if num_conf_files == 1
                  => Some(ShowDiff),

                  1 if valid_file_num(uints[0], num_conf_files)
                  => Some(ShowDiffWith(uints[0])),

                  2 if valid_file_num(uints[0], num_conf_files) && valid_file_num(uints[1], num_conf_files)
                  => Some(ShowDiffBetween(uints[0], uints[1])),

                  _ => None
               }
            }

            'm'      if nothing_left => Some(MoveToTrash),
            's'      if nothing_left => Some(Skip),
            'q'      if nothing_left => Some(Quit),
            'h' |'?' if nothing_left => Some(Help),

            _ => None,
         }
      }
   }
}

fn valid_file_num(file_num: uint, num_confs: uint) -> bool
{
   file_num > 0 && file_num <= num_confs
}

fn take_uints(parser: &mut Parser) -> Vec<uint>
{
   let mut uints  = Vec::new();
   while ! parser.eof() {
      parser.skip_whitespace();
      match parser.take_uint() {
         Ok(uint) => uints.push(uint),
         Err(..)  => break
      }
   }

   uints
}

#[test]
fn tests()
{
   test_str("t"       , None);
   test_str("t1"      , Some(TakeFile(1)));
   test_str(" t1"     , Some(TakeFile(1)));
   test_str(" t  1"   , Some(TakeFile(1)));
   test_str(" t  1  " , Some(TakeFile(1)));
   test_str(" t  1  2", None);
   test_str("d12"     , Some(ShowDiffWith(12)));
   test_str("d13"     , None);
   test_str("d"       , None);
   test_str("d1 2"    , Some(ShowDiffBetween(1, 2)));
   test_str("d1    2" , Some(ShowDiffBetween(1, 2)));
   test_str("d  1  2" , Some(ShowDiffBetween(1, 2)));
   test_str("D  1  2" , Some(ShowDiffBetween(1, 2)));
   test_str("  m  "   , Some(MoveToTrash));
   test_str("m  "     , Some(MoveToTrash));
   test_str("M  "     , Some(MoveToTrash));
   test_str("M  1"    , None);
   test_str("s"       , Some(Skip));
   test_str("q"       , Some(Quit));
   test_str("qq"      , None);
   test_str("h"       , Some(Help));
   test_str("?"       , Some(Help));
}

#[cfg(test)]
fn test_str(input: &str, reply: Option<UserReply>)
{
   println!("test: {}", input);
   assert_eq!(parse(&input.to_string(), 12), reply);
}
<|endoftext|>