<commit_before>use std::io::{self, Read, Write, Seek, SeekFrom};
use std::fs::File;
use std::path::Path;
use std::env;
use std;

use super::imp;

/// An unnamed temporary file.
///
/// This variant is secure/reliable in the presence of a pathological temporary file cleaner.
///
/// Deletion:
///
/// Linux >= 3.11: The temporary file is never linked into the filesystem so it can't be leaked.
///
/// Other *nix: The temporary file is immediately unlinked on create. The OS will delete it when
/// the last open copy of it is closed (the last TempFile reference to it is dropped).
///
/// Windows: The temporary file is marked DeleteOnClose and, again, will be deleted when the last
/// open copy of it is closed. Unlike *nix operating systems, the file is not immediately unlinked
/// from the filesystem.
pub struct TempFile(File);

impl TempFile {
    /// Create a new temporary file.
    #[inline]
    pub fn new() -> io::Result<TempFile> {
        Self::new_in(&env::temp_dir())
    }

    /// Create a new temporary file in the specified directory.
    #[inline]
    pub fn new_in<P: AsRef<Path>>(dir: P) -> io::Result<TempFile> {
        imp::create(dir.as_ref()).map(|f| TempFile(f))
    }

    /// Create a new temporary file and open it `count` times returning `count` independent
    /// references to the same file.
    ///
    /// This can be useful if you want multiple seek positions in the same temporary file.
    /// Additionally, this function guarantees that all of the returned temporary file objects
    /// refer to the same underlying temporary file even in the presence of a pathological
    /// temporary file cleaner.
    #[inline]
    pub fn shared(count: usize) -> io::Result<Vec<TempFile>> {
        Self::shared_in(&env::temp_dir(), count)
    }

    /// Same as `shared` but creates the file in the specified directory.
    #[inline]
    pub fn shared_in<P: AsRef<Path>>(dir: P, count: usize) -> io::Result<Vec<TempFile>> {
        imp::create_shared(dir.as_ref(), count).map(|files| {
            files.into_iter().map(|f|TempFile(f)).collect()
        })
    }

    /// Number of bytes in the file.
    #[inline]
    pub fn len(&self) -> io::Result<u64> {
        self.0.metadata().map(|m| m.len())
    }

    /// Truncate the file to `size` bytes.
    #[inline(always)]
    pub fn set_len(&self, size: u64) -> io::Result<()> {
        self.0.set_len(size)
    }
}

impl Read for TempFile {
    #[inline(always)]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }
}

impl Write for TempFile {
    #[inline(always)]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }
    #[inline(always)]
    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}

impl Seek for TempFile {
    #[inline(always)]
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        self.0.seek(pos)
    }
}

#[cfg(unix)]
impl std::os::unix::io::AsRawFd for TempFile {
    #[inline(always)]
    fn as_raw_fd(&self) -> std::os::unix::io::RawFd {
        self.0.as_raw_fd()
    }
}

#[cfg(windows)]
impl std::os::windows::io::AsRawHandle for TempFile {
    #[inline(always)]
    fn as_raw_handle(&self) -> std::os::windows::io::RawHandle {
        self.0.as_raw_handle()
    }
}

<commit_msg>Implement debug for unnamed tempfiles.<commit_after>use std::io::{self, Read, Write, Seek, SeekFrom};
use std::fs::File;
use std::fmt;
use std::path::Path;
use std::env;
use std;

use super::imp;

/// An unnamed temporary file.
///
/// This variant is secure/reliable in the presence of a pathological temporary file cleaner.
///
/// Deletion:
///
/// Linux >= 3.11: The temporary file is never linked into the filesystem so it can't be leaked.
///
/// Other *nix: The temporary file is immediately unlinked on create. The OS will delete it when
/// the last open copy of it is closed (the last TempFile reference to it is dropped).
///
/// Windows: The temporary file is marked DeleteOnClose and, again, will be deleted when the last
/// open copy of it is closed. Unlike *nix operating systems, the file is not immediately unlinked
/// from the filesystem.
pub struct TempFile(File);

impl fmt::Debug for TempFile {
    #[cfg(unix)]
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use std::os::unix::io::AsRawFd;
        write!(f, "TempFile({})", self.0.as_raw_fd())
    }

    #[cfg(windows)]
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use std::os::windows::io::AsRawHandle;
        write!(f, "TempFile({})", self.0.as_raw_handle() as usize)
    }
}

impl TempFile {
    /// Create a new temporary file.
    #[inline]
    pub fn new() -> io::Result<TempFile> {
        Self::new_in(&env::temp_dir())
    }

    /// Create a new temporary file in the specified directory.
    #[inline]
    pub fn new_in<P: AsRef<Path>>(dir: P) -> io::Result<TempFile> {
        imp::create(dir.as_ref()).map(|f| TempFile(f))
    }

    /// Create a new temporary file and open it `count` times returning `count` independent
    /// references to the same file.
    ///
    /// This can be useful if you want multiple seek positions in the same temporary file.
    /// Additionally, this function guarantees that all of the returned temporary file objects
    /// refer to the same underlying temporary file even in the presence of a pathological
    /// temporary file cleaner.
    #[inline]
    pub fn shared(count: usize) -> io::Result<Vec<TempFile>> {
        Self::shared_in(&env::temp_dir(), count)
    }

    /// Same as `shared` but creates the file in the specified directory.
    #[inline]
    pub fn shared_in<P: AsRef<Path>>(dir: P, count: usize) -> io::Result<Vec<TempFile>> {
        imp::create_shared(dir.as_ref(), count).map(|files| {
            files.into_iter().map(|f|TempFile(f)).collect()
        })
    }

    /// Number of bytes in the file.
    #[inline]
    pub fn len(&self) -> io::Result<u64> {
        self.0.metadata().map(|m| m.len())
    }

    /// Truncate the file to `size` bytes.
    #[inline(always)]
    pub fn set_len(&self, size: u64) -> io::Result<()> {
        self.0.set_len(size)
    }
}

impl Read for TempFile {
    #[inline(always)]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }
}

impl Write for TempFile {
    #[inline(always)]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }
    #[inline(always)]
    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}

impl Seek for TempFile {
    #[inline(always)]
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        self.0.seek(pos)
    }
}

#[cfg(unix)]
impl std::os::unix::io::AsRawFd for TempFile {
    #[inline(always)]
    fn as_raw_fd(&self) -> std::os::unix::io::RawFd {
        self.0.as_raw_fd()
    }
}

#[cfg(windows)]
impl std::os::windows::io::AsRawHandle for TempFile {
    #[inline(always)]
    fn as_raw_handle(&self) -> std::os::windows::io::RawHandle {
        self.0.as_raw_handle()
    }
}

<|endoftext|>


<commit_before>/// A type to represent all supported types for parser 'get'-like functions
#[derive(Clone, Debug, PartialEq)]
pub enum Variant<'a> {
    Bool(bool),
    Bytes(&'a [u8]),
    Str(&'a str),
    I8(i8),
    I16(i16),
    I32(i32),
    I64(i64),
    U8(u8),
    U16(u16),
    U32(u32),
    U64(u64),
    USize(usize),

    List(Box<Vec<Variant<'a>>>),

    OwnedStr(String),
}

impl<'a> Variant<'a> {
    pub fn from_slice<T>(v: &'a [T]) -> Variant<'a>
    where
        Variant<'a>: From<&'a T>,
    {
        let v = v.iter().map(|s| Variant::from(s)).collect();
        Variant::List(Box::new(v))
    }

    pub fn from_vec<T>(v: &'a Vec<T>) -> Variant<'a>
    where
        Variant<'a>: From<&'a T>,
    {
        let v = v.iter().map(|s| Variant::from(s)).collect();
        Variant::List(Box::new(v))
    }
}

use std::convert::From;

macro_rules! variant_from_primitive {
    ( $t:ty, $it:expr ) => {
        impl<'a> From<$t> for Variant<'a> {
            fn from(input: $t) -> Self {
                $it(input)
            }
        }
    };
}

variant_from_primitive!(bool, Variant::Bool);
variant_from_primitive!(i8, Variant::I8);
variant_from_primitive!(i16, Variant::I16);
variant_from_primitive!(i32, Variant::I32);
variant_from_primitive!(i64, Variant::I64);
variant_from_primitive!(u8, Variant::U8);
variant_from_primitive!(u16, Variant::U16);
variant_from_primitive!(u32, Variant::U32);
variant_from_primitive!(u64, Variant::U64);
variant_from_primitive!(usize, Variant::USize);
impl<'a> From<&'a [u8]> for Variant<'a> {
    fn from(input: &'a [u8]) -> Self {
        Variant::Bytes(input)
    }
}

impl<'a> From<&'a str> for Variant<'a> {
    fn from(input: &'a str) -> Self {
        Variant::Str(input)
    }
}

impl<'a> From<&'a String> for Variant<'a> {
    fn from(input: &'a String) -> Self {
        Variant::Str(&input)
    }
}

#[macro_export]
macro_rules! gen_get_variants {
    // Entry point
    ($t:ident, $ns:tt, $($body:tt)* ) => {
        fn get<'b>(&'b self, key: &str) -> Option<Variant<'b>> {
            gen_get_variants!{ @gen_match $ns $t {}, self, key, $($body)* }
        }
        fn keys(&self) -> ::std::slice::Iter<&str> {
            gen_get_variants!{ @gen_keys $ns [], $($body)* }
        }
    };
    //
    // MATCH ARMS
    //
    // Simple closure case
    (@gen_match $ns:tt $t:ident {$($arms:tt)*}, $self:ident, $key:ident, $pattern:ident => |$s:ident| $closure:expr, $($tail:tt)*) => {
        gen_get_variants!{
            @gen_match
            $ns
            $t
            {
                $($arms)*
                concat!($ns, stringify!{$pattern}) => {
                    let closure = |$s: &'b $t| $closure;
                    closure($self)
                },
            },
            $self,
            $key,
            $($tail)*
        }
    };
    // Shortcut: into
    (@gen_match $ns:tt $t:ident {$($arms:tt)*}, $self:ident, $key:ident, $pattern:ident => into, $($tail:tt)*) => {
        gen_get_variants!{
            @gen_match
            $ns
            $t
            {
                $($arms)*
                concat!($ns, stringify!{$pattern}) => {
                    Some($self.$pattern.into())
                },
            },
            $self,
            $key,
            $($tail)*
        }
    };
    // Shortcut: map
    (@gen_match $ns:tt $t:ident {$($arms:tt)*}, $self:ident, $key:ident, $pattern:ident => map, $($tail:tt)*) => {
        gen_get_variants!{
            @gen_match
            $ns
            $t
            {
                $($arms)*
                concat!($ns, stringify!{$pattern}) => {
                    $self.$pattern.map(|p| p.into())
                },
            },
            $self,
            $key,
            $($tail)*
        }
    };
    // Shortcut: map_as_ref
    (@gen_match $ns:tt $t:ident {$($arms:tt)*}, $self:ident, $key:ident, $pattern:ident => map_as_ref, $($tail:tt)*) => {
        gen_get_variants!{
            @gen_match
            $ns
            $t
            {
                $($arms)*
                concat!($ns, stringify!{$pattern}) => {
                    $self.$pattern.as_ref().map(|p| p.into())
                },
            },
            $self,
            $key,
            $($tail)*
        }
    };
    // Termination rule
    (@gen_match $ns:tt $t:ident {$($arms:tt)*}, $self:ident, $key:ident, /* $($body:tt)* */  $(,)* ) => {
        match $key {
            $($arms)*
            _ => None
        }
    };
    //
    // KEYS
    //
    // Simple closure case
    (@gen_keys $ns:tt [$($arms:tt)*], $pattern:tt => |$s:ident| $closure:expr, $($tail:tt)*) => {
        gen_get_variants!{
            @gen_keys
            $ns
            [
                $($arms)* concat!($ns, stringify!{$pattern}),
            ],
            $($tail)*
        }
    };
    // Shortcut: into
    (@gen_keys $ns:tt [$($arms:tt)*], $pattern:ident => $kw:tt, $($tail:tt)*) => {
        gen_get_variants!{
            @gen_keys
            $ns
            [
                $($arms)* concat!($ns, stringify!{$pattern}),
            ],
            $($tail)*
        }
    };
    // Termination rule
    (@gen_keys $ns:tt [$($keys:tt)*], /* $($body:tt)* */  $(,)* ) => {
        [
            $($keys)*
        ].iter()
    };
}

#[cfg(test)]
mod tests {
    use super::Variant;
    use std::mem;

    #[test]
    fn variant_size() {
        // expected: 32: 8 (variant) + 24 (String)
        println!("sizeof Variant: {}", mem::size_of::<Variant>());
    }
}
<commit_msg>Replace Box<Vec<T>> with Vec<T>. This is the last clippy warning!<commit_after>/// A type to represent all supported types for parser 'get'-like functions
#[derive(Clone, Debug, PartialEq)]
pub enum Variant<'a> {
    Bool(bool),
    Bytes(&'a [u8]),
    Str(&'a str),
    I8(i8),
    I16(i16),
    I32(i32),
    I64(i64),
    U8(u8),
    U16(u16),
    U32(u32),
    U64(u64),
    USize(usize),

    List(Vec<Variant<'a>>),

    OwnedStr(String),
}

impl<'a> Variant<'a> {
    pub fn from_slice<T>(v: &'a [T]) -> Variant<'a>
    where
        Variant<'a>: From<&'a T>,
    {
        let v = v.iter().map(|s| Variant::from(s)).collect();
        Variant::List(v)
    }
}

use std::convert::From;

macro_rules! variant_from_primitive {
    ( $t:ty, $it:expr ) => {
        impl<'a> From<$t> for Variant<'a> {
            fn from(input: $t) -> Self {
                $it(input)
            }
        }
    };
}

variant_from_primitive!(bool, Variant::Bool);
variant_from_primitive!(i8, Variant::I8);
variant_from_primitive!(i16, Variant::I16);
variant_from_primitive!(i32, Variant::I32);
variant_from_primitive!(i64, Variant::I64);
variant_from_primitive!(u8, Variant::U8);
variant_from_primitive!(u16, Variant::U16);
variant_from_primitive!(u32, Variant::U32);
variant_from_primitive!(u64, Variant::U64);
variant_from_primitive!(usize, Variant::USize);
impl<'a> From<&'a [u8]> for Variant<'a> {
    fn from(input: &'a [u8]) -> Self {
        Variant::Bytes(input)
    }
}

impl<'a> From<&'a str> for Variant<'a> {
    fn from(input: &'a str) -> Self {
        Variant::Str(input)
    }
}

impl<'a> From<&'a String> for Variant<'a> {
    fn from(input: &'a String) -> Self {
        Variant::Str(&input)
    }
}

#[macro_export]
macro_rules! gen_get_variants {
    // Entry point
    ($t:ident, $ns:tt, $($body:tt)* ) => {
        fn get<'b>(&'b self, key: &str) -> Option<Variant<'b>> {
            gen_get_variants!{ @gen_match $ns $t {}, self, key, $($body)* }
        }
        fn keys(&self) -> ::std::slice::Iter<&str> {
            gen_get_variants!{ @gen_keys $ns [], $($body)* }
        }
    };
    //
    // MATCH ARMS
    //
    // Simple closure case
    (@gen_match $ns:tt $t:ident {$($arms:tt)*}, $self:ident, $key:ident, $pattern:ident => |$s:ident| $closure:expr, $($tail:tt)*) => {
        gen_get_variants!{
            @gen_match
            $ns
            $t
            {
                $($arms)*
                concat!($ns, stringify!{$pattern}) => {
                    let closure = |$s: &'b $t| $closure;
                    closure($self)
                },
            },
            $self,
            $key,
            $($tail)*
        }
    };
    // Shortcut: into
    (@gen_match $ns:tt $t:ident {$($arms:tt)*}, $self:ident, $key:ident, $pattern:ident => into, $($tail:tt)*) => {
        gen_get_variants!{
            @gen_match
            $ns
            $t
            {
                $($arms)*
                concat!($ns, stringify!{$pattern}) => {
                    Some($self.$pattern.into())
                },
            },
            $self,
            $key,
            $($tail)*
        }
    };
    // Shortcut: map
    (@gen_match $ns:tt $t:ident {$($arms:tt)*}, $self:ident, $key:ident, $pattern:ident => map, $($tail:tt)*) => {
        gen_get_variants!{
            @gen_match
            $ns
            $t
            {
                $($arms)*
                concat!($ns, stringify!{$pattern}) => {
                    $self.$pattern.map(|p| p.into())
                },
            },
            $self,
            $key,
            $($tail)*
        }
    };
    // Shortcut: map_as_ref
    (@gen_match $ns:tt $t:ident {$($arms:tt)*}, $self:ident, $key:ident, $pattern:ident => map_as_ref, $($tail:tt)*) => {
        gen_get_variants!{
            @gen_match
            $ns
            $t
            {
                $($arms)*
                concat!($ns, stringify!{$pattern}) => {
                    $self.$pattern.as_ref().map(|p| p.into())
                },
            },
            $self,
            $key,
            $($tail)*
        }
    };
    // Termination rule
    (@gen_match $ns:tt $t:ident {$($arms:tt)*}, $self:ident, $key:ident, /* $($body:tt)* */  $(,)* ) => {
        match $key {
            $($arms)*
            _ => None
        }
    };
    //
    // KEYS
    //
    // Simple closure case
    (@gen_keys $ns:tt [$($arms:tt)*], $pattern:tt => |$s:ident| $closure:expr, $($tail:tt)*) => {
        gen_get_variants!{
            @gen_keys
            $ns
            [
                $($arms)* concat!($ns, stringify!{$pattern}),
            ],
            $($tail)*
        }
    };
    // Shortcut: into
    (@gen_keys $ns:tt [$($arms:tt)*], $pattern:ident => $kw:tt, $($tail:tt)*) => {
        gen_get_variants!{
            @gen_keys
            $ns
            [
                $($arms)* concat!($ns, stringify!{$pattern}),
            ],
            $($tail)*
        }
    };
    // Termination rule
    (@gen_keys $ns:tt [$($keys:tt)*], /* $($body:tt)* */  $(,)* ) => {
        [
            $($keys)*
        ].iter()
    };
}

#[cfg(test)]
mod tests {
    use super::Variant;
    use std::mem;

    #[test]
    fn variant_size() {
        // expected: 32: 8 (variant) + 24 (String)
        println!("sizeof Variant: {}", mem::size_of::<Variant>());
    }
}
<|endoftext|>


<commit_before>pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");
pub const MINECRAFT: &'static str = "1.11";
pub const ASSETS: &'static str = "1.11";
pub const PROTOCOL: u16 = 315;
<commit_msg>Change Version<commit_after>pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");
pub const MINECRAFT: &'static str = "1.11.2";
pub const ASSETS: &'static str = "1.11";
pub const PROTOCOL: u16 = 316;
<|endoftext|>


<commit_before>#![feature(test)]
#![allow(unused_imports)]

extern crate test;
extern crate ndarray;

use ndarray::{Array, S, Si};
use ndarray::{arr0, arr1, arr2};

use test::black_box;

#[bench]
fn bench_std_add(bench: &mut test::Bencher)
{
    let mut a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    let b = a.clone();
    bench.iter(|| a.iadd(&b));
}

#[bench]
fn bench_std_iter_1d(bench: &mut test::Bencher)
{
    let a = arr1::<f32>(&[1., 2., 2.,
                         3., 4., 4.,
                         3., 4., 4.,
                         3., 4., 4.,
                         5., 6., 6.]);
    bench.iter(|| for &elt in a.iter() { black_box(elt); })
}

#[bench]
fn bench_std_iter_1d_raw(bench: &mut test::Bencher)
{
    let a = arr1::<f32>(&[1., 2., 2.,
                         3., 4., 4.,
                         3., 4., 4.,
                         3., 4., 4.,
                         5., 6., 6.]);
    bench.iter(|| for &elt in a.raw_data().iter() { black_box(elt); })
}

#[bench]
fn bench_std_iter_2d(bench: &mut test::Bencher)
{
    let a = arr2::<f32, _>(&[[1., 2., 2.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [5., 6., 6.]]);
    bench.iter(|| for &elt in a.iter() { black_box(elt); })
}

#[bench]
fn bench_std_iter_1d_large(bench: &mut test::Bencher)
{
    let a = Array::<i32, _>::zeros(64 * 64);
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.iter() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn bench_std_iter_1d_raw_large(bench: &mut test::Bencher)
{
    // this is autovectorized to death (= great performance)
    let a = Array::<i32, _>::zeros(64 * 64);
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.raw_data() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn bench_std_iter_2d_large(bench: &mut test::Bencher)
{
    let a = Array::<i32, _>::zeros((64, 64));
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.iter() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn bench_std_iter_2d_raw_large(bench: &mut test::Bencher)
{
    // this is autovectorized to death (= great performance)
    let a = Array::<i32, _>::zeros((64, 64));
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.raw_data() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn assign_scalar_2d_transposed(bench: &mut test::Bencher)
{
    let mut a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    a.swap_axes(0, 1);
    bench.iter(|| a.assign_scalar(&3.))
}

#[bench]
fn assign_scalar_2d(bench: &mut test::Bencher)
{
    let mut a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    bench.iter(|| a.assign_scalar(&3.))
}

#[bench]
fn assign_scalar_2d_large(bench: &mut test::Bencher)
{
    let a = Array::zeros((64, 64));
    let mut a = black_box(a);
    let s = black_box(3.);
    bench.iter(|| a.assign_scalar(&s))
}

#[bench]
fn assign_scalar_2d_transposed_large(bench: &mut test::Bencher)
{
    let mut a = Array::zeros((64, 64));
    a.swap_axes(0, 1);
    let mut a = black_box(a);
    let s = black_box(3.);
    bench.iter(|| a.assign_scalar(&s))
}

#[bench]
fn assign_scalar_2d_raw_large(bench: &mut test::Bencher)
{
    let a = Array::zeros((64, 64));
    let mut a = black_box(a);
    let s = black_box(3.);
    bench.iter(|| for elt in a.raw_data_mut() { *elt = s; });
}

#[bench]
fn bench_iter_diag(bench: &mut test::Bencher)
{
    let a = Array::<f32, _>::zeros((1024, 1024));
    bench.iter(|| for elt in a.diag_iter() { black_box(elt); })
}

#[bench]
fn bench_row_iter(bench: &mut test::Bencher)
{
    let a = Array::<f32, _>::zeros((1024, 1024));
    let it = a.row_iter(17);
    bench.iter(|| for elt in it.clone() { black_box(elt); })
}

#[bench]
fn bench_col_iter(bench: &mut test::Bencher)
{
    let a = Array::<f32, _>::zeros((1024, 1024));
    bench.iter(|| for elt in a.col_iter(17) { black_box(elt); })
}

#[bench]
fn bench_mat_mul(bench: &mut test::Bencher)
{
    let a = arr2::<f32, _>(&[[1., 2., 2.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [5., 6., 6.]]);
    let mut at = a.clone();
    at.swap_axes(0, 1);
    bench.iter(|| at.mat_mul(&a));
}

#[bench]
fn lst_squares(bench: &mut test::Bencher)
{
    let xs = arr2::<f32, _>(&[[ 2.,  3.],
                           [-2., -1.],
                           [ 1.,  5.],
                           [-1.,  2.]]);
    let b = arr1(&[1., -1., 2., 1.]);
    bench.iter(|| ndarray::linalg::least_squares(&xs, &b));
}
<commit_msg>Add bench for owned array<commit_after>#![feature(test)]
#![allow(unused_imports)]

extern crate test;
extern crate ndarray;

use ndarray::{Array, S, Si};
use ndarray::{arr0, arr1, arr2};

use test::black_box;

#[bench]
fn bench_std_add_shared(bench: &mut test::Bencher)
{
    let mut a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    let b = a.clone();
    bench.iter(|| a.iadd(&b));
}

#[bench]
fn bench_std_add_owned(bench: &mut test::Bencher)
{
    let a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    let mut a = a.to_owned();
    let b = a.clone();
    bench.iter(|| a.iadd(&b));
}

#[bench]
fn bench_std_iter_1d(bench: &mut test::Bencher)
{
    let a = arr1::<f32>(&[1., 2., 2.,
                         3., 4., 4.,
                         3., 4., 4.,
                         3., 4., 4.,
                         5., 6., 6.]);
    bench.iter(|| for &elt in a.iter() { black_box(elt); })
}

#[bench]
fn bench_std_iter_1d_raw(bench: &mut test::Bencher)
{
    let a = arr1::<f32>(&[1., 2., 2.,
                         3., 4., 4.,
                         3., 4., 4.,
                         3., 4., 4.,
                         5., 6., 6.]);
    bench.iter(|| for &elt in a.raw_data().iter() { black_box(elt); })
}

#[bench]
fn bench_std_iter_2d(bench: &mut test::Bencher)
{
    let a = arr2::<f32, _>(&[[1., 2., 2.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [5., 6., 6.]]);
    bench.iter(|| for &elt in a.iter() { black_box(elt); })
}

#[bench]
fn bench_std_iter_1d_large(bench: &mut test::Bencher)
{
    let a = Array::<i32, _>::zeros(64 * 64);
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.iter() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn bench_std_iter_1d_raw_large(bench: &mut test::Bencher)
{
    // this is autovectorized to death (= great performance)
    let a = Array::<i32, _>::zeros(64 * 64);
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.raw_data() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn bench_std_iter_2d_large(bench: &mut test::Bencher)
{
    let a = Array::<i32, _>::zeros((64, 64));
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.iter() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn bench_std_iter_2d_raw_large(bench: &mut test::Bencher)
{
    // this is autovectorized to death (= great performance)
    let a = Array::<i32, _>::zeros((64, 64));
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.raw_data() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn assign_scalar_2d_transposed(bench: &mut test::Bencher)
{
    let mut a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    a.swap_axes(0, 1);
    bench.iter(|| a.assign_scalar(&3.))
}

#[bench]
fn assign_scalar_2d(bench: &mut test::Bencher)
{
    let mut a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    bench.iter(|| a.assign_scalar(&3.))
}

#[bench]
fn assign_scalar_2d_large(bench: &mut test::Bencher)
{
    let a = Array::zeros((64, 64));
    let mut a = black_box(a);
    let s = black_box(3.);
    bench.iter(|| a.assign_scalar(&s))
}

#[bench]
fn assign_scalar_2d_transposed_large(bench: &mut test::Bencher)
{
    let mut a = Array::zeros((64, 64));
    a.swap_axes(0, 1);
    let mut a = black_box(a);
    let s = black_box(3.);
    bench.iter(|| a.assign_scalar(&s))
}

#[bench]
fn assign_scalar_2d_raw_large(bench: &mut test::Bencher)
{
    let a = Array::zeros((64, 64));
    let mut a = black_box(a);
    let s = black_box(3.);
    bench.iter(|| for elt in a.raw_data_mut() { *elt = s; });
}

#[bench]
fn bench_iter_diag(bench: &mut test::Bencher)
{
    let a = Array::<f32, _>::zeros((1024, 1024));
    bench.iter(|| for elt in a.diag_iter() { black_box(elt); })
}

#[bench]
fn bench_row_iter(bench: &mut test::Bencher)
{
    let a = Array::<f32, _>::zeros((1024, 1024));
    let it = a.row_iter(17);
    bench.iter(|| for elt in it.clone() { black_box(elt); })
}

#[bench]
fn bench_col_iter(bench: &mut test::Bencher)
{
    let a = Array::<f32, _>::zeros((1024, 1024));
    bench.iter(|| for elt in a.col_iter(17) { black_box(elt); })
}

#[bench]
fn bench_mat_mul(bench: &mut test::Bencher)
{
    let a = arr2::<f32, _>(&[[1., 2., 2.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [5., 6., 6.]]);
    let mut at = a.clone();
    at.swap_axes(0, 1);
    bench.iter(|| at.mat_mul(&a));
}

#[bench]
fn lst_squares(bench: &mut test::Bencher)
{
    let xs = arr2::<f32, _>(&[[ 2.,  3.],
                           [-2., -1.],
                           [ 1.,  5.],
                           [-1.,  2.]]);
    let b = arr1(&[1., -1., 2., 1.]);
    bench.iter(|| ndarray::linalg::least_squares(&xs, &b));
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate test;
extern crate num;
extern crate rand;

use std::mem::replace;
use test::Bencher;
use num::{BigInt, BigUint, Zero, One, FromPrimitive};
use num::bigint::RandBigInt;
use rand::{SeedableRng, StdRng};

fn get_rng() -> StdRng {
    let seed: &[_] = &[1, 2, 3, 4];
    SeedableRng::from_seed(seed)
}

fn multiply_bench(b: &mut Bencher, xbits: usize, ybits: usize) {
    let mut rng = get_rng();
    let x = rng.gen_bigint(xbits);
    let y = rng.gen_bigint(ybits);

    b.iter(|| &x * &y);
}

fn divide_bench(b: &mut Bencher, xbits: usize, ybits: usize) {
    let mut rng = get_rng();
    let x = rng.gen_bigint(xbits);
    let y = rng.gen_bigint(ybits);

    b.iter(|| &x / &y);
}

fn factorial(n: usize) -> BigUint {
    let mut f: BigUint = One::one();
    for i in 1..(n+1) {
        let bu: BigUint = FromPrimitive::from_usize(i).unwrap();
        f = f * bu;
    }
    f
}

/// Compute Fibonacci numbers
fn fib(n: usize) -> BigUint {
    let mut f0: BigUint = Zero::zero();
    let mut f1: BigUint = One::one();
    for _ in 0..n {
        let f2 = f0 + &f1;
        f0 = replace(&mut f1, f2);
    }
    f0
}

/// Compute Fibonacci numbers with two ops per iteration
/// (add and subtract, like issue #200)
fn fib2(n: usize) -> BigUint {
    let mut f0: BigUint = Zero::zero();
    let mut f1: BigUint = One::one();
    for _ in 0..n {
        f1 = f1 + &f0;
        f0 = &f1 - f0;
    }
    f0
}

#[bench]
fn multiply_0(b: &mut Bencher) {
    multiply_bench(b, 1 << 8, 1 << 8);
}

#[bench]
fn multiply_1(b: &mut Bencher) {
    multiply_bench(b, 1 << 8, 1 << 16);
}

#[bench]
fn multiply_2(b: &mut Bencher) {
    multiply_bench(b, 1 << 16, 1 << 16);
}

#[bench]
fn divide_0(b: &mut Bencher) {
    divide_bench(b, 1 << 8, 1 << 6);
}

#[bench]
fn divide_1(b: &mut Bencher) {
    divide_bench(b, 1 << 12, 1 << 8);
}

#[bench]
fn divide_2(b: &mut Bencher) {
    divide_bench(b, 1 << 16, 1 << 12);
}

#[bench]
fn factorial_100(b: &mut Bencher) {
    b.iter(|| factorial(100));
}

#[bench]
fn fib_100(b: &mut Bencher) {
    b.iter(|| fib(100));
}

#[bench]
fn fib_1000(b: &mut Bencher) {
    b.iter(|| fib(1000));
}

#[bench]
fn fib_10000(b: &mut Bencher) {
    b.iter(|| fib(10000));
}

#[bench]
fn fib2_100(b: &mut Bencher) {
    b.iter(|| fib2(100));
}

#[bench]
fn fib2_1000(b: &mut Bencher) {
    b.iter(|| fib2(1000));
}

#[bench]
fn fib2_10000(b: &mut Bencher) {
    b.iter(|| fib2(10000));
}

#[bench]
fn fac_to_string(b: &mut Bencher) {
    let fac = factorial(100);
    b.iter(|| fac.to_string());
}

#[bench]
fn fib_to_string(b: &mut Bencher) {
    let fib = fib(100);
    b.iter(|| fib.to_string());
}

fn to_str_radix_bench(b: &mut Bencher, radix: u32) {
    let mut rng = get_rng();
    let x = rng.gen_bigint(1009);
    b.iter(|| x.to_str_radix(radix));
}

#[bench]
fn to_str_radix_02(b: &mut Bencher) {
    to_str_radix_bench(b, 2);
}

#[bench]
fn to_str_radix_08(b: &mut Bencher) {
    to_str_radix_bench(b, 8);
}

#[bench]
fn to_str_radix_10(b: &mut Bencher) {
    to_str_radix_bench(b, 10);
}

#[bench]
fn to_str_radix_16(b: &mut Bencher) {
    to_str_radix_bench(b, 16);
}

#[bench]
fn to_str_radix_36(b: &mut Bencher) {
    to_str_radix_bench(b, 36);
}

fn from_str_radix_bench(b: &mut Bencher, radix: u32) {
    use num::Num;
    let mut rng = get_rng();
    let x = rng.gen_bigint(1009);
    let s = x.to_str_radix(radix);
    assert_eq!(x, BigInt::from_str_radix(&s, radix).unwrap());
    b.iter(|| BigInt::from_str_radix(&s, radix));
}

#[bench]
fn from_str_radix_02(b: &mut Bencher) {
    from_str_radix_bench(b, 2);
}

#[bench]
fn from_str_radix_08(b: &mut Bencher) {
    from_str_radix_bench(b, 8);
}

#[bench]
fn from_str_radix_10(b: &mut Bencher) {
    from_str_radix_bench(b, 10);
}

#[bench]
fn from_str_radix_16(b: &mut Bencher) {
    from_str_radix_bench(b, 16);
}

#[bench]
fn from_str_radix_36(b: &mut Bencher) {
    from_str_radix_bench(b, 36);
}

#[bench]
fn shl(b: &mut Bencher) {
    let n = BigUint::one() << 1000;
    b.iter(|| {
        let mut m = n.clone();
        for i in 0..50 {
            m = m << i;
        }
    })
}

#[bench]
fn shr(b: &mut Bencher) {
    let n = BigUint::one() << 2000;
    b.iter(|| {
        let mut m = n.clone();
        for i in 0..50 {
            m = m >> i;
        }
    })
}

#[bench]
fn hash(b: &mut Bencher) {
    use std::collections::HashSet;
    let mut rng = get_rng();
    let v: Vec<BigInt> = (1000..2000).map(|bits| rng.gen_bigint(bits)).collect();
    b.iter(|| {
        let h: HashSet<&BigInt> = v.iter().collect();
        assert_eq!(h.len(), v.len());
    });
}

#[bench]
fn pow_bench(b: &mut Bencher) {
    b.iter(|| {
        let upper = 100_usize;
        for i in 2..upper + 1 {
            for j in 2..upper + 1 {
                let i_big = BigUint::from_usize(i).unwrap();
                num::pow(i_big, j);
            }
        }
    });
}
<commit_msg>Add a bench for bigint multiply<commit_after>#![feature(test)]

extern crate test;
extern crate num;
extern crate rand;

use std::mem::replace;
use test::Bencher;
use num::{BigInt, BigUint, Zero, One, FromPrimitive};
use num::bigint::RandBigInt;
use rand::{SeedableRng, StdRng};

fn get_rng() -> StdRng {
    let seed: &[_] = &[1, 2, 3, 4];
    SeedableRng::from_seed(seed)
}

fn multiply_bench(b: &mut Bencher, xbits: usize, ybits: usize) {
    let mut rng = get_rng();
    let x = rng.gen_bigint(xbits);
    let y = rng.gen_bigint(ybits);

    b.iter(|| &x * &y);
}

fn divide_bench(b: &mut Bencher, xbits: usize, ybits: usize) {
    let mut rng = get_rng();
    let x = rng.gen_bigint(xbits);
    let y = rng.gen_bigint(ybits);

    b.iter(|| &x / &y);
}

fn factorial(n: usize) -> BigUint {
    let mut f: BigUint = One::one();
    for i in 1..(n+1) {
        let bu: BigUint = FromPrimitive::from_usize(i).unwrap();
        f = f * bu;
    }
    f
}

/// Compute Fibonacci numbers
fn fib(n: usize) -> BigUint {
    let mut f0: BigUint = Zero::zero();
    let mut f1: BigUint = One::one();
    for _ in 0..n {
        let f2 = f0 + &f1;
        f0 = replace(&mut f1, f2);
    }
    f0
}

/// Compute Fibonacci numbers with two ops per iteration
/// (add and subtract, like issue #200)
fn fib2(n: usize) -> BigUint {
    let mut f0: BigUint = Zero::zero();
    let mut f1: BigUint = One::one();
    for _ in 0..n {
        f1 = f1 + &f0;
        f0 = &f1 - f0;
    }
    f0
}

#[bench]
fn multiply_0(b: &mut Bencher) {
    multiply_bench(b, 1 << 8, 1 << 8);
}

#[bench]
fn multiply_1(b: &mut Bencher) {
    multiply_bench(b, 1 << 8, 1 << 16);
}

#[bench]
fn multiply_2(b: &mut Bencher) {
    multiply_bench(b, 1 << 16, 1 << 16);
}

#[bench]
fn multiply_3(b: &mut Bencher) {
    multiply_bench(b, 1 << 16, 1 << 17);
}

#[bench]
fn divide_0(b: &mut Bencher) {
    divide_bench(b, 1 << 8, 1 << 6);
}

#[bench]
fn divide_1(b: &mut Bencher) {
    divide_bench(b, 1 << 12, 1 << 8);
}

#[bench]
fn divide_2(b: &mut Bencher) {
    divide_bench(b, 1 << 16, 1 << 12);
}

#[bench]
fn factorial_100(b: &mut Bencher) {
    b.iter(|| factorial(100));
}

#[bench]
fn fib_100(b: &mut Bencher) {
    b.iter(|| fib(100));
}

#[bench]
fn fib_1000(b: &mut Bencher) {
    b.iter(|| fib(1000));
}

#[bench]
fn fib_10000(b: &mut Bencher) {
    b.iter(|| fib(10000));
}

#[bench]
fn fib2_100(b: &mut Bencher) {
    b.iter(|| fib2(100));
}

#[bench]
fn fib2_1000(b: &mut Bencher) {
    b.iter(|| fib2(1000));
}

#[bench]
fn fib2_10000(b: &mut Bencher) {
    b.iter(|| fib2(10000));
}

#[bench]
fn fac_to_string(b: &mut Bencher) {
    let fac = factorial(100);
    b.iter(|| fac.to_string());
}

#[bench]
fn fib_to_string(b: &mut Bencher) {
    let fib = fib(100);
    b.iter(|| fib.to_string());
}

fn to_str_radix_bench(b: &mut Bencher, radix: u32) {
    let mut rng = get_rng();
    let x = rng.gen_bigint(1009);
    b.iter(|| x.to_str_radix(radix));
}

#[bench]
fn to_str_radix_02(b: &mut Bencher) {
    to_str_radix_bench(b, 2);
}

#[bench]
fn to_str_radix_08(b: &mut Bencher) {
    to_str_radix_bench(b, 8);
}

#[bench]
fn to_str_radix_10(b: &mut Bencher) {
    to_str_radix_bench(b, 10);
}

#[bench]
fn to_str_radix_16(b: &mut Bencher) {
    to_str_radix_bench(b, 16);
}

#[bench]
fn to_str_radix_36(b: &mut Bencher) {
    to_str_radix_bench(b, 36);
}

fn from_str_radix_bench(b: &mut Bencher, radix: u32) {
    use num::Num;
    let mut rng = get_rng();
    let x = rng.gen_bigint(1009);
    let s = x.to_str_radix(radix);
    assert_eq!(x, BigInt::from_str_radix(&s, radix).unwrap());
    b.iter(|| BigInt::from_str_radix(&s, radix));
}

#[bench]
fn from_str_radix_02(b: &mut Bencher) {
    from_str_radix_bench(b, 2);
}

#[bench]
fn from_str_radix_08(b: &mut Bencher) {
    from_str_radix_bench(b, 8);
}

#[bench]
fn from_str_radix_10(b: &mut Bencher) {
    from_str_radix_bench(b, 10);
}

#[bench]
fn from_str_radix_16(b: &mut Bencher) {
    from_str_radix_bench(b, 16);
}

#[bench]
fn from_str_radix_36(b: &mut Bencher) {
    from_str_radix_bench(b, 36);
}

#[bench]
fn shl(b: &mut Bencher) {
    let n = BigUint::one() << 1000;
    b.iter(|| {
        let mut m = n.clone();
        for i in 0..50 {
            m = m << i;
        }
    })
}

#[bench]
fn shr(b: &mut Bencher) {
    let n = BigUint::one() << 2000;
    b.iter(|| {
        let mut m = n.clone();
        for i in 0..50 {
            m = m >> i;
        }
    })
}

#[bench]
fn hash(b: &mut Bencher) {
    use std::collections::HashSet;
    let mut rng = get_rng();
    let v: Vec<BigInt> = (1000..2000).map(|bits| rng.gen_bigint(bits)).collect();
    b.iter(|| {
        let h: HashSet<&BigInt> = v.iter().collect();
        assert_eq!(h.len(), v.len());
    });
}

#[bench]
fn pow_bench(b: &mut Bencher) {
    b.iter(|| {
        let upper = 100_usize;
        for i in 2..upper + 1 {
            for j in 2..upper + 1 {
                let i_big = BigUint::from_usize(i).unwrap();
                num::pow(i_big, j);
            }
        }
    });
}
<|endoftext|>


<commit_before>// Copyright 2017 Adam Greig
// Licensed under the MIT license, see LICENSE for details.

#![feature(test)]
extern crate test;
use test::Bencher;

extern crate labrador_ldpc;
use labrador_ldpc::LDPCCode;

#[bench]
fn bench_decode_mp(b: &mut Bencher) {
    let code = LDPCCode::TM2048;

    let mut g = vec![0u32; code.generator_len()];
    code.init_generator(&mut g);

    let mut ci = vec![0; code.sparse_paritycheck_ci_len()];
    let mut cs = vec![0; code.sparse_paritycheck_cs_len()];
    let mut vi = vec![0; code.sparse_paritycheck_vi_len()];
    let mut vs = vec![0; code.sparse_paritycheck_vs_len()];
    code.init_sparse_paritycheck(&mut ci, &mut cs, &mut vi, &mut vs);

    let txdata: Vec<u8> = (0..code.k()/8).map(|i| !(i as u8)).collect();
    let mut txcode = vec![0u8; code.n()/8];
    code.encode_fast(&g, &txdata, &mut txcode);

    // Copy it and corrupt the first bit
    let mut rxcode = txcode.clone();
    rxcode[0] ^= 1<<7;

    // Convert the hard data to LLRs
    let mut llrs = vec![0f32; code.n()];
    code.hard_to_llrs(&rxcode, &mut llrs, -3.0);

    // Allocate working area and output area
    let mut working = vec![0f32; code.decode_mp_working_len()];
    let mut rxdata = vec![0u8; code.output_len()];

    // Run decoder
    b.iter(|| code.decode_mp(&ci, &cs, &vi, &vs, &llrs, &mut rxdata, &mut working));
}

#[bench]
fn bench_decode_bf(b: &mut Bencher) {
    let code = LDPCCode::TM2048;

    let mut g = vec![0u32; code.generator_len()];
    code.init_generator(&mut g);

    let mut ci = vec![0; code.sparse_paritycheck_ci_len()];
    let mut cs = vec![0; code.sparse_paritycheck_cs_len()];
    let mut vi = vec![0; code.sparse_paritycheck_vi_len()];
    let mut vs = vec![0; code.sparse_paritycheck_vs_len()];
    code.init_sparse_paritycheck(&mut ci, &mut cs, &mut vi, &mut vs);

    let txdata: Vec<u8> = (0..code.k()/8).map(|i| !(i as u8)).collect();
    let mut txcode = vec![0u8; code.n()/8];
    code.encode_fast(&g, &txdata, &mut txcode);

    // Copy to rx
    let mut rxcode = txcode.clone();
    rxcode[0] ^= 1<<7;

    // Allocate working area and output area
    let mut working = vec![0u8; code.decode_bf_working_len()];
    let mut output = vec![0u8; code.output_len()];

    // Run decoder
    b.iter(|| for _ in 0..100 { code.decode_bf(&ci, &cs, Some(&vi), Some(&vs), &rxcode, &mut output, &mut working); });
}
<commit_msg>only run the bf decoder once per bench iteration<commit_after>// Copyright 2017 Adam Greig
// Licensed under the MIT license, see LICENSE for details.

#![feature(test)]
extern crate test;
use test::Bencher;

extern crate labrador_ldpc;
use labrador_ldpc::LDPCCode;

#[bench]
fn bench_decode_mp(b: &mut Bencher) {
    let code = LDPCCode::TM2048;

    let mut g = vec![0u32; code.generator_len()];
    code.init_generator(&mut g);

    let mut ci = vec![0; code.sparse_paritycheck_ci_len()];
    let mut cs = vec![0; code.sparse_paritycheck_cs_len()];
    let mut vi = vec![0; code.sparse_paritycheck_vi_len()];
    let mut vs = vec![0; code.sparse_paritycheck_vs_len()];
    code.init_sparse_paritycheck(&mut ci, &mut cs, &mut vi, &mut vs);

    let txdata: Vec<u8> = (0..code.k()/8).map(|i| !(i as u8)).collect();
    let mut txcode = vec![0u8; code.n()/8];
    code.encode_fast(&g, &txdata, &mut txcode);

    // Copy it and corrupt the first bit
    let mut rxcode = txcode.clone();
    rxcode[0] ^= 1<<7;

    // Convert the hard data to LLRs
    let mut llrs = vec![0f32; code.n()];
    code.hard_to_llrs(&rxcode, &mut llrs, -3.0);

    // Allocate working area and output area
    let mut working = vec![0f32; code.decode_mp_working_len()];
    let mut rxdata = vec![0u8; code.output_len()];

    // Run decoder
    b.iter(|| code.decode_mp(&ci, &cs, &vi, &vs, &llrs, &mut rxdata, &mut working));
}

#[bench]
fn bench_decode_bf(b: &mut Bencher) {
    let code = LDPCCode::TM2048;

    let mut g = vec![0u32; code.generator_len()];
    code.init_generator(&mut g);

    let mut ci = vec![0; code.sparse_paritycheck_ci_len()];
    let mut cs = vec![0; code.sparse_paritycheck_cs_len()];
    let mut vi = vec![0; code.sparse_paritycheck_vi_len()];
    let mut vs = vec![0; code.sparse_paritycheck_vs_len()];
    code.init_sparse_paritycheck(&mut ci, &mut cs, &mut vi, &mut vs);

    let txdata: Vec<u8> = (0..code.k()/8).map(|i| !(i as u8)).collect();
    let mut txcode = vec![0u8; code.n()/8];
    code.encode_fast(&g, &txdata, &mut txcode);

    // Copy to rx
    let mut rxcode = txcode.clone();
    rxcode[0] ^= 1<<7;

    // Allocate working area and output area
    let mut working = vec![0u8; code.decode_bf_working_len()];
    let mut output = vec![0u8; code.output_len()];

    // Run decoder
    b.iter(|| code.decode_bf(&ci, &cs, Some(&vi), Some(&vs), &rxcode, &mut output, &mut working));
}
<|endoftext|>


<commit_before>use std::cmp::Ordering;
use std::collections::BinaryHeap;
use angle::Angle;
use point::Point;
use events::{Event, EventKind};
use beach::{Beach, Arc, ArcStart};
use diagram::{Diagram, Vertex, Cell};
use cgmath::InnerSpace;

#[derive(Default)]
struct Builder {
    events: BinaryHeap<Event>,
    beach: Beach,
    diagram: Diagram,
    scan_theta: Angle,
    temporary: Vec<Vertex>,
}

impl Builder {
    fn new(points: &[Point]) -> Self {
        let mut builder = Builder::default();
        for &point in points {
            let cell = builder.diagram.add_cell(point);
            builder.events.push(Event {
                theta: point.theta.value,
                kind: EventKind::Site(cell),
            });
        }
        builder
    }

    pub fn build(mut self, relaxations: usize) -> Diagram {
        self.build_iter();
        for _ in 1..relaxations {
            self.reset();
            self.build_iter();
        }
        self.finish();
        self.diagram
    }

    fn build_iter(&mut self) {
        while let Some(event) = self.events.pop() {
            //println!("{:?}", event);
            self.scan_theta = Angle::from(event.theta);
            match event.kind {
                EventKind::Site(cell) => self.handle_site_event(cell),
                EventKind::Circle { arc, generation } => self.handle_circle_event(arc, generation),
            }
        }
    }

    fn reset(&mut self) {
        self.diagram.reset();
        self.events.clear();
        self.temporary.clear();
        self.beach.clear();
        self.scan_theta = Angle::default();
        for cell in self.diagram.cells() {
            self.events.push(Event {
                theta: self.diagram.cell_point(cell).theta.value,
                kind: EventKind::Site(cell)
            });
        }
    }

    fn arc_point(&self, arc: Arc) -> &Point {
        &self.diagram.cell_point(self.beach.cell(arc))
    }

    fn create_temporary(&mut self, arc0: Arc, arc1: Arc) {
        let index = self.temporary.len();
        self.temporary.push(Vertex::invalid());
        self.beach.set_start(arc0, ArcStart::Temporary(index));
        self.beach.set_start(arc1, ArcStart::Temporary(index));
    }

    fn handle_site_event(&mut self, cell: Cell) {
        if let Some(mut arc) = self.beach.root() {
            if self.beach.len() == 1 {
                self.beach.insert_after(Some(arc), cell);
                let arc0 = self.beach.first();
                let arc1 = self.beach.last();
                self.create_temporary(arc0, arc1);
                return;
            }
            let point = *self.diagram.cell_point(cell);
            let mut use_tree = true;
            loop {
                let prev = self.beach.prev(arc);
                let next = self.beach.next(arc);
                let start = self.arcs_intersection(prev, arc);
                let end = self.arcs_intersection(arc, next);
                match point.phi.is_in_range(start, end) {
                    Ordering::Less => {
                        if use_tree {
                            if let Some(left) = self.beach.left(arc) {
                                arc = left;
                            } else {
                                // the tree has failed us, do the linear search from now on.
                                arc = self.beach.last();
                                use_tree = false;
                            }
                        } else {
                            arc = self.beach.prev(arc);
                        }
                    },
                    Ordering::Greater => {
                        if use_tree {
                            if let Some(right) = self.beach.right(arc) {
                                arc = right;
                            } else {
                                // the tree has failed us, do the linear search from now on.
                                arc = self.beach.first();
                                use_tree = false;
                            }
                        } else {
                            arc = self.beach.next(arc);
                        }
                    },
                    Ordering::Equal => {
                        self.beach.detach(arc);
                        let twin = {
                            let cell = self.beach.cell(arc);
                            let a = if prev == self.beach.last() {
                                None
                            } else {
                                Some(prev)
                            };
                            self.beach.insert_after(a, cell)
                        };
                        let new_arc = self.beach.insert_after(Some(twin), cell);
                        self.create_temporary(twin, new_arc);
                        self.attach_circle(prev, twin, new_arc, point.theta.value);
                        self.attach_circle(new_arc, arc, next, point.theta.value);
                        if self.beach.generation(prev) > 0 {
                            let prev_prev = self.beach.prev(prev);
                            self.attach_circle(prev_prev, prev, twin, ::std::f64::MIN);
                        }
                        break;
                    }
                }
            }
        } else {
            self.beach.insert_after(None, cell);
        }
    }

    fn merge_arcs(&mut self, arc0: Arc, arc1: Arc, arc2: Arc, vertex: Option<Vertex>) {
        let theta = self.scan_theta.value;
        if self.attach_circle(arc0, arc1, arc2, theta) {
            if let Some(vertex) = vertex {
                self.beach.set_start(arc1, ArcStart::Vertex(vertex));
            }
        }
    }

    fn create_edge(&mut self, arc: Arc, end: Vertex) {
        match self.beach.start(arc) {
            ArcStart::Temporary(index) => {
                let start = self.temporary[index];
                if start.is_invalid() {
                    self.temporary[index] = end;
                } else {
                    self.diagram.add_edge(start, end);
                }
            },
            ArcStart::Vertex(start) => {
                self.diagram.add_edge(start, end);
            },
            ArcStart::None => {},
        };
    }

    fn handle_circle_event(&mut self, arc: Arc, generation: usize) {
        let arc_generation = self.beach.generation(arc);
        if arc_generation != generation {
            return;
        };
        let prev = self.beach.prev(arc);
        let next = self.beach.next(arc);
        self.beach.detach(arc);
        self.beach.detach(prev);
        self.beach.detach(next);
        let point = self.beach.center(arc);
        let vertex = self.diagram.add_vertex(point, &[self.beach.cell(prev), self.beach.cell(arc), self.beach.cell(next)]);
        self.create_edge(prev, vertex);
        self.create_edge(arc, vertex);
        self.beach.remove(arc);
        if self.beach.prev(prev) == next {
            self.create_edge(next, vertex);
            self.beach.remove(prev);
            self.beach.remove(next);
        } else {
            let prev_prev = self.beach.prev(prev);
            let next_next = self.beach.next(next);
            self.merge_arcs(prev_prev, prev, next, Some(vertex));
            self.merge_arcs(prev, next, next_next, None);
        }
    }

    fn arcs_intersection(&self, arc0: Arc, arc1: Arc) -> f64 {
        let point0 = self.arc_point(arc0);
        let point1 = self.arc_point(arc1);
        let u1 = (self.scan_theta.cos - point1.theta.cos) * point0.theta.sin;
        let u2 = (self.scan_theta.cos - point0.theta.cos) * point1.theta.sin;
        let a = u1 * point0.phi.cos - u2 * point1.phi.cos;
        let b = u1 * point0.phi.sin - u2 * point1.phi.sin;
        let c = (point0.theta.cos - point1.theta.cos) * self.scan_theta.sin;
        let length = (a * a + b * b).sqrt();
        let gamma = a.atan2(b);
        let phi_plus_gamma = (c / length).asin();
        Angle::wrap(phi_plus_gamma - gamma)
    }

    fn attach_circle(&mut self, arc0: Arc, arc: Arc, arc2: Arc, min_theta: f64) -> bool {
        let p1 = self.arc_point(arc).position;
        let p01 = self.arc_point(arc0).position - p1;
        let p21 = self.arc_point(arc2).position - p1;
        let center = p01.cross(p21).normalize();
        let radius = center.dot(p1).acos();
        let theta = center.z.acos() + radius;
        if theta >= min_theta {
            let generation = self.beach.attach(arc, center);
            self.events.push(Event {
                theta: theta,
                kind: EventKind::Circle { arc: arc, generation: generation },
            });
            true
        } else {
            false
        }
    }

    fn finish(&mut self) {
        for edge in self.diagram.edges() {
            let mut common = Vec::new();
            let (vertex0, vertex1) = self.diagram.edge_vertices(edge);
            for &cell0 in self.diagram.vertex_cells(vertex0) {
                for &cell1 in self.diagram.vertex_cells(vertex1) {
                    if cell0 == cell1 {
                        common.push(cell0);
                    }
                }
            }
            assert_eq!(common.len(), 2);
            self.diagram.set_edge_cells(edge, common[0], common[1]);
        }
    }
}

pub fn build(points: &[Point], relaxations: usize) -> Diagram {
    Builder::new(points).build(relaxations)
}
<commit_msg>Do not reattach circles (is it correct?)<commit_after>use std::cmp::Ordering;
use std::collections::BinaryHeap;
use angle::Angle;
use point::Point;
use events::{Event, EventKind};
use beach::{Beach, Arc, ArcStart};
use diagram::{Diagram, Vertex, Cell};
use cgmath::InnerSpace;

#[derive(Default)]
struct Builder {
    events: BinaryHeap<Event>,
    beach: Beach,
    diagram: Diagram,
    scan_theta: Angle,
    temporary: Vec<Vertex>,
}

impl Builder {
    fn new(points: &[Point]) -> Self {
        let mut builder = Builder::default();
        for &point in points {
            let cell = builder.diagram.add_cell(point);
            builder.events.push(Event {
                theta: point.theta.value,
                kind: EventKind::Site(cell),
            });
        }
        builder
    }

    pub fn build(mut self, relaxations: usize) -> Diagram {
        self.build_iter();
        for _ in 1..relaxations {
            self.reset();
            self.build_iter();
        }
        self.finish();
        self.diagram
    }

    fn build_iter(&mut self) {
        while let Some(event) = self.events.pop() {
            //println!("{:?}", event);
            self.scan_theta = Angle::from(event.theta);
            match event.kind {
                EventKind::Site(cell) => self.handle_site_event(cell),
                EventKind::Circle { arc, generation } => self.handle_circle_event(arc, generation),
            }
        }
    }

    fn reset(&mut self) {
        self.diagram.reset();
        self.events.clear();
        self.temporary.clear();
        self.beach.clear();
        self.scan_theta = Angle::default();
        for cell in self.diagram.cells() {
            self.events.push(Event {
                theta: self.diagram.cell_point(cell).theta.value,
                kind: EventKind::Site(cell)
            });
        }
    }

    fn arc_point(&self, arc: Arc) -> &Point {
        &self.diagram.cell_point(self.beach.cell(arc))
    }

    fn create_temporary(&mut self, arc0: Arc, arc1: Arc) {
        let index = self.temporary.len();
        self.temporary.push(Vertex::invalid());
        self.beach.set_start(arc0, ArcStart::Temporary(index));
        self.beach.set_start(arc1, ArcStart::Temporary(index));
    }

    fn handle_site_event(&mut self, cell: Cell) {
        if let Some(mut arc) = self.beach.root() {
            if self.beach.len() == 1 {
                self.beach.insert_after(Some(arc), cell);
                let arc0 = self.beach.first();
                let arc1 = self.beach.last();
                self.create_temporary(arc0, arc1);
                return;
            }
            let point = *self.diagram.cell_point(cell);
            let mut use_tree = true;
            loop {
                let prev = self.beach.prev(arc);
                let next = self.beach.next(arc);
                let start = self.arcs_intersection(prev, arc);
                let end = self.arcs_intersection(arc, next);
                match point.phi.is_in_range(start, end) {
                    Ordering::Less => {
                        if use_tree {
                            if let Some(left) = self.beach.left(arc) {
                                arc = left;
                            } else {
                                // the tree has failed us, do the linear search from now on.
                                arc = self.beach.last();
                                use_tree = false;
                            }
                        } else {
                            arc = self.beach.prev(arc);
                        }
                    },
                    Ordering::Greater => {
                        if use_tree {
                            if let Some(right) = self.beach.right(arc) {
                                arc = right;
                            } else {
                                // the tree has failed us, do the linear search from now on.
                                arc = self.beach.first();
                                use_tree = false;
                            }
                        } else {
                            arc = self.beach.next(arc);
                        }
                    },
                    Ordering::Equal => {
                        self.beach.detach(arc);
                        let twin = {
                            let cell = self.beach.cell(arc);
                            let a = if prev == self.beach.last() {
                                None
                            } else {
                                Some(prev)
                            };
                            self.beach.insert_after(a, cell)
                        };
                        let new = self.beach.insert_after(Some(twin), cell);
                        self.create_temporary(twin, new);
                        self.attach_circle(twin, prev, new, point.theta.value);
                        self.attach_circle(arc, new, next, point.theta.value);
                        break;
                    }
                }
            }
        } else {
            self.beach.insert_after(None, cell);
        }
    }

    fn merge_arcs(&mut self, arc: Arc, prev: Arc, next: Arc, vertex: Option<Vertex>) {
        let theta = self.scan_theta.value;
        if self.attach_circle(arc, prev, next, theta) {
            if let Some(vertex) = vertex {
                self.beach.set_start(arc, ArcStart::Vertex(vertex));
            }
        }
    }

    fn create_edge(&mut self, arc: Arc, end: Vertex) {
        match self.beach.start(arc) {
            ArcStart::Temporary(index) => {
                let start = self.temporary[index];
                if start.is_invalid() {
                    self.temporary[index] = end;
                } else {
                    self.diagram.add_edge(start, end);
                }
            },
            ArcStart::Vertex(start) => {
                self.diagram.add_edge(start, end);
            },
            ArcStart::None => {},
        };
    }

    fn handle_circle_event(&mut self, arc: Arc, generation: usize) {
        let arc_generation = self.beach.generation(arc);
        if arc_generation != generation {
            return;
        };
        let prev = self.beach.prev(arc);
        let next = self.beach.next(arc);
        self.beach.detach(arc);
        self.beach.detach(prev);
        self.beach.detach(next);
        let point = self.beach.center(arc);
        let vertex = self.diagram.add_vertex(point, &[self.beach.cell(prev), self.beach.cell(arc), self.beach.cell(next)]);
        self.create_edge(prev, vertex);
        self.create_edge(arc, vertex);
        self.beach.remove(arc);
        if self.beach.prev(prev) == next {
            self.create_edge(next, vertex);
            self.beach.remove(prev);
            self.beach.remove(next);
        } else {
            let prev_prev = self.beach.prev(prev);
            let next_next = self.beach.next(next);
            self.merge_arcs(prev, prev_prev, next, Some(vertex));
            self.merge_arcs(next, prev, next_next, None);
        }
    }

    fn arcs_intersection(&self, arc0: Arc, arc1: Arc) -> f64 {
        let point0 = self.arc_point(arc0);
        let point1 = self.arc_point(arc1);
        let u1 = (self.scan_theta.cos - point1.theta.cos) * point0.theta.sin;
        let u2 = (self.scan_theta.cos - point0.theta.cos) * point1.theta.sin;
        let a = u1 * point0.phi.cos - u2 * point1.phi.cos;
        let b = u1 * point0.phi.sin - u2 * point1.phi.sin;
        let c = (point0.theta.cos - point1.theta.cos) * self.scan_theta.sin;
        let length = (a * a + b * b).sqrt();
        let gamma = a.atan2(b);
        let phi_plus_gamma = (c / length).asin();
        Angle::wrap(phi_plus_gamma - gamma)
    }

    fn attach_circle(&mut self, arc: Arc, prev: Arc, next: Arc, min_theta: f64) -> bool {
        let position = self.arc_point(arc).position;
        let from_prev = self.arc_point(prev).position - position;
        let from_next = self.arc_point(next).position - position;
        let center = from_prev.cross(from_next).normalize();
        let radius = center.dot(position).acos();
        let theta = center.z.acos() + radius;
        if theta >= min_theta {
            let generation = self.beach.attach(arc, center);
            self.events.push(Event {
                theta: theta,
                kind: EventKind::Circle { arc: arc, generation: generation },
            });
            true
        } else {
            false
        }
    }

    fn finish(&mut self) {
        for edge in self.diagram.edges() {
            let mut common = Vec::new();
            let (vertex0, vertex1) = self.diagram.edge_vertices(edge);
            for &cell0 in self.diagram.vertex_cells(vertex0) {
                for &cell1 in self.diagram.vertex_cells(vertex1) {
                    if cell0 == cell1 {
                        common.push(cell0);
                    }
                }
            }
            assert_eq!(common.len(), 2);
            self.diagram.set_edge_cells(edge, common[0], common[1]);
        }
    }
}

pub fn build(points: &[Point], relaxations: usize) -> Diagram {
    Builder::new(points).build(relaxations)
}
<|endoftext|>


<commit_before>extern crate pkg_config;
extern crate gcc;

use std::env;
use std::ffi::OsString;
use std::fs;
use std::path::{PathBuf, Path};
use std::process::Command;
use std::io::ErrorKind;

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(t) => t,
        Err(e) => panic!("{} return the error {}", stringify!($e), e),
    })
}

fn main() {
    let target = env::var("TARGET").unwrap();
    let host = env::var("HOST").unwrap();
    let src = env::current_dir().unwrap();
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let windows = target.contains("windows");

    // OSX ships libcurl by default, so we just use that version
    // unconditionally.
    if target.contains("apple") {
        return println!("cargo:rustc-flags=-l curl");
    }

    // Next, fall back and try to use pkg-config if its available.
    if !target.contains("windows") {
        match pkg_config::find_library("libcurl") {
            Ok(lib) => {
                for path in lib.include_paths.iter() {
                    println!("cargo:include={}", path.display());
                }
                return
            }
            Err(e) => println!("Couldn't find libcurl from \
                               pkgconfig ({:?}), compiling it from source...", e),
        }
    }

    if !Path::new("curl/.git").exists() {
        let _ = Command::new("git").args(&["submodule", "update", "--init"])
                                   .status();
    }

    println!("cargo:rustc-link-search={}/lib", dst.display());
    println!("cargo:rustc-link-lib=static=curl");
    println!("cargo:root={}", dst.display());
    println!("cargo:include={}/include", dst.display());
    if windows {
        println!("cargo:rustc-flags=-l ws2_32");
    }

    // MSVC builds are just totally different
    if target.contains("msvc") {
        return build_msvc(&target);
    }

    let cfg = gcc::Config::new();
    let compiler = cfg.get_compiler();

    let _ = fs::create_dir(&dst.join("build"));

    let mut cmd = Command::new("sh");
    let mut cflags = OsString::new();
    for arg in compiler.args() {
        cflags.push(arg);
        cflags.push(" ");
    }

    // Can't run ./configure directly on msys2 b/c we're handing in
    // Windows-style paths (those starting with C:\), but it chokes on those.
    // For that reason we build up a shell script with paths converted to
    // posix versions hopefully...
    //
    // Also apparently the buildbots choke unless we manually set LD, who knows
    // why?!
    cmd.env("CC", compiler.path())
       .env("CFLAGS", cflags)
       .env("LD", &which("ld").unwrap())
       .env("VERBOSE", "1")
       .current_dir(&dst.join("build"))
       .arg(msys_compatible(&src.join("curl/configure")));

    if windows {
        cmd.arg("--with-winssl");
    } else {
        cmd.arg("--without-ca-bundle");
        cmd.arg("--without-ca-path");

        // DEP_OPENSSL_ROOT was what cargo used to use via overrides, and
        // OPENSSL_ROOT_DIR is also used by libssh2 which cargo uses and can be
        // set by various build scripts.
        let openssl_root = env::var("DEP_OPENSSL_ROOT").or_else(|_| {
            env::var("OPENSSL_ROOT_DIR")
        });
        if let Ok(s) = openssl_root {
            cmd.arg(format!("--with-ssl={}", s));
        }
    }
    cmd.arg("--enable-static=yes");
    cmd.arg("--enable-shared=no");
    match &env::var("PROFILE").unwrap()[..] {
        "bench" | "release" => {
            cmd.arg("--enable-optimize");
        }
        _ => {
            cmd.arg("--enable-debug");
            cmd.arg("--disable-optimize");
        }
    }
    cmd.arg(format!("--prefix={}", msys_compatible(&dst)));

    if target != host &&
       (!target.contains("windows") || !host.contains("windows")) {
        cmd.arg(format!("--host={}", host));
        cmd.arg(format!("--target={}", target));
    }

    cmd.arg("--without-librtmp");
    cmd.arg("--without-libidn");
    cmd.arg("--without-libssh2");
    cmd.arg("--without-nghttp2");
    cmd.arg("--disable-ldap");
    cmd.arg("--disable-ldaps");
    cmd.arg("--disable-ftp");
    cmd.arg("--disable-rtsp");
    cmd.arg("--disable-dict");
    cmd.arg("--disable-telnet");
    cmd.arg("--disable-tftp");
    cmd.arg("--disable-pop3");
    cmd.arg("--disable-imap");
    cmd.arg("--disable-smtp");
    cmd.arg("--disable-gopher");
    cmd.arg("--disable-manual");
    cmd.arg("--disable-smb");
    cmd.arg("--disable-sspi");

    run(&mut cmd, "sh");
    run(Command::new(make())
                .arg(&format!("-j{}", env::var("NUM_JOBS").unwrap()))
                .current_dir(&dst.join("build")), "make");
    run(Command::new(make())
                .arg("install")
                .current_dir(&dst.join("build")), "make");
}

fn run(cmd: &mut Command, program: &str) {
    println!("running: {:?}", cmd);
    let status = match cmd.status() {
        Ok(status) => status,
        Err(ref e) if e.kind() == ErrorKind::NotFound => {
            fail(&format!("failed to execute command: {}\nis `{}` not installed?",
                          e, program));
        }
        Err(e) => fail(&format!("failed to execute command: {}", e)),
    };
    if !status.success() {
        fail(&format!("command did not execute successfully, got: {}", status));
    }
}

fn fail(s: &str) -> ! {
    panic!("\n{}\n\nbuild script failed, must exit now", s)
}

fn make() -> &'static str {
    if cfg!(target_os = "freebsd") {"gmake"} else {"make"}
}

fn which(cmd: &str) -> Option<PathBuf> {
    let cmd = format!("{}{}", cmd, env::consts::EXE_SUFFIX);
    let paths = env::var_os("PATH").unwrap();
    env::split_paths(&paths).map(|p| p.join(&cmd)).find(|p| {
        fs::metadata(p).is_ok()
    })
}

fn msys_compatible(path: &Path) -> String {
    let path = path.to_str().unwrap();
    if !cfg!(windows) {
        return path.to_string()
    }
    path.replace("C:\\", "/c/")
        .replace("\\", "/")
}

fn build_msvc(target: &str) {
    let cmd = gcc::windows_registry::find(target, "nmake.exe");
    let mut cmd = cmd.unwrap_or(Command::new("nmake.exe"));
    let src = env::current_dir().unwrap();
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let machine = if target.starts_with("x86_64") {
        "x64"
    } else if target.starts_with("i686") {
        "x86"
    } else {
        panic!("unknown msvc target: {}", target);
    };

    t!(fs::create_dir_all(dst.join("include/curl")));
    t!(fs::create_dir_all(dst.join("lib")));

    cmd.current_dir(src.join("curl/winbuild"));
    cmd.arg("/f").arg("Makefile.vc")
       .arg("MODE=static")
       .arg("ENABLE_IDN=yes")
       .arg("DEBUG=no")
       .arg("GEN_PDB=no")
       .arg("ENABLE_WINSSL=yes")
       .arg("ENABLE_SSPI=yes")
       .arg(format!("MACHINE={}", machine));

    if let Some(inc) = env::var_os("DEP_Z_ROOT") {
        let inc = PathBuf::from(inc);
        let mut s = OsString::from("WITH_DEVEL=");
        s.push(&inc);
        cmd.arg("WITH_ZLIB=static").arg(s);

        // the build system for curl expects this library to be called
        // zlib_a.lib, so make sure it's named correctly (where libz-sys just
        // produces zlib.lib)
        let _ = fs::remove_file(&inc.join("lib/zlib_a.lib"));
        t!(fs::hard_link(inc.join("lib/zlib.lib"), inc.join("lib/zlib_a.lib")));
    }
    run(&mut cmd, "nmake");

    let name = format!("libcurl-vc-{}-release-static-zlib-static-\
                        ipv6-sspi-winssl", machine);
    let libs = src.join("curl/builds").join(name);

    t!(fs::copy(libs.join("lib/libcurl_a.lib"), dst.join("lib/curl.lib")));
    for f in t!(fs::read_dir(libs.join("include/curl"))) {
        let path = t!(f).path();
        let dst = dst.join("include/curl").join(path.file_name().unwrap());
        t!(fs::copy(path, dst));
    }
    t!(fs::remove_dir_all(src.join("curl/builds")));
    println!("cargo:rustc-link-lib=wldap32");
    println!("cargo:rustc-link-lib=advapi32");
    println!("cargo:rustc-link-lib=normaliz");
}
<commit_msg>Fix compilation on Solaris/Illumos<commit_after>extern crate pkg_config;
extern crate gcc;

use std::env;
use std::ffi::OsString;
use std::fs;
use std::path::{PathBuf, Path};
use std::process::Command;
use std::io::ErrorKind;

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(t) => t,
        Err(e) => panic!("{} return the error {}", stringify!($e), e),
    })
}

fn main() {
    let target = env::var("TARGET").unwrap();
    let host = env::var("HOST").unwrap();
    let src = env::current_dir().unwrap();
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let windows = target.contains("windows");

    // OSX ships libcurl by default, so we just use that version
    // unconditionally.
    if target.contains("apple") {
        return println!("cargo:rustc-flags=-l curl");
    }

    // Illumos/Solaris requires explicit linking with libnsl
    if target.contains("solaris") {
        println!("cargo:rustc-flags=-l nsl");
    }

    // Next, fall back and try to use pkg-config if its available.
    if !target.contains("windows") {
        match pkg_config::find_library("libcurl") {
            Ok(lib) => {
                for path in lib.include_paths.iter() {
                    println!("cargo:include={}", path.display());
                }
                return
            }
            Err(e) => println!("Couldn't find libcurl from \
                               pkgconfig ({:?}), compiling it from source...", e),
        }
    }

    if !Path::new("curl/.git").exists() {
        let _ = Command::new("git").args(&["submodule", "update", "--init"])
                                   .status();
    }

    println!("cargo:rustc-link-search={}/lib", dst.display());
    println!("cargo:rustc-link-lib=static=curl");
    println!("cargo:root={}", dst.display());
    println!("cargo:include={}/include", dst.display());
    if windows {
        println!("cargo:rustc-flags=-l ws2_32");
    }

    // MSVC builds are just totally different
    if target.contains("msvc") {
        return build_msvc(&target);
    }

    let cfg = gcc::Config::new();
    let compiler = cfg.get_compiler();

    let _ = fs::create_dir(&dst.join("build"));

    let mut cmd = Command::new("sh");
    let mut cflags = OsString::new();
    for arg in compiler.args() {
        cflags.push(arg);
        cflags.push(" ");
    }

    // Can't run ./configure directly on msys2 b/c we're handing in
    // Windows-style paths (those starting with C:\), but it chokes on those.
    // For that reason we build up a shell script with paths converted to
    // posix versions hopefully...
    //
    // Also apparently the buildbots choke unless we manually set LD, who knows
    // why?!
    cmd.env("CC", compiler.path())
       .env("CFLAGS", cflags)
       .env("LD", &which("ld").unwrap())
       .env("VERBOSE", "1")
       .current_dir(&dst.join("build"))
       .arg(msys_compatible(&src.join("curl/configure")));

    if windows {
        cmd.arg("--with-winssl");
    } else {
        cmd.arg("--without-ca-bundle");
        cmd.arg("--without-ca-path");

        // DEP_OPENSSL_ROOT was what cargo used to use via overrides, and
        // OPENSSL_ROOT_DIR is also used by libssh2 which cargo uses and can be
        // set by various build scripts.
        let openssl_root = env::var("DEP_OPENSSL_ROOT").or_else(|_| {
            env::var("OPENSSL_ROOT_DIR")
        });
        if let Ok(s) = openssl_root {
            cmd.arg(format!("--with-ssl={}", s));
        }
    }
    cmd.arg("--enable-static=yes");
    cmd.arg("--enable-shared=no");
    match &env::var("PROFILE").unwrap()[..] {
        "bench" | "release" => {
            cmd.arg("--enable-optimize");
        }
        _ => {
            cmd.arg("--enable-debug");
            cmd.arg("--disable-optimize");
        }
    }
    cmd.arg(format!("--prefix={}", msys_compatible(&dst)));

    if target != host &&
       (!target.contains("windows") || !host.contains("windows")) {
        cmd.arg(format!("--host={}", host));
        cmd.arg(format!("--target={}", target));
    }

    cmd.arg("--without-librtmp");
    cmd.arg("--without-libidn");
    cmd.arg("--without-libssh2");
    cmd.arg("--without-nghttp2");
    cmd.arg("--disable-ldap");
    cmd.arg("--disable-ldaps");
    cmd.arg("--disable-ftp");
    cmd.arg("--disable-rtsp");
    cmd.arg("--disable-dict");
    cmd.arg("--disable-telnet");
    cmd.arg("--disable-tftp");
    cmd.arg("--disable-pop3");
    cmd.arg("--disable-imap");
    cmd.arg("--disable-smtp");
    cmd.arg("--disable-gopher");
    cmd.arg("--disable-manual");
    cmd.arg("--disable-smb");
    cmd.arg("--disable-sspi");

    run(&mut cmd, "sh");
    run(Command::new(make())
                .arg(&format!("-j{}", env::var("NUM_JOBS").unwrap()))
                .current_dir(&dst.join("build")), "make");
    run(Command::new(make())
                .arg("install")
                .current_dir(&dst.join("build")), "make");
}

fn run(cmd: &mut Command, program: &str) {
    println!("running: {:?}", cmd);
    let status = match cmd.status() {
        Ok(status) => status,
        Err(ref e) if e.kind() == ErrorKind::NotFound => {
            fail(&format!("failed to execute command: {}\nis `{}` not installed?",
                          e, program));
        }
        Err(e) => fail(&format!("failed to execute command: {}", e)),
    };
    if !status.success() {
        fail(&format!("command did not execute successfully, got: {}", status));
    }
}

fn fail(s: &str) -> ! {
    panic!("\n{}\n\nbuild script failed, must exit now", s)
}

fn make() -> &'static str {
    if cfg!(target_os = "freebsd") {"gmake"} else {"make"}
}

fn which(cmd: &str) -> Option<PathBuf> {
    let cmd = format!("{}{}", cmd, env::consts::EXE_SUFFIX);
    let paths = env::var_os("PATH").unwrap();
    env::split_paths(&paths).map(|p| p.join(&cmd)).find(|p| {
        fs::metadata(p).is_ok()
    })
}

fn msys_compatible(path: &Path) -> String {
    let path = path.to_str().unwrap();
    if !cfg!(windows) {
        return path.to_string()
    }
    path.replace("C:\\", "/c/")
        .replace("\\", "/")
}

fn build_msvc(target: &str) {
    let cmd = gcc::windows_registry::find(target, "nmake.exe");
    let mut cmd = cmd.unwrap_or(Command::new("nmake.exe"));
    let src = env::current_dir().unwrap();
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let machine = if target.starts_with("x86_64") {
        "x64"
    } else if target.starts_with("i686") {
        "x86"
    } else {
        panic!("unknown msvc target: {}", target);
    };

    t!(fs::create_dir_all(dst.join("include/curl")));
    t!(fs::create_dir_all(dst.join("lib")));

    cmd.current_dir(src.join("curl/winbuild"));
    cmd.arg("/f").arg("Makefile.vc")
       .arg("MODE=static")
       .arg("ENABLE_IDN=yes")
       .arg("DEBUG=no")
       .arg("GEN_PDB=no")
       .arg("ENABLE_WINSSL=yes")
       .arg("ENABLE_SSPI=yes")
       .arg(format!("MACHINE={}", machine));

    if let Some(inc) = env::var_os("DEP_Z_ROOT") {
        let inc = PathBuf::from(inc);
        let mut s = OsString::from("WITH_DEVEL=");
        s.push(&inc);
        cmd.arg("WITH_ZLIB=static").arg(s);

        // the build system for curl expects this library to be called
        // zlib_a.lib, so make sure it's named correctly (where libz-sys just
        // produces zlib.lib)
        let _ = fs::remove_file(&inc.join("lib/zlib_a.lib"));
        t!(fs::hard_link(inc.join("lib/zlib.lib"), inc.join("lib/zlib_a.lib")));
    }
    run(&mut cmd, "nmake");

    let name = format!("libcurl-vc-{}-release-static-zlib-static-\
                        ipv6-sspi-winssl", machine);
    let libs = src.join("curl/builds").join(name);

    t!(fs::copy(libs.join("lib/libcurl_a.lib"), dst.join("lib/curl.lib")));
    for f in t!(fs::read_dir(libs.join("include/curl"))) {
        let path = t!(f).path();
        let dst = dst.join("include/curl").join(path.file_name().unwrap());
        t!(fs::copy(path, dst));
    }
    t!(fs::remove_dir_all(src.join("curl/builds")));
    println!("cargo:rustc-link-lib=wldap32");
    println!("cargo:rustc-link-lib=advapi32");
    println!("cargo:rustc-link-lib=normaliz");
}
<|endoftext|>


<commit_before>use std::io::Read;
use std::env;
use hyper::Client;
use hyper::header::Connection;
use std::collections::BTreeMap;
use rustc_serialize::json;
use std::fs::File;

static BASE_URL:    &'static str = "https://www.googleapis.com/youtube/v3";
lazy_static! {
    static ref API_KEY: String = {
        let opt_key = env::var("YOUTUBE_API_KEY");
        match opt_key {
            Ok(key) => key,
            Err(_) => {
                let mut f = File::open("youtube.txt").unwrap();
                let mut s = String::new();
                let _ = f.read_to_string(&mut s);
                s
            }
        }
    };
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct Thumbnail {
    pub url:    String,
    pub width:  i32,
    pub height: i32
}

impl PartialEq for Thumbnail {
    fn eq(&self, t: &Thumbnail) -> bool {
        return self.url == t.url;
    }
}

#[allow(non_snake_case)]
#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct PlaylistItemResponse {
    pub kind:          String,
    pub etag:          String,
    pub nextPageToken: String,
    pub pageInfo:      BTreeMap<String, i32>,
    pub items:         Vec<PlaylistItem>,
}

#[allow(non_snake_case)]
#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct PlaylistItem {
    pub kind:    String,
    pub etag:    String,
    pub id:      String,
    pub snippet: PlaylistItemSnippet,
}

#[allow(non_snake_case)]
#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct PlaylistItemSnippet {
    pub title:         String,
    pub description:   String,
    pub publishedAt:   String,
    pub channelId:     String,
    pub channelTitle:  String,
    pub thumbnails:    BTreeMap<String, Thumbnail>,
    pub position:      i32,
    pub playlistId:    String,
    pub resourceId:    BTreeMap<String, String>
}

pub fn fetch_playlist(id: &str) -> json::DecodeResult<PlaylistItemResponse> {
    let params = format!("key={}&part=snippet&playlistId={}", *API_KEY, id);
    let url    = format!("{}/{}?{}",
                         BASE_URL,
                         "playlistItems",
                         params);
    println!("{}", url);
    let client = Client::new();
    let mut res = client.get(&url)
        .header(Connection::close())
        .send().unwrap();

    let mut body = String::new();
    res.read_to_string(&mut body).unwrap();

    return  json::decode::<PlaylistItemResponse>(&body)
}

<commit_msg>Implement youtube::fetch_video<commit_after>use std::io::Read;
use std::env;
use hyper::Client;
use hyper::header::Connection;
use std::collections::BTreeMap;
use rustc_serialize::json;
use std::fs::File;

static BASE_URL:    &'static str = "https://www.googleapis.com/youtube/v3";
lazy_static! {
    static ref API_KEY: String = {
        let opt_key = env::var("YOUTUBE_API_KEY");
        match opt_key {
            Ok(key) => key,
            Err(_) => {
                let mut f = File::open("youtube.txt").unwrap();
                let mut s = String::new();
                let _ = f.read_to_string(&mut s);
                s
            }
        }
    };
}

#[derive(Debug, Clone, RustcDecodable, RustcEncodable)]
pub struct Thumbnail {
    pub url:    String,
    pub width:  i32,
    pub height: i32
}

impl PartialEq for Thumbnail {
    fn eq(&self, t: &Thumbnail) -> bool {
        return self.url == t.url;
    }
}

#[allow(non_snake_case)]
#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct PlaylistItemResponse {
    pub kind:          String,
    pub etag:          String,
    pub nextPageToken: String,
    pub pageInfo:      BTreeMap<String, i32>,
    pub items:         Vec<PlaylistItem>,
}

#[allow(non_snake_case)]
#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct PlaylistItem {
    pub kind:    String,
    pub etag:    String,
    pub id:      String,
    pub snippet: PlaylistItemSnippet,
}

#[allow(non_snake_case)]
#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct PlaylistItemSnippet {
    pub title:         String,
    pub description:   String,
    pub publishedAt:   String,
    pub channelId:     String,
    pub channelTitle:  String,
    pub thumbnails:    BTreeMap<String, Thumbnail>,
    pub position:      i32,
    pub playlistId:    String,
    pub resourceId:    BTreeMap<String, String>
}

#[allow(non_snake_case)]
#[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct VideoResponse {
    pub kind:          String,
    pub etag:          String,
    pub pageInfo:      BTreeMap<String, i32>,
    pub items:         Vec<Video>,
}

#[allow(non_snake_case)]
#[derive(Debug, Clone, RustcDecodable, RustcEncodable)]
pub struct Video {
    pub kind:    String,
    pub etag:    String,
    pub id:      String,
    pub snippet: VideoSnippet,
}

#[allow(non_snake_case)]
#[derive(Debug, Clone, RustcDecodable, RustcEncodable)]
pub struct VideoSnippet {
    pub title:                String,
    pub description:          String,
    pub publishedAt:          String,
    pub channelId:            String,
    pub channelTitle:         String,
    pub thumbnails:           BTreeMap<String, Thumbnail>,
    pub tags:                 Vec<String>,
    pub categoryId:           String,
    pub liveBroadcastContent: String,
}

pub fn fetch_playlist(id: &str) -> json::DecodeResult<PlaylistItemResponse> {
    let params = format!("key={}&part=snippet&playlistId={}", *API_KEY, id);
    let url    = format!("{}/{}?{}", BASE_URL, "playlistItems", params);
    let client = Client::new();
    let mut res = client.get(&url)
                        .header(Connection::close())
                        .send().unwrap();

    let mut body = String::new();
    res.read_to_string(&mut body).unwrap();
    json::decode::<PlaylistItemResponse>(&body)
}

pub fn fetch_video(id: &str) -> json::DecodeResult<Video> {
    let params = format!("key={}&part=snippet&id={}", *API_KEY, id);
    let url    = format!("{}/{}?{}", BASE_URL, "videos", params);
    let client = Client::new();
    let mut res = client.get(&url)
                        .header(Connection::close())
                        .send().unwrap();
    let mut body = String::new();
    res.read_to_string(&mut body).unwrap();
    let res = try!(json::decode::<VideoResponse>(&body));
    if res.items.len() > 0 {
        return Ok(res.items[0].clone());
    }
    Err(json::DecoderError::ApplicationError("track not found".to_string()))
}
<|endoftext|>


<commit_before>///! fff-lang
///!
///! pefile, from native program with its attributes and instructions to binary

extern crate util;

mod errors;
mod dos_header;
mod file_headers;

use errors::Error;
use dos_header::get_default_dos_header;
use dos_header::check_dos_header;

pub use file_headers::FileHeader;
pub use file_headers::FileAttributes;
pub use file_headers::FileHeaderDirectoryIndex;
pub use file_headers::DataDirecotry;

pub struct PEFile {
    // nt_headers: ImageNTHeader,
}
impl PEFile {

    pub fn new() {
    }

    pub fn from_bytes(bytes: &[u8]) -> Result<PEFile, Error> {
        let _file_header_offset = check_dos_header(bytes)?;
        Ok(PEFile{})
    }
    pub fn into_bytes(self) {
        let _dos_header_bytes = get_default_dos_header();
    }
}

#[cfg(test)] #[test]
fn gen_hello_world_test() {
    use std::fs::File;
    use std::io::Write;
    use dos_header::get_default_dos_header;

    let dos_header_bytes = get_default_dos_header();

    let file_header = FileHeader::new();

    let file_header_bytes = file_header.into_bytes();

    let mut file = File::create(r"..\tests\pefile\gened-hello.exe").expect("Create file failed");
    let _ = file.write(&dos_header_bytes[..]).expect("write dos header failed");
    let _ = file.write(&file_header_bytes[..]).expect("write nt header failed");
    let _ = file.flush().expect("flush file failed");
}

#[cfg(test)] #[test] #[ignore]
fn it_works() {
    // first expect

    // let statics = ["Helloworld"];
    // let imports = [
    //     ("kernel32", "GetConsoleHandle"),
    //     ("kernel32", "WriteConsole"),
    //     ("kernel32", "ExitProcess"),
    // ];
    // let code = [
    //     MOV(RBP, RSP),
    //     PUSH(RBP),
    //     MOV(RAX, -11),
    //     CALL(imports[0]),
    //     MOV(RAX, [RBP - 4]),
    //     PUSH(statics[0]),
    //     PUSH(11),
    //     PUSH([RBP - 4]),
    //     CALL(imports[1]),
    //     XOR(RAX, RAX),
    //     CALL(imports[2]),
    // ]
    // let pefile = PEFile::new(statics, imports, code);
    // let file = File::create("hello.exe").expect("create failed");
    // pefile.write(file);
}
<commit_msg>[pefile] add todo<commit_after>///! fff-lang
///!
///! pefile, from native program with its attributes and instructions to binary

extern crate util;

mod errors;
mod dos_header;
mod file_headers;

use errors::Error;
use dos_header::get_default_dos_header;
use dos_header::check_dos_header;

pub use file_headers::FileHeader;
pub use file_headers::FileAttributes;
pub use file_headers::FileHeaderDirectoryIndex;
pub use file_headers::DataDirecotry;

pub struct PEFile {
    // nt_headers: ImageNTHeader,
}
impl PEFile {

    pub fn new() {
    }

    pub fn from_bytes(bytes: &[u8]) -> Result<PEFile, Error> {
        let _file_header_offset = check_dos_header(bytes)?;
        Ok(PEFile{})
    }
    pub fn into_bytes(self) {
        let _dos_header_bytes = get_default_dos_header();
    }
}

#[cfg(test)] #[test]
fn gen_hello_world_test() {
    use std::fs::File;
    use std::io::Write;
    use dos_header::get_default_dos_header;

    let dos_header_bytes = get_default_dos_header();

    let file_header = FileHeader::new();

    let file_header_bytes = file_header.into_bytes();

    let mut file = File::create(r"..\tests\pefile\gened-hello.exe").expect("Create file failed");
    let _ = file.write(&dos_header_bytes[..]).expect("write dos header failed");
    let _ = file.write(&file_header_bytes[..]).expect("write nt header failed");
    let _ = file.flush().expect("flush file failed");
}

#[cfg(test)] #[test] #[ignore]
fn it_works() {
    // first expect

    // let statics = ["Helloworld"];
    // let imports = [
    //     ("kernel32", "GetConsoleHandle"),
    //     ("kernel32", "WriteConsole"),
    //     ("kernel32", "ExitProcess"),
    // ];
    // let code = [
    //     MOV(RBP, RSP),
    //     PUSH(RBP),
    //     MOV(RAX, -11),
    //     CALL(imports[0]),
    //     MOV(RAX, [RBP - 4]),
    //     PUSH(statics[0]),
    //     PUSH(11),
    //     PUSH([RBP - 4]),
    //     CALL(imports[1]),
    //     XOR(RAX, RAX),
    //     CALL(imports[2]),
    // ]
    // let pefile = PEFile::new(statics, imports, code);
    // let file = File::create("hello.exe").expect("create failed");
    // pefile.write(file);
}

// TODO:
// try to finish file header part of helloworld exe generation
// continue working on from bytes but do not check too much, only check is PE and is x64
//     no one will give you a file with exe extension and MZ header but with very very special this and that byte not correct<|endoftext|>