<commit_before>extern crate libc;
extern crate glib;

use std::f64;

use self::glib::translate::*;

use strtod::*;
use drawing_ctx;
use drawing_ctx::RsvgDrawingCtx;

/* Keep this in sync with ../../rsvg-private.h:LengthUnit */
#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum LengthUnit {
    Default,
    Percent,
    FontEm,
    FontEx,
    Inch,
    RelativeLarger,
    RelativeSmaller
}

/* Keep this in sync with ../../rsvg-private.h:LengthDir */
#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum LengthDir {
    Horizontal,
    Vertical,
    Both
}

/* This is *not* an opaque struct; it is actually visible to the C code.  It is so
 * that the remaining C code can create RsvgLength values as part of existing
 * structures or objects, without allocations on the heap.
 */
/* Keep this in sync with ../../rsvg-private.h:RsvgLength */
#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub struct RsvgLength {
    length: f64,
    unit: LengthUnit,
    dir: LengthDir
}

const POINTS_PER_INCH: f64 = 72.0;
const CM_PER_INCH:     f64 = 2.54;
const MM_PER_INCH:     f64 = 25.4;
const PICA_PER_INCH:   f64 = 6.0;

fn compute_named_size (name: &str) -> f64 {
    let power: f64;

    match name {
        "xx-small" => { power = -3.0; },
        "x-small"  => { power = -2.0; },
        "small"    => { power = -1.0; },
        "medium"   => { power = 0.0; },
        "large"    => { power = 1.0; },
        "x-large"  => { power = 2.0; },
        "xx-large" => { power = 3.0; },
        _          => { return 0.0; }
    }

    12.0 * 1.2f64.powf (power) / POINTS_PER_INCH
}

#[no_mangle]
pub extern fn rsvg_length_parse (string: *const libc::c_char, dir: LengthDir) -> RsvgLength {
    let my_string = unsafe { &String::from_glib_none (string) };

    RsvgLength::parse (my_string, dir)
}

/* https://www.w3.org/TR/SVG/types.html#DataTypeLength
 * https://www.w3.org/TR/2008/REC-CSS2-20080411/syndata.html#length-units
 *
 * Lengths have units.  When they need to be need resolved to
 * units in the user's coordinate system, some unit types
 * need to know if they are horizontal/vertical/both.  For example,
 * a some_object.width="50%" is 50% with respect to the current
 * viewport's width.  In this case, the @dir argument is used
 * inside RsvgLength::normalize(), when it needs to know to what the
 * length refers.
 */
impl RsvgLength {
    pub fn parse (string: &str, dir: LengthDir) -> RsvgLength {
        let unit: LengthUnit;

        let (mut value, rest) = strtod (string);

        match rest.as_ref () {
            "%" => {
                value *= 0.01; // normalize to [0, 1]
                unit = LengthUnit::Percent;
            },

            "em" => {
                unit = LengthUnit::FontEm;
            },

            "ex" => {
                unit = LengthUnit::FontEx;
            },

            "pt" => {
                value /= POINTS_PER_INCH;
                unit = LengthUnit::Inch;
            },

            "in" => {
                unit = LengthUnit::Inch;
            },

            "cm" => {
                value /= CM_PER_INCH;
                unit = LengthUnit::Inch;
            },

            "mm" => {
                value /= MM_PER_INCH;
                unit = LengthUnit::Inch;
            },

            "pc" => {
                value /= PICA_PER_INCH;
                unit = LengthUnit::Inch;
            },

            "larger" => {
                unit = LengthUnit::RelativeLarger;
            },

            "smaller" => {
                unit = LengthUnit::RelativeSmaller;
            },

            "xx-small" |
            "x-small" |
            "small" |
            "medium" |
            "large" |
            "x-large" |
            "xx-large" => {
                value = compute_named_size (rest);
                unit = LengthUnit::Inch;
            },

            _ => {
                unit = LengthUnit::Default;
            }
        }

        RsvgLength {
            length: value,
            unit: unit,
            dir: dir
        }
    }

    pub fn normalize (&self, draw_ctx: *const RsvgDrawingCtx) -> f64 {
        match self.unit {
            LengthUnit::Default => {
                self.length
            },

            LengthUnit::Percent => {
                let (width, height) = drawing_ctx::get_view_box_size (draw_ctx);

                match self.dir {
                    LengthDir::Horizontal => { self.length * width },
                    LengthDir::Vertical   => { self.length * height },
                    LengthDir::Both       => { self.length * viewport_percentage (width, height) }
                }
            },

            LengthUnit::FontEm => {
                self.length * drawing_ctx::get_normalized_font_size (draw_ctx)
            },

            LengthUnit::FontEx => {
                self.length * drawing_ctx::get_normalized_font_size (draw_ctx) / 2.0
            },

            LengthUnit::Inch => {
                let (dpi_x, dpi_y) = drawing_ctx::get_dpi (draw_ctx);

                match self.dir {
                    LengthDir::Horizontal => { self.length * dpi_x },
                    LengthDir::Vertical   => { self.length * dpi_y },
                    LengthDir::Both       => { self.length * viewport_percentage (dpi_x, dpi_y) }
                }
            },

            // FIXME: these are pending: https://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#propdef-font-size
            LengthUnit::RelativeLarger |
            LengthUnit::RelativeSmaller => { 0.0 }
        }
    }

    pub fn hand_normalize (&self,
                           pixels_per_inch: f64,
                           width_or_height: f64,
                           font_size: f64) -> f64 {
        match self.unit {
            LengthUnit::Default => { self.length },

            LengthUnit::Percent => { self.length * width_or_height },

            LengthUnit::FontEm => { self.length * font_size },

            LengthUnit::FontEx => { self.length * font_size / 2.0 },

            LengthUnit::Inch => { self.length * pixels_per_inch },

            _ => { 0.0 }
        }
    }
}

fn viewport_percentage (x: f64, y: f64) -> f64 {
    /* https://www.w3.org/TR/SVG/coords.html#Units
     *
     * "For any other length value expressed as a percentage of the viewport, the
     * percentage is calculated as the specified percentage of
     * sqrt((actual-width)**2 + (actual-height)**2))/sqrt(2)."
     */
    return (x * x + y * y).sqrt () / f64::consts::SQRT_2;
}

#[no_mangle]
pub extern fn rsvg_length_normalize (raw_length: *const RsvgLength, draw_ctx: *const RsvgDrawingCtx) -> f64 {
    assert! (!raw_length.is_null ());

    let length: &RsvgLength = unsafe { &*raw_length };

    length.normalize (draw_ctx)
}

#[no_mangle]
pub extern fn rsvg_length_hand_normalize (raw_length: *const RsvgLength,
                                          pixels_per_inch: f64,
                                          width_or_height: f64,
                                          font_size: f64) -> f64 {
    assert! (!raw_length.is_null ());

    let length: &RsvgLength = unsafe { &*raw_length };

    length.hand_normalize (pixels_per_inch, width_or_height, font_size)
}

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

    #[test]
    fn parses_default () {
        assert_eq! (RsvgLength::parse ("42", LengthDir::Horizontal),
                    RsvgLength {
                        length: 42.0,
                        unit:   LengthUnit::Default,
                        dir:    LengthDir::Horizontal});

        assert_eq! (RsvgLength::parse ("-42px", LengthDir::Horizontal),
                    RsvgLength {
                        length: -42.0,
                        unit:   LengthUnit::Default,
                        dir:    LengthDir::Horizontal});
    }

    #[test]
    fn parses_percent () {
        assert_eq! (RsvgLength::parse ("50.0%", LengthDir::Horizontal),
                    RsvgLength {
                        length: 0.5,
                        unit:   LengthUnit::Percent,
                        dir:    LengthDir::Horizontal});
    }

    #[test]
    fn parses_font_em () {
        assert_eq! (RsvgLength::parse ("22.5em", LengthDir::Vertical),
                    RsvgLength {
                        length: 22.5,
                        unit:   LengthUnit::FontEm,
                        dir:    LengthDir::Vertical });
    }

    #[test]
    fn parses_font_ex () {
        assert_eq! (RsvgLength::parse ("22.5ex", LengthDir::Vertical),
                    RsvgLength {
                        length: 22.5,
                        unit:   LengthUnit::FontEx,
                        dir:    LengthDir::Vertical });
    }

    #[test]
    fn parses_physical_units () {
        assert_eq! (RsvgLength::parse ("72pt", LengthDir::Both),
                    RsvgLength {
                        length: 1.0,
                        unit:   LengthUnit::Inch,
                        dir:    LengthDir::Both });

        assert_eq! (RsvgLength::parse ("-22.5in", LengthDir::Both),
                    RsvgLength {
                        length: -22.5,
                        unit:   LengthUnit::Inch,
                        dir:    LengthDir::Both });

        assert_eq! (RsvgLength::parse ("-25.4cm", LengthDir::Both),
                    RsvgLength {
                        length: -10.0,
                        unit:   LengthUnit::Inch,
                        dir:    LengthDir::Both });

        assert_eq! (RsvgLength::parse ("254mm", LengthDir::Both),
                    RsvgLength {
                        length: 10.0,
                        unit:   LengthUnit::Inch,
                        dir:    LengthDir::Both });

        assert_eq! (RsvgLength::parse ("60pc", LengthDir::Both),
                    RsvgLength {
                        length: 10.0,
                        unit:   LengthUnit::Inch,
                        dir:    LengthDir::Both });
    }

    #[test]
    fn parses_relative_larger () {
        assert_eq! (RsvgLength::parse ("larger", LengthDir::Vertical),
                    RsvgLength {
                        length: 0.0,
                        unit:   LengthUnit::RelativeLarger,
                        dir:    LengthDir::Vertical });
    }

    #[test]
    fn parses_relative_smaller () {
        assert_eq! (RsvgLength::parse ("smaller", LengthDir::Vertical),
                    RsvgLength {
                        length: 0.0,
                        unit:   LengthUnit::RelativeSmaller,
                        dir:    LengthDir::Vertical });
    }

    #[test]
    fn parses_named_sizes () {
        let names = vec![ "xx-small",
                           "x-small",
                           "small",
                           "medium",
                           "large",
                           "x-large",
                           "xx-large" ];

        let mut previous_value: Option<f64> = None;

        // Just ensure that the values are progressively larger; don't
        // enforce a particular sequence.

        for name in names {
            let length = RsvgLength::parse (name, LengthDir::Both);

            assert_eq! (length.unit, LengthUnit::Inch);
            assert_eq! (length.dir, LengthDir::Both);

            if let Some (v) = previous_value {
                assert! (length.length > v);
            } else {
                previous_value = Some (length.length);
            }

        }

    }
}
<commit_msg>length.rs: Implement trait Default for RsvgLength<commit_after>extern crate libc;
extern crate glib;

use std::f64;

use self::glib::translate::*;

use strtod::*;
use drawing_ctx;
use drawing_ctx::RsvgDrawingCtx;

/* Keep this in sync with ../../rsvg-private.h:LengthUnit */
#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum LengthUnit {
    Default,
    Percent,
    FontEm,
    FontEx,
    Inch,
    RelativeLarger,
    RelativeSmaller
}

/* Keep this in sync with ../../rsvg-private.h:LengthDir */
#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum LengthDir {
    Horizontal,
    Vertical,
    Both
}

/* This is *not* an opaque struct; it is actually visible to the C code.  It is so
 * that the remaining C code can create RsvgLength values as part of existing
 * structures or objects, without allocations on the heap.
 */
/* Keep this in sync with ../../rsvg-private.h:RsvgLength */
#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub struct RsvgLength {
    length: f64,
    unit: LengthUnit,
    dir: LengthDir
}

impl Default for RsvgLength {
    fn default () -> RsvgLength {
        RsvgLength {
            length: 0.0,
            unit:   LengthUnit::Default,
            dir:    LengthDir::Both
        }
    }
}

const POINTS_PER_INCH: f64 = 72.0;
const CM_PER_INCH:     f64 = 2.54;
const MM_PER_INCH:     f64 = 25.4;
const PICA_PER_INCH:   f64 = 6.0;

fn compute_named_size (name: &str) -> f64 {
    let power: f64;

    match name {
        "xx-small" => { power = -3.0; },
        "x-small"  => { power = -2.0; },
        "small"    => { power = -1.0; },
        "medium"   => { power = 0.0; },
        "large"    => { power = 1.0; },
        "x-large"  => { power = 2.0; },
        "xx-large" => { power = 3.0; },
        _          => { return 0.0; }
    }

    12.0 * 1.2f64.powf (power) / POINTS_PER_INCH
}

#[no_mangle]
pub extern fn rsvg_length_parse (string: *const libc::c_char, dir: LengthDir) -> RsvgLength {
    let my_string = unsafe { &String::from_glib_none (string) };

    RsvgLength::parse (my_string, dir)
}

/* https://www.w3.org/TR/SVG/types.html#DataTypeLength
 * https://www.w3.org/TR/2008/REC-CSS2-20080411/syndata.html#length-units
 *
 * Lengths have units.  When they need to be need resolved to
 * units in the user's coordinate system, some unit types
 * need to know if they are horizontal/vertical/both.  For example,
 * a some_object.width="50%" is 50% with respect to the current
 * viewport's width.  In this case, the @dir argument is used
 * inside RsvgLength::normalize(), when it needs to know to what the
 * length refers.
 */
impl RsvgLength {
    pub fn parse (string: &str, dir: LengthDir) -> RsvgLength {
        let unit: LengthUnit;

        let (mut value, rest) = strtod (string);

        match rest.as_ref () {
            "%" => {
                value *= 0.01; // normalize to [0, 1]
                unit = LengthUnit::Percent;
            },

            "em" => {
                unit = LengthUnit::FontEm;
            },

            "ex" => {
                unit = LengthUnit::FontEx;
            },

            "pt" => {
                value /= POINTS_PER_INCH;
                unit = LengthUnit::Inch;
            },

            "in" => {
                unit = LengthUnit::Inch;
            },

            "cm" => {
                value /= CM_PER_INCH;
                unit = LengthUnit::Inch;
            },

            "mm" => {
                value /= MM_PER_INCH;
                unit = LengthUnit::Inch;
            },

            "pc" => {
                value /= PICA_PER_INCH;
                unit = LengthUnit::Inch;
            },

            "larger" => {
                unit = LengthUnit::RelativeLarger;
            },

            "smaller" => {
                unit = LengthUnit::RelativeSmaller;
            },

            "xx-small" |
            "x-small" |
            "small" |
            "medium" |
            "large" |
            "x-large" |
            "xx-large" => {
                value = compute_named_size (rest);
                unit = LengthUnit::Inch;
            },

            _ => {
                unit = LengthUnit::Default;
            }
        }

        RsvgLength {
            length: value,
            unit: unit,
            dir: dir
        }
    }

    pub fn normalize (&self, draw_ctx: *const RsvgDrawingCtx) -> f64 {
        match self.unit {
            LengthUnit::Default => {
                self.length
            },

            LengthUnit::Percent => {
                let (width, height) = drawing_ctx::get_view_box_size (draw_ctx);

                match self.dir {
                    LengthDir::Horizontal => { self.length * width },
                    LengthDir::Vertical   => { self.length * height },
                    LengthDir::Both       => { self.length * viewport_percentage (width, height) }
                }
            },

            LengthUnit::FontEm => {
                self.length * drawing_ctx::get_normalized_font_size (draw_ctx)
            },

            LengthUnit::FontEx => {
                self.length * drawing_ctx::get_normalized_font_size (draw_ctx) / 2.0
            },

            LengthUnit::Inch => {
                let (dpi_x, dpi_y) = drawing_ctx::get_dpi (draw_ctx);

                match self.dir {
                    LengthDir::Horizontal => { self.length * dpi_x },
                    LengthDir::Vertical   => { self.length * dpi_y },
                    LengthDir::Both       => { self.length * viewport_percentage (dpi_x, dpi_y) }
                }
            },

            // FIXME: these are pending: https://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#propdef-font-size
            LengthUnit::RelativeLarger |
            LengthUnit::RelativeSmaller => { 0.0 }
        }
    }

    pub fn hand_normalize (&self,
                           pixels_per_inch: f64,
                           width_or_height: f64,
                           font_size: f64) -> f64 {
        match self.unit {
            LengthUnit::Default => { self.length },

            LengthUnit::Percent => { self.length * width_or_height },

            LengthUnit::FontEm => { self.length * font_size },

            LengthUnit::FontEx => { self.length * font_size / 2.0 },

            LengthUnit::Inch => { self.length * pixels_per_inch },

            _ => { 0.0 }
        }
    }
}

fn viewport_percentage (x: f64, y: f64) -> f64 {
    /* https://www.w3.org/TR/SVG/coords.html#Units
     *
     * "For any other length value expressed as a percentage of the viewport, the
     * percentage is calculated as the specified percentage of
     * sqrt((actual-width)**2 + (actual-height)**2))/sqrt(2)."
     */
    return (x * x + y * y).sqrt () / f64::consts::SQRT_2;
}

#[no_mangle]
pub extern fn rsvg_length_normalize (raw_length: *const RsvgLength, draw_ctx: *const RsvgDrawingCtx) -> f64 {
    assert! (!raw_length.is_null ());

    let length: &RsvgLength = unsafe { &*raw_length };

    length.normalize (draw_ctx)
}

#[no_mangle]
pub extern fn rsvg_length_hand_normalize (raw_length: *const RsvgLength,
                                          pixels_per_inch: f64,
                                          width_or_height: f64,
                                          font_size: f64) -> f64 {
    assert! (!raw_length.is_null ());

    let length: &RsvgLength = unsafe { &*raw_length };

    length.hand_normalize (pixels_per_inch, width_or_height, font_size)
}

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

    #[test]
    fn parses_default () {
        assert_eq! (RsvgLength::parse ("42", LengthDir::Horizontal),
                    RsvgLength {
                        length: 42.0,
                        unit:   LengthUnit::Default,
                        dir:    LengthDir::Horizontal});

        assert_eq! (RsvgLength::parse ("-42px", LengthDir::Horizontal),
                    RsvgLength {
                        length: -42.0,
                        unit:   LengthUnit::Default,
                        dir:    LengthDir::Horizontal});
    }

    #[test]
    fn parses_percent () {
        assert_eq! (RsvgLength::parse ("50.0%", LengthDir::Horizontal),
                    RsvgLength {
                        length: 0.5,
                        unit:   LengthUnit::Percent,
                        dir:    LengthDir::Horizontal});
    }

    #[test]
    fn parses_font_em () {
        assert_eq! (RsvgLength::parse ("22.5em", LengthDir::Vertical),
                    RsvgLength {
                        length: 22.5,
                        unit:   LengthUnit::FontEm,
                        dir:    LengthDir::Vertical });
    }

    #[test]
    fn parses_font_ex () {
        assert_eq! (RsvgLength::parse ("22.5ex", LengthDir::Vertical),
                    RsvgLength {
                        length: 22.5,
                        unit:   LengthUnit::FontEx,
                        dir:    LengthDir::Vertical });
    }

    #[test]
    fn parses_physical_units () {
        assert_eq! (RsvgLength::parse ("72pt", LengthDir::Both),
                    RsvgLength {
                        length: 1.0,
                        unit:   LengthUnit::Inch,
                        dir:    LengthDir::Both });

        assert_eq! (RsvgLength::parse ("-22.5in", LengthDir::Both),
                    RsvgLength {
                        length: -22.5,
                        unit:   LengthUnit::Inch,
                        dir:    LengthDir::Both });

        assert_eq! (RsvgLength::parse ("-25.4cm", LengthDir::Both),
                    RsvgLength {
                        length: -10.0,
                        unit:   LengthUnit::Inch,
                        dir:    LengthDir::Both });

        assert_eq! (RsvgLength::parse ("254mm", LengthDir::Both),
                    RsvgLength {
                        length: 10.0,
                        unit:   LengthUnit::Inch,
                        dir:    LengthDir::Both });

        assert_eq! (RsvgLength::parse ("60pc", LengthDir::Both),
                    RsvgLength {
                        length: 10.0,
                        unit:   LengthUnit::Inch,
                        dir:    LengthDir::Both });
    }

    #[test]
    fn parses_relative_larger () {
        assert_eq! (RsvgLength::parse ("larger", LengthDir::Vertical),
                    RsvgLength {
                        length: 0.0,
                        unit:   LengthUnit::RelativeLarger,
                        dir:    LengthDir::Vertical });
    }

    #[test]
    fn parses_relative_smaller () {
        assert_eq! (RsvgLength::parse ("smaller", LengthDir::Vertical),
                    RsvgLength {
                        length: 0.0,
                        unit:   LengthUnit::RelativeSmaller,
                        dir:    LengthDir::Vertical });
    }

    #[test]
    fn parses_named_sizes () {
        let names = vec![ "xx-small",
                           "x-small",
                           "small",
                           "medium",
                           "large",
                           "x-large",
                           "xx-large" ];

        let mut previous_value: Option<f64> = None;

        // Just ensure that the values are progressively larger; don't
        // enforce a particular sequence.

        for name in names {
            let length = RsvgLength::parse (name, LengthDir::Both);

            assert_eq! (length.unit, LengthUnit::Inch);
            assert_eq! (length.dir, LengthDir::Both);

            if let Some (v) = previous_value {
                assert! (length.length > v);
            } else {
                previous_value = Some (length.length);
            }

        }

    }
}
<|endoftext|>


<commit_before>use mli::*;
pub use ndarray::{Array, Array2, ArrayView2};

pub struct Conv2(pub Array2<f32>);

impl<'a> Forward<ArrayView2<'a, f32>> for Conv2 {
    type Internal = ();
    type Output = Array2<f32>;

    fn forward(&self, input: &ArrayView2<'a, f32>) -> ((), Self::Output) {
        let Self(filter) = self;
        let filter_dims = filter.raw_dim();
        let output_dims = (
            input.shape()[0] + 1 - filter_dims[0],
            input.shape()[1] + 1 - filter_dims[1],
        );
        (
            (),
            Array::from_shape_vec(
                output_dims,
                input
                    .windows(filter_dims)
                    .into_iter()
                    .map(|view| (view.to_owned() * filter).sum())
                    .collect(),
            )
            .expect("convolution produced incorrectly sized output"),
        )
    }
}
<commit_msg>halfway done with the convolve backpropogation<commit_after>use mli::*;
pub use ndarray::{azip, s, Array, Array2, ArrayView2};

fn convolve<'a>(signal: ArrayView2<'a, f32>, filter: ArrayView2<'a, f32>) -> Array2<f32> {
    let filter_dims = filter.raw_dim();
    let output_dims = (
        signal.shape()[0] + 1 - filter_dims[0],
        signal.shape()[1] + 1 - filter_dims[1],
    );
    Array::from_shape_vec(
        output_dims,
        signal
            .windows(filter_dims)
            .into_iter()
            .map(|view| (view.to_owned() * filter).sum())
            .collect(),
    )
    .expect("convolution produced incorrectly sized output")
}

pub struct Conv2(pub Array2<f32>);

impl Forward<Array2<f32>> for Conv2 {
    type Internal = ();
    type Output = Array2<f32>;

    fn forward(&self, input: &Array2<f32>) -> ((), Self::Output) {
        let Self(filter) = self;
        ((), convolve(input.view(), filter.view()))
    }
}

impl Backward<Array2<f32>, Array2<f32>> for Conv2 {
    type InputDelta = Array2<f32>;
    type TrainDelta = Array2<f32>;

    fn backward(
        &self,
        input: &Array2<f32>,
        internal: &Self::Internal,
        output_delta: &Array2<f32>,
    ) -> (Self::InputDelta, Self::TrainDelta) {
        // To compute the `input_delta`, we need to convolve the filter flipped across all its axes with
        // the zero-padded version of the `output_delta`. The amount of zero-padding that needs to be added
        // is `(l - 1) * 2` where `l` is the length of the filter along a given dimension.
        let Self(filter) = self;
        let filter_dims = filter.raw_dim();
        // If the filter is 1 in either dimension, the below code wont work.
        if filter_dims[0] == 1 || filter_dims[1] == 1 {
            unimplemented!("mli-conv: filter dimensions of 1 not implemented yet");
        }
        let padding = (2 * (filter_dims[0] - 1), 2 * (filter_dims[1] - 1));
        let pad_dims = (input.shape()[0] + padding.0, input.shape()[1] + padding.1);
        let mut pad = Array::zeros(pad_dims);
        pad.slice_mut(s![
            padding.0 as i32..-(padding.0 as i32),
            padding.1 as i32..-(padding.1 as i32)
        ])
        .assign(output_delta);
        let input_delta = convolve(pad.view(), filter.slice(s![..;-1,..;-1]));
        (
            input_delta.clone(),
            unimplemented!("train data not yet computed"),
        )
    }
}
<|endoftext|>


<commit_before>// Zinc, the bare metal stack for rust.
// Copyright 2014 Ben Gamari <bgamari@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use core::option::{None, Some};
use core::ty::Unsafe;
use core::kinds::marker;
use core::kinds::Share;

use hal::cortex_m3::sched::NoInterrupts;
use util::queue::{Queue, Node};
use os::task::{TaskDescriptor, Tasks};

pub struct CondVar {
  waiting: Queue<*mut TaskDescriptor>
}

pub static COND_VAR_INIT: CondVar = CondVar {
  waiting: Queue {
    head: Unsafe { value: 0 as *mut Node<*mut TaskDescriptor>, marker1: marker::InvariantType },
    tail: Unsafe { value: 0 as *mut Node<*mut TaskDescriptor>, marker1: marker::InvariantType },
  }
};

impl CondVar {
  pub fn new() -> CondVar {
    CondVar { waiting: Queue::new() }
  }

  /// Wait on a condition variable.
  pub fn wait<'a>(&'a self) {
    /*
     * The signalling thread is responsible for removing the waiting
     * thread which ensures that a signal wakes up exactly one thread
     * whenever there is one waiting.
     */
    unsafe {
      let crit = NoInterrupts::new();
      let mut waiting = Node::new(Tasks.current_task() as *mut TaskDescriptor);
      self.waiting.push(&mut waiting, &crit);
      Tasks.current_task().block(crit);
    }
  }

  /// Wake up a thread waiting on a condition variable.
  pub fn signal<'a>(&'a self) {
    unsafe {
      let crit = NoInterrupts::new();
      match self.waiting.pop(&crit) {
        None => { },
        Some(task) => (*(*task).data).unblock(&crit)
      }
    }
  }

  /// Wake up all threads waiting on a condition variable.
  pub fn broadcast<'a>(&'a self) {
    unsafe {
      let crit = NoInterrupts::new();
      loop {
        match self.waiting.pop(&crit) {
          None => break,
          Some(task) => (*(*task).data).unblock(&crit)
        }
      }
    }
  }
}

impl Share for CondVar {}
<commit_msg>os::cond_var: Dust off and add single-threaded implementation<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Ben Gamari <bgamari@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Condition variables

pub use os::cond_var::internal::{CondVar, COND_VAR_INIT};

#[cfg(multitasking)]
mod internal {
  use core::option::{None, Some};
  use core::ty::Unsafe;
  use core::kinds::marker;
  use core::kinds::Share;

  use hal::cortex_m3::sched::NoInterrupts;
  use util::queue::{Queue, Node};
  use os::task::{TaskDescriptor, Tasks};

  /// A condition variable
  pub struct CondVar {
    waiting: Queue<*mut TaskDescriptor>
  }

  /// Static initializer
  pub const COND_VAR_INIT: CondVar = CondVar {
    waiting: Queue {
      head: Unsafe { value: 0 as *mut Node<*mut TaskDescriptor>, marker1: marker::InvariantType },
      tail: Unsafe { value: 0 as *mut Node<*mut TaskDescriptor>, marker1: marker::InvariantType },
    }
  };

  impl CondVar {
    /// Create a new condition variable
    pub fn new() -> CondVar {
      CondVar { waiting: Queue::new() }
    }

    /// Wait on a condition variable.
    pub fn wait(&self) {
      /*
       * The signalling thread is responsible for removing the waiting
       * thread which ensures that a signal wakes up exactly one thread
       * whenever there is one waiting.
       */
      unsafe {
        let crit = NoInterrupts::new();
        let mut waiting = Node::new(Tasks.current_task() as *mut TaskDescriptor);
        self.waiting.push(&mut waiting, &crit);
        Tasks.current_task().block(crit);
      }
    }

    /// Wake up a thread waiting on a condition variable.
    pub fn signal(&self) {
      unsafe {
        let crit = NoInterrupts::new();
        match self.waiting.pop(&crit) {
          None => { },
          Some(task) => (*(*task).data).unblock(&crit)
        }
      }
    }

    /// Wake up all threads waiting on a condition variable.
    pub fn broadcast(&self) {
      unsafe {
        let crit = NoInterrupts::new();
        loop {
          match self.waiting.pop(&crit) {
            None => break,
            Some(task) => (*(*task).data).unblock(&crit)
          }
        }
      }
    }
  }

  impl Share for CondVar {}
}

#[cfg(not(multitasking))]
mod internal {
  use core::kinds::marker;
  use core::kinds::Share;
  use core::cell::UnsafeCell;

  /// A condition variable
  pub struct CondVar {
    waiting: UnsafeCell<bool>,
    nocopy: marker::NoCopy
  }

  /// Static initializer
  pub const COND_VAR_INIT: CondVar = CondVar {
    waiting: UnsafeCell { value: false },
    nocopy: marker::NoCopy,
  };

  impl CondVar {
    /// Create a new condition variable
    pub fn new() -> CondVar {
      CondVar {
        waiting: UnsafeCell::new(false),
        nocopy: marker::NoCopy,
      }
    }

    /// Wait on a condition variable.
    pub fn wait(&self) {
      unsafe {
        while *self.waiting.get() {
          asm!("wfi")
        }
      }
    }

    /// Wake up a thread waiting on a condition variable.
    pub fn signal(&self) {
      unsafe {
        *self.waiting.get() = true;
      }
    }

    /// Wake up all threads waiting on a condition variable.
    pub fn broadcast(&self) {
      self.signal();
    }
  }

  impl Share for CondVar {}
}
<|endoftext|>


<commit_before>fn main() {
    let examples = vec!["broood", "bananaaa", "hiphophiphop"];
    for example in examples {
        let encoded = encode(example);
        println!("{} encodes to {:?}", example, encoded);
    }
}

fn get_symbols() -> Vec<u8> {
    (b'a'..b'z').collect()
}

fn encode(input: &str) -> Vec<usize> {
    input
        .as_bytes()
        .iter()
        .fold((Vec::new(), get_symbols()), |(mut o, mut s), x| {
            let i = s.iter().position(|c| c == x).unwrap();
            let c = s.remove(i);
            s.insert(0, c);
            o.push(i);
            (o, s)
        })
        .0
}

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

    #[test]
    fn correct_encode() {
        let encoded = encode("broood");
        assert_eq!(encoded, vec![1,17,15,0,0,5]);
    }
}
<commit_msg>add decode implementation<commit_after>fn main() {
    let examples = vec!["broood", "bananaaa", "hiphophiphop"];
    for example in examples {
        let encoded = encode(example);
        let decoded = decode(&encoded);
        println!(
            "{} encodes to {:?} decodes to {}",
            example, encoded, decoded
        );
    }
}

fn get_symbols() -> Vec<u8> {
    (b'a'..b'z').collect()
}

fn encode(input: &str) -> Vec<usize> {
    input
        .as_bytes()
        .iter()
        .fold((Vec::new(), get_symbols()), |(mut o, mut s), x| {
            let i = s.iter().position(|c| c == x).unwrap();
            let c = s.remove(i);
            s.insert(0, c);
            o.push(i);
            (o, s)
        })
        .0
}

fn decode(input: &[usize]) -> String {
    input
        .iter()
        .fold((Vec::new(), get_symbols()), |(mut o, mut s), x| {
            o.push(s[*x]);
            let c = s.remove(*x);
            s.insert(0, c);
            (o, s)
        })
        .0
        .into_iter()
        .map(|c| c as char)
        .collect()
}

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

    #[test]
    fn correct_encode() {
        let encoded = encode("broood");
        assert_eq!(encoded, vec![1, 17, 15, 0, 0, 5]);
    }

    #[test]
    fn correct_decode() {
        let decoded = decode(&[1, 17, 15, 0, 0, 5]);
        assert_eq!(decoded, "broood");
    }
}
<|endoftext|>


<commit_before>fn main() {
    let strings = vec![
        String::from("1001110011"),
        String::from("1110111011"),
        String::from("0010010010"),
        String::from("1010101010"),
        String::from("1111111111"),
        String::from("0100101101"),
        String::from("0100100"),
        String::from("101"),
        String::from("11"),
        String::from("00"),
        String::from("1"),
    ];
    for string in strings {
        match rep_string(&string) {
            Some(rep_string) => println!(
                "Longuest rep-string for '{}' is '{}' ({} chars)",
                string,
                rep_string,
                rep_string.len(),
            ),
            None => println!("No rep-string found for '{}'", string),
        };
    }
}

fn rep_string(string: &str) -> Option<&str> {
    let index = string.len() / 2;

    for split_index in (1..=index).rev() {
        let mut is_rep_string = true;
        let (first, last) = string.split_at(split_index);

        let inter = last.chars().collect::<Vec<char>>();
        let mut iter = inter.chunks_exact(split_index);
        for chunk in iter.by_ref() {
            if first != chunk.iter().collect::<String>() {
                is_rep_string = false;
                break;
            }
        }
        let rmnd = iter.remainder().iter().collect::<String>();

        // Check that the remainder starts with the rep-string
        if !first.starts_with(rmnd.as_str()) {
            is_rep_string = false;
        }

        if is_rep_string {
            return Some(first);
        }
    }
    None
}

#[cfg(test)]
mod tests {
    use super::rep_string;
    use std::collections::HashMap;

    #[test]
    fn test_rep_string() {
        let mut results = HashMap::new();
        results.insert(String::from("1001110011"), Some("10011"));
        results.insert(String::from("1110111011"), Some("1110"));
        results.insert(String::from("0010010010"), Some("001"));
        results.insert(String::from("1010101010"), Some("1010"));
        results.insert(String::from("1111111111"), Some("11111"));
        results.insert(String::from("0100101101"), None);
        results.insert(String::from("0100100"), Some("010"));
        results.insert(String::from("101"), None);
        results.insert(String::from("11"), Some("1"));
        results.insert(String::from("00"), Some("0"));
        results.insert(String::from("1"), None);

        for (input, expected) in results {
            assert_eq!(expected, rep_string(&input));
        }
    }
}
<commit_msg>nitpick minor typo<commit_after>fn main() {
    let strings = vec![
        String::from("1001110011"),
        String::from("1110111011"),
        String::from("0010010010"),
        String::from("1010101010"),
        String::from("1111111111"),
        String::from("0100101101"),
        String::from("0100100"),
        String::from("101"),
        String::from("11"),
        String::from("00"),
        String::from("1"),
    ];
    for string in strings {
        match rep_string(&string) {
            Some(rep_string) => println!(
                "Longest rep-string for '{}' is '{}' ({} chars)",
                string,
                rep_string,
                rep_string.len(),
            ),
            None => println!("No rep-string found for '{}'", string),
        };
    }
}

fn rep_string(string: &str) -> Option<&str> {
    let index = string.len() / 2;

    for split_index in (1..=index).rev() {
        let mut is_rep_string = true;
        let (first, last) = string.split_at(split_index);

        let inter = last.chars().collect::<Vec<char>>();
        let mut iter = inter.chunks_exact(split_index);
        for chunk in iter.by_ref() {
            if first != chunk.iter().collect::<String>() {
                is_rep_string = false;
                break;
            }
        }
        let rmnd = iter.remainder().iter().collect::<String>();

        // Check that the remainder starts with the rep-string
        if !first.starts_with(rmnd.as_str()) {
            is_rep_string = false;
        }

        if is_rep_string {
            return Some(first);
        }
    }
    None
}

#[cfg(test)]
mod tests {
    use super::rep_string;
    use std::collections::HashMap;

    #[test]
    fn test_rep_string() {
        let mut results = HashMap::new();
        results.insert(String::from("1001110011"), Some("10011"));
        results.insert(String::from("1110111011"), Some("1110"));
        results.insert(String::from("0010010010"), Some("001"));
        results.insert(String::from("1010101010"), Some("1010"));
        results.insert(String::from("1111111111"), Some("11111"));
        results.insert(String::from("0100101101"), None);
        results.insert(String::from("0100100"), Some("010"));
        results.insert(String::from("101"), None);
        results.insert(String::from("11"), Some("1"));
        results.insert(String::from("00"), Some("0"));
        results.insert(String::from("1"), None);

        for (input, expected) in results {
            assert_eq!(expected, rep_string(&input));
        }
    }
}
<|endoftext|>


<commit_before>use std::io::IoResult;

use xmpp_send::XmppSend;
use xmpp_socket::XmppSocket;
use ns;

///
///
///
pub struct XmppServerHandler {
    pub socket: XmppSocket
}

///
///
///
impl XmppServerHandler {
    pub fn start_stream(&mut self, domain: &str) -> IoResult<()> {
        let start = format!(
            "<?xml version='1.0'?>\n\
            <stream:stream \
                xmlns:stream='{}'
                xmlns='{}' \
                version='1.0' \
                from='{}'\
                id='{}'
            >",
            ns::STREAMS,
            ns::JABBER_CLIENT,
            domain,
            "arandomid"
        );
        self.send(start)
    }

    /// advertize the security features provided by the server
    ///
    /// must be send right after the server has sent its own
    /// <stream:stream> (without waiting for client answer)
    /// and BEFORE non-security features are advertized, as define
    /// in RFC3920 section 4.6
    pub fn advertize_security_features(&mut self) -> IoResult<()> {

        // TODO the list of SASL mechanism provided should be extensible
        // rather than hardcoded
        let features = format!(
            "<stream:features>\
                <mechanisms xmlns='{sasl}'>\
                    <mechanism>PLAIN</mechanism>\
                </mechanisms>\
            </stream:features>",
            sasl= ns::FEATURE_SASL
        );

        self.send(features)
    }

    pub fn close_stream(&mut self) -> IoResult<()> {
        self.send("</stream:stream>")
    }

    pub fn send<T: XmppSend>(&mut self, data: T) -> IoResult<()> {
        let data = data.xmpp_str();
        println!("Out: {}", data);
        try!(self.socket.write(data.as_slice().as_bytes()));
        self.socket.flush()
    }
}

<commit_msg>added doc for start_stream function<commit_after>use std::io::IoResult;

use xmpp_send::XmppSend;
use xmpp_socket::XmppSocket;
use ns;

///
///
///
pub struct XmppServerHandler {
    pub socket: XmppSocket
}

///
///
///
impl XmppServerHandler {

    /// start XMPP stream from server side
    ///
    /// to be called after we've received <stream:stream> from client
    /// as defined in RFC3920
    /// http://xmpp.org/rfcs/rfc3920.html#streams
    ///
    /// domain is the domain served by this connection
    pub fn start_stream(&mut self, domain: &str) -> IoResult<()> {
        let start = format!(
            "<?xml version='1.0'?>\n\
            <stream:stream \
                xmlns:stream='{}'
                xmlns='{}' \
                version='1.0' \
                from='{}'\
                id='{}'
            >",
            ns::STREAMS,
            ns::JABBER_CLIENT,
            domain,
            "arandomid"
        );
        self.send(start)
    }

    /// advertize the security features provided by the server
    ///
    /// must be send right after the server has sent its own
    /// <stream:stream> (without waiting for client answer)
    /// and BEFORE non-security features are advertized, as define
    /// in RFC3920 section 4.6
    pub fn advertize_security_features(&mut self) -> IoResult<()> {

        // TODO the list of SASL mechanism provided should be extensible
        // rather than hardcoded
        let features = format!(
            "<stream:features>\
                <mechanisms xmlns='{sasl}'>\
                    <mechanism>PLAIN</mechanism>\
                </mechanisms>\
            </stream:features>",
            sasl= ns::FEATURE_SASL
        );

        self.send(features)
    }

    pub fn close_stream(&mut self) -> IoResult<()> {
        self.send("</stream:stream>")
    }

    pub fn send<T: XmppSend>(&mut self, data: T) -> IoResult<()> {
        let data = data.xmpp_str();
        println!("Out: {}", data);
        try!(self.socket.write(data.as_slice().as_bytes()));
        self.socket.flush()
    }
}

<|endoftext|>


<commit_before>use encoding::all::UTF_16LE;
use encoding::{Encoding, DecoderTrap};
use byteorder::{ReadBytesExt, LittleEndian};
use lnkpkg::errors::{LnkError};
use lnkpkg::utils;
use std::io::SeekFrom;
use std::io::Read;
use std::io::Seek;

#[derive(Debug)]
pub struct NetworkShareInfo {
    pub size: u32,
    pub flags: u32,
    pub offset_share_name: u32,
    pub offset_device_name: u32,
    pub provider_type: u32,
    pub offset_share_name_unicode: Option<u32>,
    pub offset_device_name_unicode: Option<u32>,
    pub share_name: String,
    pub device_name: String,
    pub share_name_unicode: Option<String>,
    pub device_name_unicode: Option<String>
}
impl NetworkShareInfo {
    pub fn new<Rs: Read+Seek>(mut reader: Rs) -> Result<NetworkShareInfo,LnkError> {
        // Get Current Pos
        let cur_pos = reader.seek(
            SeekFrom::Current(0)
        )?;

        let size = reader.read_u32::<LittleEndian>()?;
        let flags = reader.read_u32::<LittleEndian>()?;
        let offset_share_name = reader.read_u32::<LittleEndian>()?;
        let offset_device_name = reader.read_u32::<LittleEndian>()?;
        let provider_type = reader.read_u32::<LittleEndian>()?;

        let mut offset_share_name_unicode = None;
        let mut offset_device_name_unicode = None;
        if offset_share_name > 20 {
            offset_share_name_unicode = Some(reader.read_u32::<LittleEndian>()?);
            offset_device_name_unicode = Some(reader.read_u32::<LittleEndian>()?);
        }

        reader.seek(
            SeekFrom::Start(cur_pos + offset_share_name as u64)
        )?;
        // Get share name
        let share_name = String::from_utf8(
            utils::get_u8_vec(&mut reader)?
        )?;

        reader.seek(
            SeekFrom::Start(cur_pos + offset_device_name as u64)
        )?;
        // Get device name
        let device_name = String::from_utf8(
            utils::get_u8_vec(&mut reader)?
        )?;

        let mut share_name_unicode = None;
        if offset_share_name_unicode.is_some() {
            reader.seek(
                SeekFrom::Start(cur_pos + offset_share_name_unicode.unwrap() as u64)
            )?;

            let utf16_buffer = utils::get_u8_vec_utf16(&mut reader)?;
            let utf16_string = match UTF_16LE.decode(&utf16_buffer,DecoderTrap::Ignore) {
                Ok(utf16) => utf16,
                Err(error) => return Err(
                    LnkError::utf16_decode_error(
                        format!("Error decoding name in share_name_unicode field. [{}]",error)
                    )
                )
            };
            share_name_unicode = Some(utf16_string);
        }

        let mut device_name_unicode = None;
        if offset_device_name_unicode.is_some() {
            reader.seek(
                SeekFrom::Start(cur_pos + offset_device_name_unicode.unwrap() as u64)
            )?;

            let utf16_buffer = utils::get_u8_vec_utf16(&mut reader)?;
            let utf16_string = match UTF_16LE.decode(&utf16_buffer.as_slice(),DecoderTrap::Ignore) {
                Ok(utf16) => utf16,
                Err(error) => return Err(
                    LnkError::utf16_decode_error(
                        format!("Error decoding name in device_name_unicode field. [{}]",error)
                    )
                )
            };
            device_name_unicode = Some(utf16_string);
        }

        Ok(
            NetworkShareInfo {
                size: size,
                flags: flags,
                offset_share_name: offset_share_name,
                offset_device_name: offset_device_name,
                provider_type: provider_type,
                offset_share_name_unicode: offset_share_name_unicode,
                offset_device_name_unicode: offset_device_name_unicode,
                share_name: share_name,
                device_name: device_name,
                share_name_unicode: share_name_unicode,
                device_name_unicode: device_name_unicode
            }
        )
    }
}
<commit_msg>switched to string helper methods<commit_after>use encoding::all::UTF_16LE;
use encoding::{Encoding, DecoderTrap};
use byteorder::{ReadBytesExt, LittleEndian};
use lnkpkg::errors::{LnkError};
use lnkpkg::utils;
use std::io::SeekFrom;
use std::io::Read;
use std::io::Seek;

#[derive(Debug)]
pub struct NetworkShareInfo {
    pub size: u32,
    pub flags: u32,
    pub offset_share_name: u32,
    pub offset_device_name: u32,
    pub provider_type: u32,
    pub offset_share_name_unicode: Option<u32>,
    pub offset_device_name_unicode: Option<u32>,
    pub share_name: String,
    pub device_name: String,
    pub share_name_unicode: Option<String>,
    pub device_name_unicode: Option<String>
}
impl NetworkShareInfo {
    pub fn new<Rs: Read+Seek>(mut reader: Rs) -> Result<NetworkShareInfo,LnkError> {
        // Get Current Pos
        let cur_pos = reader.seek(
            SeekFrom::Current(0)
        )?;

        let size = reader.read_u32::<LittleEndian>()?;
        let flags = reader.read_u32::<LittleEndian>()?;
        let offset_share_name = reader.read_u32::<LittleEndian>()?;
        let offset_device_name = reader.read_u32::<LittleEndian>()?;
        let provider_type = reader.read_u32::<LittleEndian>()?;

        let mut offset_share_name_unicode = None;
        let mut offset_device_name_unicode = None;
        if offset_share_name > 20 {
            offset_share_name_unicode = Some(reader.read_u32::<LittleEndian>()?);
            offset_device_name_unicode = Some(reader.read_u32::<LittleEndian>()?);
        }

        reader.seek(
            SeekFrom::Start(cur_pos + offset_share_name as u64)
        )?;
        let share_name = utils::read_string_u8_till_null(&mut reader)?;

        reader.seek(
            SeekFrom::Start(cur_pos + offset_device_name as u64)
        )?;
        // Get device name
        let device_name = utils::read_string_u8_till_null(&mut reader)?;

        let mut share_name_unicode = None;
        if offset_share_name_unicode.is_some() {
            reader.seek(
                SeekFrom::Start(cur_pos + offset_share_name_unicode.unwrap() as u64)
            )?;
            share_name_unicode = Some(utils::read_string_u16_till_null(&mut reader)?);
        }

        let mut device_name_unicode = None;
        if offset_device_name_unicode.is_some() {
            reader.seek(
                SeekFrom::Start(cur_pos + offset_device_name_unicode.unwrap() as u64)
            )?;
            device_name_unicode = Some(utils::read_string_u16_till_null(&mut reader)?);
        }

        Ok(
            NetworkShareInfo {
                size: size,
                flags: flags,
                offset_share_name: offset_share_name,
                offset_device_name: offset_device_name,
                provider_type: provider_type,
                offset_share_name_unicode: offset_share_name_unicode,
                offset_device_name_unicode: offset_device_name_unicode,
                share_name: share_name,
                device_name: device_name,
                share_name_unicode: share_name_unicode,
                device_name_unicode: device_name_unicode
            }
        )
    }
}
<|endoftext|>


<commit_before>//! A chat server that broadcasts a message to all connections.

extern crate tokio_core;
extern crate futures;

use std::collections::HashMap;
use std::rc::Rc;
use std::cell::RefCell;
use std::iter;
use std::env;
use std::io::{Error, ErrorKind, BufReader};

use tokio_core::net::TcpListener;
use tokio_core::reactor::Core;
use tokio_core::io::{self, Io};

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

fn main() {
    let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
    let addr = addr.parse().unwrap();
    // We are single-threaded, so we can just use Rc and RefCell.
    let connections = Rc::new(RefCell::new(HashMap::new()));

    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let socket = TcpListener::bind(&addr, &handle).unwrap();
    println!("Listening on: {}", addr);

    let future = socket.incoming().for_each(move |(stream, addr)| {
        let connections = connections.clone();
        let handle_inner = handle.clone();
        // We create a new future in which we create all other futures.
        // This makes `stream` be bound on the outer future's task, allowing
        // `ReadHalf` and `WriteHalf` to be shared between inner futures.
        handle.spawn_fn(move || {
            println!("New Connection: {}", addr);
            let (reader, writer) = stream.split();
            // channel to send messages to this connection from other futures
            let (tx, rx) = tokio_core::channel::channel(&handle_inner).unwrap();
            // add sender to hashmap of all current connections
            connections.borrow_mut().insert(addr, tx);

            let reader = BufReader::new(reader);
            let connections_inner = connections.clone();
            // https://users.rust-lang.org/t/loop-futures-for-client-handling/6950/2
            // First we need to get an infinite iterator
            let iter = stream::iter::<_, _, std::io::Error>(iter::repeat(()).map(Ok));
            // Then we fold it as infinite loop
            let socket_reader = iter.fold(reader, move |reader, _| {
                let connections = connections_inner.clone();
                // read line
                let amt = io::read_until(reader, '\n' as u8, vec![]);
                // check if we hit EOF and need to close the connection
                let amt = amt.and_then(|(reader, vec)| {
                    // EOF was hit without reading a delimiter
                    if vec.len() == 0 {
                        let err = Error::new(ErrorKind::BrokenPipe, "Broken Pipe");
                        futures::failed(err).boxed()
                    } else {
                        futures::finished((reader, vec)).boxed()
                    }
                });
                // convert bytes into string
                let amt = amt.map(|(reader, vec)| (reader, String::from_utf8(vec)));
                amt.and_then(move |(reader, message)| {
                    println!("{}: {:?}", addr, message);
                    let conns = connections.borrow_mut();
                    if let Ok(msg) = message {
                        // For each open connection except the sender, send the string
                        // via the channel
                        let iter = conns.iter().filter(|&(&k,_)| k != addr).map(|(_,v)| v);
                        for tx in iter {
                            tx.send(msg.clone()).unwrap();
                        }
                    } else {
                        let tx = conns.get(&addr).unwrap();
                        tx.send("You didn't send valid UTF-8.".to_string()).unwrap();
                    }
                    futures::finished(reader)
                })
            });

            // Whenever we receive a string on the Receiver, we write it to `WriteHalf<TcpStream>`.
            let socket_writer = rx.fold(writer, |writer, msg| {
                let amt = io::write_all(writer, msg.into_bytes());
                let amt = amt.map(|(writer, _)| writer);
                amt
            });

            // In order to fuse the reading and writing futures in the end, we need to have the
            // same output type. Therefore we use `(Option<BufReader<ReadHalf<TcpStream>>>,
            // Option<WriteHalf<TcpStream>>)`.
            let socket_reader = socket_reader.map(|reader| (Some(reader), None));
            let socket_writer = socket_writer.map(|writer| (None, Some(writer)));

            let amt = socket_reader.select(socket_writer);
            amt.then(move |_| {
                connections.borrow_mut().remove(&addr);
                println!("Connection {:?} closed.", addr);
                Ok(())
            })
        });
        Ok(())
    });

    // exectue server
    core.run(future).unwrap();
}

<commit_msg>ref(chat): Make code more readable<commit_after>//! A chat server that broadcasts a message to all connections.

extern crate tokio_core;
extern crate futures;

use std::collections::HashMap;
use std::rc::Rc;
use std::cell::RefCell;
use std::iter;
use std::env;
use std::io::{Error, ErrorKind, BufReader};

use tokio_core::net::TcpListener;
use tokio_core::reactor::Core;
use tokio_core::io::{self, Io};

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

fn main() {
    let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
    let addr = addr.parse().unwrap();
    // We are single-threaded, so we can just use Rc and RefCell.
    let connections = Rc::new(RefCell::new(HashMap::new()));

    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let socket = TcpListener::bind(&addr, &handle).unwrap();
    println!("Listening on: {}", addr);

    let future = socket.incoming().for_each(move |(stream, addr)| {
        let connections = connections.clone();
        let handle_inner = handle.clone();
        // We create a new future in which we create all other futures.
        // This makes `stream` be bound on the outer future's task, allowing
        // `ReadHalf` and `WriteHalf` to be shared between inner futures.
        let main_fn = move || {
            println!("New Connection: {}", addr);
            let (reader, writer) = stream.split();
            // channel to send messages to this connection from other futures
            let (tx, rx) = tokio_core::channel::channel(&handle_inner).unwrap();
            // add sender to hashmap of all current connections
            connections.borrow_mut().insert(addr, tx);

            let reader = BufReader::new(reader);
            let connections_inner = connections.clone();
            // https://users.rust-lang.org/t/loop-futures-for-client-handling/6950/2
            // First we need to get an infinite iterator
            let iter = stream::iter::<_, _, std::io::Error>(iter::repeat(()).map(Ok));
            // Then we fold it as infinite loop
            let socket_reader = iter.fold(reader, move |reader, _| {
                let connections = connections_inner.clone();
                // read line
                let amt = io::read_until(reader, '\n' as u8, vec![]);
                // check if we hit EOF and need to close the connection
                let amt = amt.and_then(|(reader, vec)| {
                    // EOF was hit without reading a delimiter
                    if vec.len() == 0 {
                        let err = Error::new(ErrorKind::BrokenPipe, "Broken Pipe");
                        futures::failed(err).boxed()
                    } else {
                        futures::finished((reader, vec)).boxed()
                    }
                });
                // convert bytes into string
                let amt = amt.map(|(reader, vec)| (reader, String::from_utf8(vec)));
                amt.map(move |(reader, message)| {
                    println!("{}: {:?}", addr, message);
                    let conns = connections.borrow_mut();
                    if let Ok(msg) = message {
                        // For each open connection except the sender, send the string
                        // via the channel
                        let iter = conns.iter().filter(|&(&k,_)| k != addr).map(|(_,v)| v);
                        for tx in iter {
                            tx.send(format!("{}: {}", addr, msg)).unwrap();
                        }
                    } else {
                        let tx = conns.get(&addr).unwrap();
                        tx.send("You didn't send valid UTF-8.".to_string()).unwrap();
                    }
                    reader
                })
            });

            // Whenever we receive a string on the Receiver, we write it to `WriteHalf<TcpStream>`.
            let socket_writer = rx.fold(writer, |writer, msg| {
                let amt = io::write_all(writer, msg.into_bytes());
                let amt = amt.map(|(writer, _)| writer);
                amt
            });

            // In order to fuse the reading and writing futures in the end, we need to have the
            // same output type. As we don't need the values anymore, we can just map them
            // to `()`.
            let socket_reader = socket_reader.map(|_| ());
            let socket_writer = socket_writer.map(|_| ());

            let amt = socket_reader.select(socket_writer);
            amt.then(move |_| {
                connections.borrow_mut().remove(&addr);
                println!("Connection {} closed.", addr);
                Ok(())
            })
        };
        handle.spawn_fn(main_fn);
        Ok(())
    });

    // exectue server
    core.run(future).unwrap();
}

<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::f64;

// external
use svgdom::{
    Document,
    ElementType,
    FuzzyEq,
    Node,
};

// self
use math;
use short::{
    AId,
    EId,
};
use traits::{
    GetValue,
};

pub fn fix_gradient_stops(doc: &Document) {
    for node in doc.descendants().filter(|n| n.is_gradient()) {
        let mut prev_offset = 0.0;
        let mut prev_stop: Option<Node> = None;
        for mut stop in node.children().filter(|n| n.is_tag_name(EId::Stop)) {
            let mut offset = stop.attributes().get_number(AId::Offset).unwrap_or(0.0);
            offset = math::f64_bound(0.0, offset, 1.0);

            // Next offset must be smaller then previous.
            if offset < prev_offset || offset.fuzzy_eq(&prev_offset) {
                if let Some(mut prev_stop) = prev_stop {
                    // Make previous offset a bit smaller.
                    let new_offset = prev_offset - f64::EPSILON;
                    prev_stop.set_attribute((AId::Offset, new_offset));
                }

                offset = prev_offset;
            }

            stop.set_attribute((AId::Offset, offset));
            prev_offset = offset;
            prev_stop = Some(stop);
        }
    }
}
<commit_msg>Fixed 'stop' elements offset correction.<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::f64;

// external
use svgdom::{
    Document,
    ElementType,
    FuzzyEq,
};

// self
use math;
use short::{
    AId,
    AValue,
    EId,
};
use traits::{
    GetValue,
};

pub fn fix_gradient_stops(doc: &Document) {
    // Clamp offsets.
    for node in doc.descendants().filter(|n| n.is_gradient()) {
        for mut stop in node.children().filter(|n| n.is_tag_name(EId::Stop)) {
            let mut attrs = stop.attributes_mut();
            let av = attrs.get_value_mut(AId::Offset);
            if let Some(&mut AValue::Number(ref mut offset)) = av {
                *offset = math::f64_bound(0.0, *offset, 1.0);
            }
        }
    }

    // Remove stops with equal offset.
    //
    // Example:
    // offset="0.5"
    // offset="0.7"
    // offset="0.7" <-- this one should be removed
    // offset="0.7"
    // offset="0.9"
    let mut stops = Vec::new();
    for node in doc.descendants().filter(|n| n.is_gradient()) {
        stops.clear();
        for stop in node.children().filter(|n| n.is_tag_name(EId::Stop)) {
            stops.push(stop);
        }

        if stops.len() < 3 {
            continue;
        }

        let mut i = 0;
        while i < stops.len() - 2 {
            let offset1 = stops[i + 0].attributes().get_number(AId::Offset).unwrap_or(0.0);
            let offset2 = stops[i + 1].attributes().get_number(AId::Offset).unwrap_or(0.0);
            let offset3 = stops[i + 2].attributes().get_number(AId::Offset).unwrap_or(0.0);

            if offset1.fuzzy_eq(&offset2) && offset2.fuzzy_eq(&offset3) {
                // Remove offset in the middle.
                stops[i + 1].remove();
                stops.remove(1);
            } else {
                i += 1;
            }
        }
    }

    // Shift equal offsets.
    //
    // From:
    // offset="0.5"
    // offset="0.7"
    // offset="0.7"
    //
    // To:
    // offset="0.5"
    // offset="0.699999999"
    // offset="0.7"
    for node in doc.descendants().filter(|n| n.is_gradient()) {
        let mut prev_offset = 0.0;
        for mut stop in node.children().filter(|n| n.is_tag_name(EId::Stop)) {
            let mut offset = stop.attributes().get_number(AId::Offset).unwrap_or(0.0);

            // Next offset must be smaller then previous.
            if offset < prev_offset || offset.fuzzy_eq(&prev_offset) {
                if let Some(mut prev_stop) = stop.previous_sibling() {
                    // Make previous offset a bit smaller.
                    let new_offset = prev_offset - f64::EPSILON;
                    prev_stop.set_attribute((AId::Offset, new_offset));
                }

                offset = prev_offset;
            }

            stop.set_attribute((AId::Offset, offset));
            prev_offset = offset;
        }
    }
}
<|endoftext|>


<commit_before>/*!
`ed25519`, a signature scheme specified in
[Ed25519](http://ed25519.cr.yp.to/). This function is conjectured to meet the
standard notion of unforgeability for a public-key signature scheme under
chosen-message attacks.
*/
extern crate serialize;
use std::libc::{c_ulonglong, c_int};
use std::slice::{from_elem};

#[link(name = "sodium")]
extern {
    fn crypto_sign_ed25519_keypair(pk: *mut u8,
                                   sk: *mut u8) -> c_int;
    fn crypto_sign_ed25519_seed_keypair(pk: *mut u8,
                                        sk: *mut u8,
                                        seed: *u8) -> c_int;
    fn crypto_sign_ed25519(sm: *mut u8,
                           smlen: *mut c_ulonglong,
                           m: *u8,
                           mlen: c_ulonglong,
                           sk: *u8) -> c_int;
    fn crypto_sign_ed25519_open(m: *mut u8,
                                mlen: *mut c_ulonglong,
                                sm: *u8,
                                smlen: c_ulonglong,
                                pk: *u8) -> c_int;
}

pub static SEEDBYTES: uint = 32;
pub static SECRETKEYBYTES: uint = 64;
pub static PUBLICKEYBYTES: uint = 32;
pub static SIGNATUREBYTES: uint = 64;

/**
 * `Seed` that can be used for keypair generation
 *
 * The `Seed` is used by `keypair_from_seed()` to generate
 * a secret and public signature key.
 *
 * When a `Seed` goes out of scope its contents
 * will be zeroed out
 */
pub struct Seed([u8, ..SEEDBYTES]);
impl Drop for Seed {
    fn drop(&mut self) {
        let &Seed(ref mut s) = self;
        for e in s.mut_iter() { *e = 0 }
    }
}

/**
 * `SecretKey` for signatures
 *
 * When a `SecretKey` goes out of scope its contents
 * will be zeroed out
 */
pub struct SecretKey([u8, ..SECRETKEYBYTES]);
impl Drop for SecretKey {
    fn drop(&mut self) {
        let &SecretKey(ref mut sk) = self;
        for e in sk.mut_iter() { *e = 0 }
    }
}
/**
 * `PublicKey` for signatures
 */
pub struct PublicKey([u8, ..PUBLICKEYBYTES]);

/**
 * `gen_keypair()` randomly generates a secret key and a corresponding public
 * key.
 *
 * THREAD SAFETY: `gen_keypair()` is thread-safe provided that you have
 * called `sodiumoxide::init()` once before using any other function
 * from sodiumoxide.
 */
pub fn gen_keypair() -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8, ..PUBLICKEYBYTES];
        let mut sk = [0u8, ..SECRETKEYBYTES];
        crypto_sign_ed25519_keypair(pk.as_mut_ptr(), sk.as_mut_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `keypair_from_seed()` computes a secret key and a corresponding public key
 * from a `Seed`.
 */
pub fn keypair_from_seed(&Seed(seed): &Seed) -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8, ..PUBLICKEYBYTES];
        let mut sk = [0u8, ..SECRETKEYBYTES];
        crypto_sign_ed25519_seed_keypair(pk.as_mut_ptr(),
                                         sk.as_mut_ptr(),
                                         seed.as_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `sign()` signs a message `m` using the signer's secret key `sk`.
 * `sign()` returns the resulting signed message `sm`.
 */
pub fn sign(m: &[u8],
            &SecretKey(sk): &SecretKey) -> ~[u8] {
    unsafe {
        let mut sm = from_elem(m.len() + SIGNATUREBYTES, 0u8);
        let mut smlen = 0;
        crypto_sign_ed25519(sm.as_mut_ptr(),
                            &mut smlen,
                            m.as_ptr(),
                            m.len() as c_ulonglong,
                            sk.as_ptr());
        sm.truncate(smlen as uint);
        sm
    }
}

/**
 * `verify()` verifies the signature in `sm` using the signer's public key `pk`.
 * `verify()` returns the message `Some(m)`.
 * If the signature fails verification, `verify()` returns `None`.
 */
pub fn verify(sm: &[u8],
              &PublicKey(pk): &PublicKey) -> Option<~[u8]> {
    unsafe {
        let mut m = from_elem(sm.len(), 0u8);
        let mut mlen = 0;
        if crypto_sign_ed25519_open(m.as_mut_ptr(),
                                    &mut mlen,
                                    sm.as_ptr(),
                                    sm.len() as c_ulonglong,
                                    pk.as_ptr()) == 0 {
            m.truncate(mlen as uint);
            Some(m)
        } else {
            None
        }
    }
}

#[test]
fn test_sign_verify() {
    use randombytes::randombytes;
    for i in range(0, 256) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i as uint);
        let sm = sign(m, &sk);
        let m2 = verify(sm, &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper() {
    use randombytes::randombytes;
    for i in range(0, 32) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i as uint);
        let mut sm = sign(m, &sk);
        for j in range(0, sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_sign_verify_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in range(0, 256) {
        let mut seedbuf = [0, ..32];
        randombytes_into(seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i as uint);
        let sm = sign(m, &sk);
        let m2 = verify(sm, &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in range(0, 32) {
        let mut seedbuf = [0, ..32];
        randombytes_into(seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i as uint);
        let mut sm = sign(m, &sk);
        for j in range(0, sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_vectors() {
    // test vectors from the Python implementation
    // form the [Ed25519 Homepage](http://ed25519.cr.yp.to/software.html)
    use self::serialize::hex::{FromHex, ToHex};
    use std::io::buffered::BufferedReader;
    use std::io::File;
    use std::path::Path;

    let p = &Path::new("testvectors/ed25519.input");
    let mut r = BufferedReader::new(File::open(p).unwrap());
    loop {
        let line = match r.read_line() {
            Err(_) => break,
            Ok(line) => line
        };
        let mut x = line.split(':');
        let x0 = x.next().unwrap();
        let x1 = x.next().unwrap();
        let x2 = x.next().unwrap();
        let x3 = x.next().unwrap();
        let seed_bytes = x0.slice(0, 64).from_hex().unwrap();
        assert!(seed_bytes.len() == SEEDBYTES);
        let mut seedbuf = [0u8, ..SEEDBYTES];
        for (s, b) in seedbuf.mut_iter().zip(seed_bytes.iter()) {
            *s = *b
        }
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = x2.from_hex().unwrap();
        let sm = sign(m, &sk);
        verify(sm, &pk).unwrap();
        let PublicKey(pkbuf) = pk;
        assert!(x1 == pkbuf.to_hex());
        assert!(x3 == sm.to_hex());
    }
}
<commit_msg>BufferedReader is now in std::io<commit_after>/*!
`ed25519`, a signature scheme specified in
[Ed25519](http://ed25519.cr.yp.to/). This function is conjectured to meet the
standard notion of unforgeability for a public-key signature scheme under
chosen-message attacks.
*/
extern crate serialize;
use std::libc::{c_ulonglong, c_int};
use std::slice::{from_elem};

#[link(name = "sodium")]
extern {
    fn crypto_sign_ed25519_keypair(pk: *mut u8,
                                   sk: *mut u8) -> c_int;
    fn crypto_sign_ed25519_seed_keypair(pk: *mut u8,
                                        sk: *mut u8,
                                        seed: *u8) -> c_int;
    fn crypto_sign_ed25519(sm: *mut u8,
                           smlen: *mut c_ulonglong,
                           m: *u8,
                           mlen: c_ulonglong,
                           sk: *u8) -> c_int;
    fn crypto_sign_ed25519_open(m: *mut u8,
                                mlen: *mut c_ulonglong,
                                sm: *u8,
                                smlen: c_ulonglong,
                                pk: *u8) -> c_int;
}

pub static SEEDBYTES: uint = 32;
pub static SECRETKEYBYTES: uint = 64;
pub static PUBLICKEYBYTES: uint = 32;
pub static SIGNATUREBYTES: uint = 64;

/**
 * `Seed` that can be used for keypair generation
 *
 * The `Seed` is used by `keypair_from_seed()` to generate
 * a secret and public signature key.
 *
 * When a `Seed` goes out of scope its contents
 * will be zeroed out
 */
pub struct Seed([u8, ..SEEDBYTES]);
impl Drop for Seed {
    fn drop(&mut self) {
        let &Seed(ref mut s) = self;
        for e in s.mut_iter() { *e = 0 }
    }
}

/**
 * `SecretKey` for signatures
 *
 * When a `SecretKey` goes out of scope its contents
 * will be zeroed out
 */
pub struct SecretKey([u8, ..SECRETKEYBYTES]);
impl Drop for SecretKey {
    fn drop(&mut self) {
        let &SecretKey(ref mut sk) = self;
        for e in sk.mut_iter() { *e = 0 }
    }
}
/**
 * `PublicKey` for signatures
 */
pub struct PublicKey([u8, ..PUBLICKEYBYTES]);

/**
 * `gen_keypair()` randomly generates a secret key and a corresponding public
 * key.
 *
 * THREAD SAFETY: `gen_keypair()` is thread-safe provided that you have
 * called `sodiumoxide::init()` once before using any other function
 * from sodiumoxide.
 */
pub fn gen_keypair() -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8, ..PUBLICKEYBYTES];
        let mut sk = [0u8, ..SECRETKEYBYTES];
        crypto_sign_ed25519_keypair(pk.as_mut_ptr(), sk.as_mut_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `keypair_from_seed()` computes a secret key and a corresponding public key
 * from a `Seed`.
 */
pub fn keypair_from_seed(&Seed(seed): &Seed) -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8, ..PUBLICKEYBYTES];
        let mut sk = [0u8, ..SECRETKEYBYTES];
        crypto_sign_ed25519_seed_keypair(pk.as_mut_ptr(),
                                         sk.as_mut_ptr(),
                                         seed.as_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `sign()` signs a message `m` using the signer's secret key `sk`.
 * `sign()` returns the resulting signed message `sm`.
 */
pub fn sign(m: &[u8],
            &SecretKey(sk): &SecretKey) -> ~[u8] {
    unsafe {
        let mut sm = from_elem(m.len() + SIGNATUREBYTES, 0u8);
        let mut smlen = 0;
        crypto_sign_ed25519(sm.as_mut_ptr(),
                            &mut smlen,
                            m.as_ptr(),
                            m.len() as c_ulonglong,
                            sk.as_ptr());
        sm.truncate(smlen as uint);
        sm
    }
}

/**
 * `verify()` verifies the signature in `sm` using the signer's public key `pk`.
 * `verify()` returns the message `Some(m)`.
 * If the signature fails verification, `verify()` returns `None`.
 */
pub fn verify(sm: &[u8],
              &PublicKey(pk): &PublicKey) -> Option<~[u8]> {
    unsafe {
        let mut m = from_elem(sm.len(), 0u8);
        let mut mlen = 0;
        if crypto_sign_ed25519_open(m.as_mut_ptr(),
                                    &mut mlen,
                                    sm.as_ptr(),
                                    sm.len() as c_ulonglong,
                                    pk.as_ptr()) == 0 {
            m.truncate(mlen as uint);
            Some(m)
        } else {
            None
        }
    }
}

#[test]
fn test_sign_verify() {
    use randombytes::randombytes;
    for i in range(0, 256) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i as uint);
        let sm = sign(m, &sk);
        let m2 = verify(sm, &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper() {
    use randombytes::randombytes;
    for i in range(0, 32) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i as uint);
        let mut sm = sign(m, &sk);
        for j in range(0, sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_sign_verify_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in range(0, 256) {
        let mut seedbuf = [0, ..32];
        randombytes_into(seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i as uint);
        let sm = sign(m, &sk);
        let m2 = verify(sm, &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in range(0, 32) {
        let mut seedbuf = [0, ..32];
        randombytes_into(seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i as uint);
        let mut sm = sign(m, &sk);
        for j in range(0, sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_vectors() {
    // test vectors from the Python implementation
    // form the [Ed25519 Homepage](http://ed25519.cr.yp.to/software.html)
    use self::serialize::hex::{FromHex, ToHex};
    use std::io::BufferedReader;
    use std::io::File;
    use std::path::Path;

    let p = &Path::new("testvectors/ed25519.input");
    let mut r = BufferedReader::new(File::open(p).unwrap());
    loop {
        let line = match r.read_line() {
            Err(_) => break,
            Ok(line) => line
        };
        let mut x = line.split(':');
        let x0 = x.next().unwrap();
        let x1 = x.next().unwrap();
        let x2 = x.next().unwrap();
        let x3 = x.next().unwrap();
        let seed_bytes = x0.slice(0, 64).from_hex().unwrap();
        assert!(seed_bytes.len() == SEEDBYTES);
        let mut seedbuf = [0u8, ..SEEDBYTES];
        for (s, b) in seedbuf.mut_iter().zip(seed_bytes.iter()) {
            *s = *b
        }
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = x2.from_hex().unwrap();
        let sm = sign(m, &sk);
        verify(sm, &pk).unwrap();
        let PublicKey(pkbuf) = pk;
        assert!(x1 == pkbuf.to_hex());
        assert!(x3 == sm.to_hex());
    }
}
<|endoftext|>


<commit_before>extern crate chrono;
extern crate lopdf;
extern crate png;
extern crate predicates;

pub mod file {

    use chrono::{DateTime, FixedOffset, Utc};

    use predicates::boolean::AndPredicate;
    use predicates::prelude::*;
    use predicates::reflection::{Case, Child, PredicateReflection, Product};
    use predicates::str::{ContainsPredicate, StartsWithPredicate};

    use std::fmt;

    /// Checks that the variable of type [u8] can be parsed as a PDF file.
    #[derive(Debug)]
    pub struct PdfPredicate {}

    impl PdfPredicate {
        pub fn with_page_count(self: Self, num_pages: usize) -> DetailPredicate<Self> {
            DetailPredicate::<Self> {
                p: self,
                d: Detail::PageCount(num_pages),
            }
        }

        pub fn with_creation_date(self: Self, when: DateTime<Utc>) -> DetailPredicate<Self> {
            DetailPredicate::<Self> {
                p: self,
                d: Detail::CreationDate(when),
            }
        }
    }

    impl Predicate<[u8]> for PdfPredicate {
        fn eval(&self, data: &[u8]) -> bool {
            lopdf::Document::load_mem(data).is_ok()
        }

        fn find_case<'a>(&'a self, _expected: bool, data: &[u8]) -> Option<Case<'a>> {
            match lopdf::Document::load_mem(data) {
                Ok(_) => None,
                Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
            }
        }
    }

    impl PredicateReflection for PdfPredicate {}

    impl fmt::Display for PdfPredicate {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "is a PDF")
        }
    }

    /// Extends a PdfPredicate by a check for page count or creation date.
    #[derive(Debug)]
    pub struct DetailPredicate<PdfPredicate> {
        p: PdfPredicate,
        d: Detail,
    }

    #[derive(Debug)]
    enum Detail {
        PageCount(usize),
        CreationDate(DateTime<Utc>),
    }

    trait Details {
        fn get_num_pages(&self) -> usize;
        fn get_creation_date(&self) -> Option<DateTime<Utc>>;
    }

    impl DetailPredicate<PdfPredicate> {
        fn eval_doc(&self, doc: &lopdf::Document) -> bool {
            match self.d {
                Detail::PageCount(n) => n == doc.get_num_pages(),
                Detail::CreationDate(d) => doc.get_creation_date().map_or(false, |date| date == d),
            }
        }

        fn find_case_for_doc<'a>(
            &'a self,
            expected: bool,
            doc: &lopdf::Document,
        ) -> Option<Case<'a>> {
            if self.eval_doc(doc) == expected {
                let product = self.product_for_doc(doc);
                Some(Case::new(Some(self), false).add_product(product))
            } else {
                None
            }
        }

        fn product_for_doc(&self, doc: &lopdf::Document) -> Product {
            match self.d {
                Detail::PageCount(_) => Product::new(
                    "actual page count",
                    format!("{} page(s)", doc.get_num_pages()),
                ),
                Detail::CreationDate(_) => Product::new(
                    "actual creation date",
                    format!("{:?}", doc.get_creation_date()),
                ),
            }
        }
    }

    impl Details for lopdf::Document {
        fn get_creation_date(self: &Self) -> Option<DateTime<Utc>> {
            fn get_from_trailer<'a>(
                doc: &'a lopdf::Document,
                key: &[u8],
            ) -> lopdf::Result<&'a lopdf::Object> {
                let id = doc.trailer.get(b"Info")?.as_reference()?;
                doc.get_object(id)?.as_dict()?.get(key)
            }

            if let Ok(obj) = get_from_trailer(self, b"CreationDate") {
                // Now this should actually be as simple as returning obj.as_datetime().
                // However there are bugs that need to be worked around here:
                //
                // First of all cairo inadvertently truncates the timezone offset,
                // see https://gitlab.freedesktop.org/cairo/cairo/issues/392
                //
                // On top of that the lopdf::Object::as_datetime() method has issues
                // and can not be used, see https://github.com/J-F-Liu/lopdf/issues/88
                //
                // So here's our implentation instead.

                fn as_datetime(str: &str) -> Option<DateTime<FixedOffset>> {
                    if str.ends_with("0000") {
                        DateTime::parse_from_str(str, "%Y%m%d%H%M%S%z").ok()
                    } else {
                        let str = String::from(str) + "00";
                        as_datetime(&str)
                    }
                }

                if let lopdf::Object::String(ref bytes, _) = obj {
                    if let Ok(str) = String::from_utf8(
                        bytes
                            .iter()
                            .filter(|b| ![b'D', b':', b'\''].contains(b))
                            .cloned()
                            .collect(),
                    ) {
                        return as_datetime(&str).map(|date| date.with_timezone(&Utc));
                    }
                }
            }
            None
        }

        fn get_num_pages(self: &Self) -> usize {
            self.get_pages().len()
        }
    }

    impl Predicate<[u8]> for DetailPredicate<PdfPredicate> {
        fn eval(&self, data: &[u8]) -> bool {
            match lopdf::Document::load_mem(data) {
                Ok(doc) => self.eval_doc(&doc),
                _ => false,
            }
        }

        fn find_case<'a>(&'a self, expected: bool, data: &[u8]) -> Option<Case<'a>> {
            match lopdf::Document::load_mem(data) {
                Ok(doc) => self.find_case_for_doc(expected, &doc),
                Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
            }
        }
    }

    impl PredicateReflection for DetailPredicate<PdfPredicate> {
        fn children<'a>(&'a self) -> Box<dyn Iterator<Item = Child<'a>> + 'a> {
            let params = vec![Child::new("predicate", &self.p)];
            Box::new(params.into_iter())
        }
    }

    impl fmt::Display for DetailPredicate<PdfPredicate> {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            match self.d {
                Detail::PageCount(n) => write!(f, "is a PDF with {} page(s)", n),
                Detail::CreationDate(d) => write!(f, "is a PDF created {:?}", d),
            }
        }
    }

    /// Checks that the variable of type [u8] can be parsed as a PNG file.
    #[derive(Debug)]
    pub struct PngPredicate {}

    impl PngPredicate {
        pub fn with_size(self: Self, w: u32, h: u32) -> SizePredicate<Self> {
            SizePredicate::<Self> { p: self, w, h }
        }
    }

    impl Predicate<[u8]> for PngPredicate {
        fn eval(&self, data: &[u8]) -> bool {
            let decoder = png::Decoder::new(data);
            decoder.read_info().is_ok()
        }

        fn find_case<'a>(&'a self, _expected: bool, data: &[u8]) -> Option<Case<'a>> {
            let decoder = png::Decoder::new(data);
            match decoder.read_info() {
                Ok(_) => None,
                Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
            }
        }
    }

    impl PredicateReflection for PngPredicate {}

    impl fmt::Display for PngPredicate {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "is a PNG")
        }
    }

    /// Extends a PngPredicate by a check for a given size of the PNG file.
    #[derive(Debug)]
    pub struct SizePredicate<PngPredicate> {
        p: PngPredicate,
        w: u32,
        h: u32,
    }

    impl SizePredicate<PngPredicate> {
        fn eval_info(&self, info: &png::OutputInfo) -> bool {
            info.width == self.w && info.height == self.h
        }

        fn find_case_for_info<'a>(
            &'a self,
            expected: bool,
            info: &png::OutputInfo,
        ) -> Option<Case<'a>> {
            if self.eval_info(info) == expected {
                let product = self.product_for_info(info);
                Some(Case::new(Some(self), false).add_product(product))
            } else {
                None
            }
        }

        fn product_for_info(&self, info: &png::OutputInfo) -> Product {
            let actual_size = format!("{} x {}", info.width, info.height);
            Product::new("actual size", actual_size)
        }
    }

    impl Predicate<[u8]> for SizePredicate<PngPredicate> {
        fn eval(&self, data: &[u8]) -> bool {
            let decoder = png::Decoder::new(data);
            match decoder.read_info() {
                Ok((info, _)) => self.eval_info(&info),
                _ => false,
            }
        }

        fn find_case<'a>(&'a self, expected: bool, data: &[u8]) -> Option<Case<'a>> {
            let decoder = png::Decoder::new(data);
            match decoder.read_info() {
                Ok((info, _)) => self.find_case_for_info(expected, &info),
                Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
            }
        }
    }

    impl PredicateReflection for SizePredicate<PngPredicate> {
        fn children<'a>(&'a self) -> Box<dyn Iterator<Item = Child<'a>> + 'a> {
            let params = vec![Child::new("predicate", &self.p)];
            Box::new(params.into_iter())
        }
    }

    impl fmt::Display for SizePredicate<PngPredicate> {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "is a PNG with size {} x {}", self.w, self.h)
        }
    }

    /// Predicates to check that some output ([u8]) is of a certain file type

    pub fn is_png() -> PngPredicate {
        PngPredicate {}
    }

    pub fn is_ps() -> StartsWithPredicate {
        predicate::str::starts_with("%!PS-Adobe-3.0\n")
    }

    pub fn is_eps() -> StartsWithPredicate {
        predicate::str::starts_with("%!PS-Adobe-3.0 EPSF-3.0\n")
    }

    pub fn is_pdf() -> PdfPredicate {
        PdfPredicate {}
    }

    pub fn is_svg() -> AndPredicate<StartsWithPredicate, ContainsPredicate, str> {
        predicate::str::starts_with("<?xml ").and(predicate::str::contains("<svg "))
    }
}
<commit_msg>Remove obsolete workarounds for datetime parsing<commit_after>extern crate chrono;
extern crate lopdf;
extern crate png;
extern crate predicates;

pub mod file {

    use chrono::{DateTime, Utc};

    use predicates::boolean::AndPredicate;
    use predicates::prelude::*;
    use predicates::reflection::{Case, Child, PredicateReflection, Product};
    use predicates::str::{ContainsPredicate, StartsWithPredicate};

    use std::fmt;

    /// Checks that the variable of type [u8] can be parsed as a PDF file.
    #[derive(Debug)]
    pub struct PdfPredicate {}

    impl PdfPredicate {
        pub fn with_page_count(self: Self, num_pages: usize) -> DetailPredicate<Self> {
            DetailPredicate::<Self> {
                p: self,
                d: Detail::PageCount(num_pages),
            }
        }

        pub fn with_creation_date(self: Self, when: DateTime<Utc>) -> DetailPredicate<Self> {
            DetailPredicate::<Self> {
                p: self,
                d: Detail::CreationDate(when),
            }
        }
    }

    impl Predicate<[u8]> for PdfPredicate {
        fn eval(&self, data: &[u8]) -> bool {
            lopdf::Document::load_mem(data).is_ok()
        }

        fn find_case<'a>(&'a self, _expected: bool, data: &[u8]) -> Option<Case<'a>> {
            match lopdf::Document::load_mem(data) {
                Ok(_) => None,
                Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
            }
        }
    }

    impl PredicateReflection for PdfPredicate {}

    impl fmt::Display for PdfPredicate {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "is a PDF")
        }
    }

    /// Extends a PdfPredicate by a check for page count or creation date.
    #[derive(Debug)]
    pub struct DetailPredicate<PdfPredicate> {
        p: PdfPredicate,
        d: Detail,
    }

    #[derive(Debug)]
    enum Detail {
        PageCount(usize),
        CreationDate(DateTime<Utc>),
    }

    trait Details {
        fn get_num_pages(&self) -> usize;
        fn get_creation_date(&self) -> Option<DateTime<Utc>>;
    }

    impl DetailPredicate<PdfPredicate> {
        fn eval_doc(&self, doc: &lopdf::Document) -> bool {
            match self.d {
                Detail::PageCount(n) => n == doc.get_num_pages(),
                Detail::CreationDate(d) => doc.get_creation_date().map_or(false, |date| date == d),
            }
        }

        fn find_case_for_doc<'a>(
            &'a self,
            expected: bool,
            doc: &lopdf::Document,
        ) -> Option<Case<'a>> {
            if self.eval_doc(doc) == expected {
                let product = self.product_for_doc(doc);
                Some(Case::new(Some(self), false).add_product(product))
            } else {
                None
            }
        }

        fn product_for_doc(&self, doc: &lopdf::Document) -> Product {
            match self.d {
                Detail::PageCount(_) => Product::new(
                    "actual page count",
                    format!("{} page(s)", doc.get_num_pages()),
                ),
                Detail::CreationDate(_) => Product::new(
                    "actual creation date",
                    format!("{:?}", doc.get_creation_date()),
                ),
            }
        }
    }

    impl Details for lopdf::Document {
        fn get_creation_date(self: &Self) -> Option<DateTime<Utc>> {
            fn get_from_trailer<'a>(
                doc: &'a lopdf::Document,
                key: &[u8],
            ) -> lopdf::Result<&'a lopdf::Object> {
                let id = doc.trailer.get(b"Info")?.as_reference()?;
                doc.get_object(id)?.as_dict()?.get(key)
            }

            match get_from_trailer(self, b"CreationDate") {
                Ok(obj) => obj.as_datetime().map(|date| date.with_timezone(&Utc)),
                Err(_) => None,
            }
        }

        fn get_num_pages(self: &Self) -> usize {
            self.get_pages().len()
        }
    }

    impl Predicate<[u8]> for DetailPredicate<PdfPredicate> {
        fn eval(&self, data: &[u8]) -> bool {
            match lopdf::Document::load_mem(data) {
                Ok(doc) => self.eval_doc(&doc),
                _ => false,
            }
        }

        fn find_case<'a>(&'a self, expected: bool, data: &[u8]) -> Option<Case<'a>> {
            match lopdf::Document::load_mem(data) {
                Ok(doc) => self.find_case_for_doc(expected, &doc),
                Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
            }
        }
    }

    impl PredicateReflection for DetailPredicate<PdfPredicate> {
        fn children<'a>(&'a self) -> Box<dyn Iterator<Item = Child<'a>> + 'a> {
            let params = vec![Child::new("predicate", &self.p)];
            Box::new(params.into_iter())
        }
    }

    impl fmt::Display for DetailPredicate<PdfPredicate> {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            match self.d {
                Detail::PageCount(n) => write!(f, "is a PDF with {} page(s)", n),
                Detail::CreationDate(d) => write!(f, "is a PDF created {:?}", d),
            }
        }
    }

    /// Checks that the variable of type [u8] can be parsed as a PNG file.
    #[derive(Debug)]
    pub struct PngPredicate {}

    impl PngPredicate {
        pub fn with_size(self: Self, w: u32, h: u32) -> SizePredicate<Self> {
            SizePredicate::<Self> { p: self, w, h }
        }
    }

    impl Predicate<[u8]> for PngPredicate {
        fn eval(&self, data: &[u8]) -> bool {
            let decoder = png::Decoder::new(data);
            decoder.read_info().is_ok()
        }

        fn find_case<'a>(&'a self, _expected: bool, data: &[u8]) -> Option<Case<'a>> {
            let decoder = png::Decoder::new(data);
            match decoder.read_info() {
                Ok(_) => None,
                Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
            }
        }
    }

    impl PredicateReflection for PngPredicate {}

    impl fmt::Display for PngPredicate {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "is a PNG")
        }
    }

    /// Extends a PngPredicate by a check for a given size of the PNG file.
    #[derive(Debug)]
    pub struct SizePredicate<PngPredicate> {
        p: PngPredicate,
        w: u32,
        h: u32,
    }

    impl SizePredicate<PngPredicate> {
        fn eval_info(&self, info: &png::OutputInfo) -> bool {
            info.width == self.w && info.height == self.h
        }

        fn find_case_for_info<'a>(
            &'a self,
            expected: bool,
            info: &png::OutputInfo,
        ) -> Option<Case<'a>> {
            if self.eval_info(info) == expected {
                let product = self.product_for_info(info);
                Some(Case::new(Some(self), false).add_product(product))
            } else {
                None
            }
        }

        fn product_for_info(&self, info: &png::OutputInfo) -> Product {
            let actual_size = format!("{} x {}", info.width, info.height);
            Product::new("actual size", actual_size)
        }
    }

    impl Predicate<[u8]> for SizePredicate<PngPredicate> {
        fn eval(&self, data: &[u8]) -> bool {
            let decoder = png::Decoder::new(data);
            match decoder.read_info() {
                Ok((info, _)) => self.eval_info(&info),
                _ => false,
            }
        }

        fn find_case<'a>(&'a self, expected: bool, data: &[u8]) -> Option<Case<'a>> {
            let decoder = png::Decoder::new(data);
            match decoder.read_info() {
                Ok((info, _)) => self.find_case_for_info(expected, &info),
                Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
            }
        }
    }

    impl PredicateReflection for SizePredicate<PngPredicate> {
        fn children<'a>(&'a self) -> Box<dyn Iterator<Item = Child<'a>> + 'a> {
            let params = vec![Child::new("predicate", &self.p)];
            Box::new(params.into_iter())
        }
    }

    impl fmt::Display for SizePredicate<PngPredicate> {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "is a PNG with size {} x {}", self.w, self.h)
        }
    }

    /// Predicates to check that some output ([u8]) is of a certain file type

    pub fn is_png() -> PngPredicate {
        PngPredicate {}
    }

    pub fn is_ps() -> StartsWithPredicate {
        predicate::str::starts_with("%!PS-Adobe-3.0\n")
    }

    pub fn is_eps() -> StartsWithPredicate {
        predicate::str::starts_with("%!PS-Adobe-3.0 EPSF-3.0\n")
    }

    pub fn is_pdf() -> PdfPredicate {
        PdfPredicate {}
    }

    pub fn is_svg() -> AndPredicate<StartsWithPredicate, ContainsPredicate, str> {
        predicate::str::starts_with("<?xml ").and(predicate::str::contains("<svg "))
    }
}
<|endoftext|>