<commit_before>//! Manipulations and data types that represent 2d matrix.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results, unused_typecasts)]

extern crate num;

use std::ops::{Add, Index, IndexMut, Mul, Sub};
use num::{One, Zero};

/// 2D matrix.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Matrix<T> {
    row: usize,
    column: usize,
    data: Vec<T>
}

impl<T> Matrix<T> {
    /// Creates a new `Matrix`.
    #[inline]
    pub fn from_fn<F>(row: usize, column: usize, f: F) -> Matrix<T>
        where F:Fn(usize, usize) -> T
    {
        Matrix {
            row: row,
            column: column,
            data: (0 .. row * column).map(|i| f(i / column, i % column)).collect()
        }
    }

    /// Creates a new `Matrix` from vector.
    #[inline]
    pub fn from_vec(row: usize, column: usize, data: Vec<T>) -> Matrix<T> {
        assert_eq!(row * column, data.len());
        Matrix { row: row, column: column, data: data }
    }

    /// Returns the matrix's row and column.
    #[inline]
    pub fn size(&self) -> (usize, usize) { (self.row(), self.column()) }
    /// Returns the matrix's row.
    #[inline]
    pub fn row(&self) -> usize { self.row }
    /// Returns the matrix's column.
    #[inline]
    pub fn column(&self) -> usize { self.column }
}

impl<T: Zero> Matrix<T> {
    /// Creates a matrix whose elements are all zero.
    #[inline]
    pub fn zero(row: usize, column: usize) -> Matrix<T> {
        Matrix::from_fn(row, column, |_, _| Zero::zero())
    }
}

impl<T: One + Zero> Matrix<T> {
    /// Creates a identity matrix.
    #[inline]
    pub fn one(row: usize, column: usize) -> Matrix<T> {
        Matrix::from_fn(row, column, |i, j| {
            if i == j {
                One::one()
            } else {
                Zero::zero()
            }
        })
    }
}

impl<T: Clone> Matrix<T> {
    #[inline]
    /// Returns transpose of the matrix.
    pub fn trans(&self) -> Matrix<T> {
        Matrix::from_fn(self.column(), self.row(), |i, j| self[(j, i)].clone())
    }
}

impl<T> Index<(usize, usize)> for Matrix<T> {
    type Output = T;

    #[inline]
    fn index(&self, (i, j): (usize, usize)) -> &T {
        assert!(i < self.row() && j < self.column());
        &self.data[i * self.column() + j]
    }
}

impl<T> IndexMut<(usize, usize)> for Matrix<T> {
    #[inline]
    fn index_mut(&mut self, (i, j): (usize, usize)) -> &mut T {
        assert!(i < self.row && j < self.column);
        &mut self.data[i * self.column + j]
    }
}

macro_rules! forward_val_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<Lhs, Rhs> $imp<Matrix<Rhs>> for Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(&other)
            }
        }
    }
}

macro_rules! forward_ref_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<Matrix<Rhs>> for &'a Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                self.$method(&other)
            }
        }
    }
}

macro_rules! forward_val_ref_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<&'a Matrix<Rhs>> for Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(other)
            }
        }
    }
}

macro_rules! forward_all_binop {
    (impl $imp:ident, $method:ident) => {
        forward_val_val_binop!(impl $imp, $method);
        forward_ref_val_binop!(impl $imp, $method);
        forward_val_ref_binop!(impl $imp, $method);
    };
}

forward_all_binop!(impl Add, add);

impl<'a, 'b, Lhs, Rhs> Add<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Add<Rhs> + Clone, Rhs: Clone
{
    type Output = Matrix<<Lhs as Add<Rhs>>::Output>;

    #[inline]
    fn add(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Add<Rhs>>::Output> {
        assert_eq!(self.size(), other.size());
        Matrix::from_fn(self.row(), self.column(), |i, j| self[(i, j)].clone() + other[(i, j)].clone())
    }
}

forward_all_binop!(impl Sub, sub);

impl<'a, 'b, Lhs, Rhs> Sub<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Sub<Rhs> + Clone, Rhs: Clone
{
    type Output = Matrix<<Lhs as Sub<Rhs>>::Output>;

    #[inline]
    fn sub(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Sub<Rhs>>::Output> {
        assert_eq!(self.size(), other.size());
        Matrix::from_fn(self.row(), self.column(), |i, j| self[(i, j)].clone() - other[(i, j)].clone())
    }
}

impl<Lhs, Rhs> Mul<Matrix<Rhs>> for Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        (&self).mul(&other)
    }
}

impl<'a, Lhs, Rhs> Mul<Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: Matrix<Rhs>) ->  Matrix<<Lhs as Mul<Rhs>>::Output> {
        self.mul(&other)
    }
}

impl<'a, Lhs, Rhs> Mul<&'a Matrix<Rhs>> for Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        self.mul(other)
    }
}

impl<'a, 'b, Lhs, Rhs> Mul<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        assert_eq!(self.column(), other.row());
        Matrix::from_fn(self.row(), other.column(), |i, j| {
            let mut sum = self[(i, 0)].clone() * other[(0, j)].clone();
            for k in 1 .. self.column() {
                sum = sum + self[(i, k)].clone() * other[(k, j)].clone();
            }
            sum
        })
    }
}

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

    #[test]
    fn from_vec() {
        let mat = Matrix::from_vec(2, 3, vec![(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]);
        for i in 0 .. mat.row() {
            for j in 0 .. mat.column() {
                assert_eq!((i, j), mat[(i, j)]);
            }
        }
    }

    #[test]
    fn index() {
        let mat = Matrix::from_fn(3, 5, |i, j| (i, j));
        for i in 0 .. mat.row() {
            for j in 0 .. mat.column() {
                assert_eq!((i, j), mat[(i, j)]);
            }
        }
    }

    #[test]
    fn mul() {
        let m1 = Matrix::from_vec(1, 3, vec![1.0f64, 2.0, 3.0]);
        let m2 = Matrix::from_vec(3, 1, vec![1.0, 2.0, 3.0]);
        assert_eq!(Matrix::from_vec(1, 1, vec![14.0]), m1 * m2);
        assert_eq!(Matrix::from_vec(3, 1, vec![1.0f64, 4.0, 7.0]),
                   Matrix::from_vec(3, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) *
                   Matrix::from_vec(3, 1, vec![1.0, 0.0, 0.0]));
        assert_eq!(Matrix::from_vec(3, 2, vec![1.0f64, 3.0, 4.0, 6.0, 7.0, 9.0]),
                   Matrix::from_vec(3, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) *
                   Matrix::from_vec(3, 2, vec![1.0, 0.0, 0.0, 0.0, 0.0, 1.0]));
    }
}

<commit_msg>added test for IndexMut implementation<commit_after>//! Manipulations and data types that represent 2d matrix.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results, unused_typecasts)]

extern crate num;

use std::ops::{Add, Index, IndexMut, Mul, Sub};
use num::{One, Zero};

/// 2D matrix.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Matrix<T> {
    row: usize,
    column: usize,
    data: Vec<T>
}

impl<T> Matrix<T> {
    /// Creates a new `Matrix`.
    #[inline]
    pub fn from_fn<F>(row: usize, column: usize, f: F) -> Matrix<T>
        where F:Fn(usize, usize) -> T
    {
        Matrix {
            row: row,
            column: column,
            data: (0 .. row * column).map(|i| f(i / column, i % column)).collect()
        }
    }

    /// Creates a new `Matrix` from vector.
    #[inline]
    pub fn from_vec(row: usize, column: usize, data: Vec<T>) -> Matrix<T> {
        assert_eq!(row * column, data.len());
        Matrix { row: row, column: column, data: data }
    }

    /// Returns the matrix's row and column.
    #[inline]
    pub fn size(&self) -> (usize, usize) { (self.row(), self.column()) }
    /// Returns the matrix's row.
    #[inline]
    pub fn row(&self) -> usize { self.row }
    /// Returns the matrix's column.
    #[inline]
    pub fn column(&self) -> usize { self.column }
}

impl<T: Zero> Matrix<T> {
    /// Creates a matrix whose elements are all zero.
    #[inline]
    pub fn zero(row: usize, column: usize) -> Matrix<T> {
        Matrix::from_fn(row, column, |_, _| Zero::zero())
    }
}

impl<T: One + Zero> Matrix<T> {
    /// Creates a identity matrix.
    #[inline]
    pub fn one(row: usize, column: usize) -> Matrix<T> {
        Matrix::from_fn(row, column, |i, j| {
            if i == j {
                One::one()
            } else {
                Zero::zero()
            }
        })
    }
}

impl<T: Clone> Matrix<T> {
    #[inline]
    /// Returns transpose of the matrix.
    pub fn trans(&self) -> Matrix<T> {
        Matrix::from_fn(self.column(), self.row(), |i, j| self[(j, i)].clone())
    }
}

impl<T> Index<(usize, usize)> for Matrix<T> {
    type Output = T;

    #[inline]
    fn index(&self, (i, j): (usize, usize)) -> &T {
        assert!(i < self.row() && j < self.column());
        &self.data[i * self.column() + j]
    }
}

impl<T> IndexMut<(usize, usize)> for Matrix<T> {
    #[inline]
    fn index_mut(&mut self, (i, j): (usize, usize)) -> &mut T {
        assert!(i < self.row && j < self.column);
        &mut self.data[i * self.column + j]
    }
}

macro_rules! forward_val_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<Lhs, Rhs> $imp<Matrix<Rhs>> for Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(&other)
            }
        }
    }
}

macro_rules! forward_ref_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<Matrix<Rhs>> for &'a Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                self.$method(&other)
            }
        }
    }
}

macro_rules! forward_val_ref_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<&'a Matrix<Rhs>> for Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(other)
            }
        }
    }
}

macro_rules! forward_all_binop {
    (impl $imp:ident, $method:ident) => {
        forward_val_val_binop!(impl $imp, $method);
        forward_ref_val_binop!(impl $imp, $method);
        forward_val_ref_binop!(impl $imp, $method);
    };
}

forward_all_binop!(impl Add, add);

impl<'a, 'b, Lhs, Rhs> Add<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Add<Rhs> + Clone, Rhs: Clone
{
    type Output = Matrix<<Lhs as Add<Rhs>>::Output>;

    #[inline]
    fn add(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Add<Rhs>>::Output> {
        assert_eq!(self.size(), other.size());
        Matrix::from_fn(self.row(), self.column(), |i, j| self[(i, j)].clone() + other[(i, j)].clone())
    }
}

forward_all_binop!(impl Sub, sub);

impl<'a, 'b, Lhs, Rhs> Sub<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Sub<Rhs> + Clone, Rhs: Clone
{
    type Output = Matrix<<Lhs as Sub<Rhs>>::Output>;

    #[inline]
    fn sub(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Sub<Rhs>>::Output> {
        assert_eq!(self.size(), other.size());
        Matrix::from_fn(self.row(), self.column(), |i, j| self[(i, j)].clone() - other[(i, j)].clone())
    }
}

impl<Lhs, Rhs> Mul<Matrix<Rhs>> for Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        (&self).mul(&other)
    }
}

impl<'a, Lhs, Rhs> Mul<Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: Matrix<Rhs>) ->  Matrix<<Lhs as Mul<Rhs>>::Output> {
        self.mul(&other)
    }
}

impl<'a, Lhs, Rhs> Mul<&'a Matrix<Rhs>> for Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        self.mul(other)
    }
}

impl<'a, 'b, Lhs, Rhs> Mul<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        assert_eq!(self.column(), other.row());
        Matrix::from_fn(self.row(), other.column(), |i, j| {
            let mut sum = self[(i, 0)].clone() * other[(0, j)].clone();
            for k in 1 .. self.column() {
                sum = sum + self[(i, k)].clone() * other[(k, j)].clone();
            }
            sum
        })
    }
}

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

    #[test]
    fn from_vec() {
        let mat = Matrix::from_vec(2, 3, vec![(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]);
        for i in 0 .. mat.row() {
            for j in 0 .. mat.column() {
                assert_eq!((i, j), mat[(i, j)]);
            }
        }
    }

    #[test]
    fn index() {
        let mat = Matrix::from_fn(3, 5, |i, j| (i, j));
        for i in 0 .. mat.row() {
            for j in 0 .. mat.column() {
                assert_eq!((i, j), mat[(i, j)]);
            }
        }
    }

    #[test]
    fn index_mut() {
        let mut m = Matrix::one(2, 2);
        m[(1,1)] = 0;
        assert_eq!(Matrix::from_vec(2, 2, vec![1, 0, 0, 0]), m);
    }

    #[test]
    fn mul() {
        let m1 = Matrix::from_vec(1, 3, vec![1.0f64, 2.0, 3.0]);
        let m2 = Matrix::from_vec(3, 1, vec![1.0, 2.0, 3.0]);
        assert_eq!(Matrix::from_vec(1, 1, vec![14.0]), m1 * m2);
        assert_eq!(Matrix::from_vec(3, 1, vec![1.0f64, 4.0, 7.0]),
                   Matrix::from_vec(3, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) *
                   Matrix::from_vec(3, 1, vec![1.0, 0.0, 0.0]));
        assert_eq!(Matrix::from_vec(3, 2, vec![1.0f64, 3.0, 4.0, 6.0, 7.0, 9.0]),
                   Matrix::from_vec(3, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) *
                   Matrix::from_vec(3, 2, vec![1.0, 0.0, 0.0, 0.0, 0.0, 1.0]));
    }
}

<|endoftext|>


<commit_before>#![feature(no_std)]
#![no_std]

pub unsafe fn load(address: usize) -> &'static Multiboot {
    let multiboot = &*(address as *const Multiboot);
    assert!(multiboot.has_valid_end_tag());
    multiboot
}

#[repr(C)]
pub struct Multiboot {
    pub total_size: u32,
    _reserved: u32,
    // tags
}

impl Multiboot {
    fn has_valid_end_tag(&self) -> bool {
        const END_TAG: Tag = Tag{typ:0, size:8};

        let self_ptr = self as *const _;
        let end_tag_addr = self_ptr as usize + (self.total_size - END_TAG.size) as usize;
        let end_tag = unsafe{&*(end_tag_addr as *const Tag)};

        end_tag.typ == END_TAG.typ && end_tag.size == END_TAG.size
    }
}

#[repr(C)]
struct Tag {
    typ: u32,
    size: u32,
    // tag specific fields
}
<commit_msg>Add tag iterator and `get_tag` method<commit_after>#![feature(no_std)]
#![no_std]

use core::mem::size_of;

pub unsafe fn load(address: usize) -> &'static Multiboot {
    let multiboot = &*(address as *const Multiboot);
    assert!(multiboot.has_valid_end_tag());
    multiboot
}

#[repr(C)]
pub struct Multiboot {
    pub total_size: u32,
    _reserved: u32,
    // tags
}

impl Multiboot {
    fn has_valid_end_tag(&self) -> bool {
        const END_TAG: Tag = Tag{typ:0, size:8};

        let self_ptr = self as *const _;
        let end_tag_addr = self_ptr as usize + (self.total_size - END_TAG.size) as usize;
        let end_tag = unsafe{&*(end_tag_addr as *const Tag)};

        end_tag.typ == END_TAG.typ && end_tag.size == END_TAG.size
    }

    fn get_tag(&self, typ: u32) -> Option<&'static Tag> {
        self.tags().find(|tag| tag.typ == typ)
    }

    fn tags(&self) -> TagIter {
        let self_addr = self as *const _ as usize;
        let first_tag = (self_addr + size_of::<Multiboot>()) as *const Tag;
        TagIter{current: first_tag}
    }
}

#[repr(C)]
struct Tag {
    typ: u32,
    size: u32,
    // tag specific fields
}

struct TagIter {
    current: *const Tag,
}

impl Iterator for TagIter {
    type Item = &'static Tag;

    fn next(&mut self) -> Option<&'static Tag> {
        match unsafe{&*self.current} {
            &Tag{typ:0, size:8} => None, // end tag
            tag => {
                // go to next tag
                let mut tag_addr = self.current as usize;
                tag_addr += tag.size as usize;
                tag_addr = ((tag_addr-1) & !0x7) + 0x8; //align at 8 byte
                self.current = tag_addr as *const _;

                Some(tag)
            },
        }
    }
}
<|endoftext|>


<commit_before>//! # `object`
//!
//! The `object` crate provides a unified interface to working with object files
//! across platforms. It supports reading object files and executable files,
//! and writing object files.
//!
//! See the [`File` struct](./read/struct.File.html) for details.

#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![no_std]

#[cfg(feature = "cargo-all")]
compile_error!("'--all-features' is not supported; use '--features all' instead");

#[allow(unused_imports)]
#[macro_use]
extern crate alloc;

#[cfg(feature = "std")]
#[allow(unused_imports)]
#[macro_use]
extern crate std;

mod common;
pub use common::*;

#[macro_use]
pub mod endian;
pub use endian::*;

#[macro_use]
pub mod pod;
pub use pod::*;

#[cfg(feature = "read_core")]
pub mod read;
#[cfg(feature = "read_core")]
pub use read::*;

#[cfg(feature = "write_core")]
pub mod write;

#[cfg(feature = "archive")]
pub mod archive;
#[cfg(feature = "elf")]
pub mod elf;
#[cfg(feature = "macho")]
pub mod macho;
#[cfg(any(feature = "coff", feature = "pe"))]
pub mod pe;
<commit_msg>doc: better crate overview<commit_after>//! # `object`
//!
//! The `object` crate provides a unified interface to working with object files
//! across platforms. It supports reading object files and executable files,
//! and writing object files.
//!
//! ## Raw struct definitions
//!
//! Raw structs are defined for: [ELF](elf), [Mach-O](macho), [PE/COFF](pe), [archive].
//! Types and traits for zerocopy support are defined in [pod] and [endian].
//!
//! ## Unified read API
//!
//! The [read::Object] trait defines the unified interace. This trait is implemented
//! by [read::File], which allows reading any file format, as well as implementations
//! for each file format: [ELF](read::elf::ElfFile), [Mach-O](read::macho::MachOFile),
//! [COFF](read::coff::CoffFile), [PE](read::pe::PeFile), [Wasm](read::wasm::WasmFile).
//!
//! ## Low level read API
//!
//! In addition to the unified read API, the various `read` modules define helpers that
//! operate on the raw structs. These also provide traits that abstract over the differences
//! between 32-bit and 64-bit versions of the file format.
//!
//! ## Unified write API
//!
//! [write::Object] allows building an object and then writing it out.

#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![no_std]

#[cfg(feature = "cargo-all")]
compile_error!("'--all-features' is not supported; use '--features all' instead");

#[allow(unused_imports)]
#[macro_use]
extern crate alloc;

#[cfg(feature = "std")]
#[allow(unused_imports)]
#[macro_use]
extern crate std;

mod common;
pub use common::*;

#[macro_use]
pub mod endian;
pub use endian::*;

#[macro_use]
pub mod pod;
pub use pod::*;

#[cfg(feature = "read_core")]
pub mod read;
#[cfg(feature = "read_core")]
pub use read::*;

#[cfg(feature = "write_core")]
pub mod write;

#[cfg(feature = "archive")]
pub mod archive;
#[cfg(feature = "elf")]
pub mod elf;
#[cfg(feature = "macho")]
pub mod macho;
#[cfg(any(feature = "coff", feature = "pe"))]
pub mod pe;
<|endoftext|>


<commit_before>extern crate term;
extern crate termios;

use term::terminfo::TermInfo;
use termios::Termios;
use std::string::String;
use std::io::{stdin, Stdin, stdout, Stdout, stderr, Stderr};

/// Holds the state for the line editor
pub struct Rebar {
    i: Stdin,   //stdin handle
    o: Stdout,  //stdout handle
    e: Stderr,  //stderr handle
    termio: Termios,
    terms: TermInfo,
    prompt: String,
    buf: String,
    cursor_pos: usize,
}

/// Initialisation function
pub fn rebar() -> Rebar {
    let info = match TermInfo::from_env() {
        Ok(s) => s,
        Err(f) => panic!(f),
    };
    let ios = match Termios::from_fd(0) {
        Ok(s) => s,
        Err(f) => panic!(f),
    };
    let res = Rebar {
        i: stdin(),
        o: stdout(),
        e: stderr(),
        termio: ios,
        terms: info,
        prompt: String::new(),
        buf: String::new(),
        cursor_pos: 0
    };
    res
}

///Clears the screen using terminfo-based clear string
pub fn clear() {
    let info = term::terminfo::TermInfo::from_env();

    let fred = match info {
        Ok(val) => val,
        Err(f) => panic!(f.to_string()),
    };

    let clear = fred.strings.get("clear").unwrap();
    let mut derf = term::stdout().unwrap();
    match derf.write_all(clear) {
        Ok(..) => {},
        Err(f) => println!("Failed to clear: {}", f),
    };
}

///Refresh the line, so that you can move cursors and shit
pub fn refresh_screen(inline: &str) {
    let mut line = String::new();
    line.push_str("\r");
    line.push_str(inline);
    print!("{}", line);
}

#[test]
fn clear_screen() {
    clear();
}
<commit_msg>added test functions<commit_after>extern crate term;
extern crate termios;

use term::terminfo::TermInfo;
use termios::Termios;
use std::string::String;
use std::io::{stdin, Stdin, stdout, Stdout, stderr, Stderr};

/// Holds the state for the line editor
pub struct Rebar {
    i: Stdin,   //stdin handle
    o: Stdout,  //stdout handle
    e: Stderr,  //stderr handle
    termio: Termios,
    terms: TermInfo,
    prompt: String,
    buf: String,
    cursor_pos: usize,
}

/// Initialisation function
pub fn rebar() -> Rebar {
    let info = match TermInfo::from_env() {
        Ok(s) => s,
        Err(f) => panic!(f),
    };
    let ios = match Termios::from_fd(0) {
        Ok(s) => s,
        Err(f) => panic!(f),
    };
    let res = Rebar {
        i: stdin(),
        o: stdout(),
        e: stderr(),
        termio: ios,
        terms: info,
        prompt: String::new(),
        buf: String::new(),
        cursor_pos: 0
    };
    res
}

///Clears the screen using terminfo-based clear string
pub fn clear() {
    let info = term::terminfo::TermInfo::from_env();

    let fred = match info {
        Ok(val) => val,
        Err(f) => panic!(f.to_string()),
    };

    let clear = fred.strings.get("clear").unwrap();
    let mut derf = term::stdout().unwrap();
    match derf.write_all(clear) {
        Ok(..) => {},
        Err(f) => println!("Failed to clear: {}", f),
    };
}

///Refresh the line, so that you can move cursors and shit
pub fn refresh_screen(inline: &str) {
    let mut line = String::new();
    line.push_str("\r");
    line.push_str(inline);
    print!("{}", line);
}

#[test]
fn init_rebar() {
    let reb = rebar();
    reb.prompt.push("$");
    reb.cursor_pos += 1;
}

#[test]
fn clear_screen() {
    clear();
}

#[test]
fn refresh() {
    refresh_screen("");
}<|endoftext|>


<commit_before>// Copyright 2016 Google Inc.
//
// 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.

extern crate libc;

use libc::{int32_t, uint32_t};
use std::{slice, str};
use std::ffi::{CStr, CString};

mod ffi;

/// Shader kind.
///
/// * The `Glsl<stage>` enumerants are forced shader kinds, which force the
///   compiler to compile the source code as the specified kind of shader,
///   regardless of `#pragma` annotations in the source code.
/// * The `GlslDefault<stage>` enumerants are default shader kinds, which
///   allow the compiler to fall back to compile the source code as the
///   specified kind of shader when `#pragma` is not found in the source
///   code.
#[repr(C)]
pub enum ShaderKind {
    GlslVertex,
    GlslFragment,
    GlslCompute,
    GlslGeometry,
    GlslTessControl,
    GlslTessEvaluation,

    /// Deduce the shader kind from `#pragma` annotation in the source code.
    ///
    /// Compiler will emit error if `#pragma` annotation is not found.
    GlslInferFromSource,

    GlslDefaultVertex,
    GlslDefaultFragment,
    GlslDefaultCompute,
    GlslDefaultGeometry,
    GlslDefaultTessControl,
    GlslDefaultTessEvaluation,

    SpirvAssembly,
}

/// An opaque object managing all compiler states.
pub struct Compiler {
    raw: *mut ffi::ShadercCompiler,
}

impl Compiler {
    pub fn new() -> Compiler {
        Compiler { raw: unsafe { ffi::shaderc_compiler_initialize() } }
    }

    pub fn compile_into_spirv(&mut self,
                              source_text: String,
                              shader_kind: ShaderKind,
                              input_file_name: String,
                              entry_point_name: String,
                              additional_options: &CompileOptions)
                              -> CompilationResult {
        let source_size = source_text.len();
        let c_source = CString::new(source_text).expect("cannot convert source to c string");
        let c_file = CString::new(input_file_name)
                         .expect("cannot convert input_file_name to c string");
        let c_entry_point = CString::new(entry_point_name)
                                .expect("cannot convert entry_point_name to c string");
        let result = unsafe {
            ffi::shaderc_compile_into_spv(self.raw,
                                          c_source.as_ptr(),
                                          source_size,
                                          shader_kind as int32_t,
                                          c_file.as_ptr(),
                                          c_entry_point.as_ptr(),
                                          additional_options.raw)
        };
        CompilationResult::new(result, true)
    }

    pub fn compile_into_spirv_assembly(&mut self,
                                       source_text: String,
                                       shader_kind: ShaderKind,
                                       input_file_name: String,
                                       entry_point_name: String,
                                       additional_options: &CompileOptions)
                                       -> CompilationResult {
        let source_size = source_text.len();
        let c_source = CString::new(source_text).expect("cannot convert source to c string");
        let c_file = CString::new(input_file_name)
                         .expect("cannot convert input_file_name to c string");
        let c_entry_point = CString::new(entry_point_name)
                                .expect("cannot convert entry_point_name to c string");
        let result = unsafe {
            ffi::shaderc_compile_into_spv_assembly(self.raw,
                                                   c_source.as_ptr(),
                                                   source_size,
                                                   shader_kind as int32_t,
                                                   c_file.as_ptr(),
                                                   c_entry_point.as_ptr(),
                                                   additional_options.raw)
        };
        CompilationResult::new(result, false)
    }
}

impl Drop for Compiler {
    fn drop(&mut self) {
        unsafe { ffi::shaderc_compiler_release(self.raw) }
    }
}

/// An opaque object managing options to compilation.
pub struct CompileOptions {
    raw: *mut ffi::ShadercCompileOptions,
}

impl CompileOptions {
    fn new() -> CompileOptions {
        CompileOptions { raw: unsafe { ffi::shaderc_compile_options_initialize() } }
    }

    fn clone(&self) -> CompileOptions {
        CompileOptions { raw: unsafe { ffi::shaderc_compile_options_clone(self.raw) } }
    }
}

impl Drop for CompileOptions {
    fn drop(&mut self) {
        unsafe { ffi::shaderc_compile_options_release(self.raw) }
    }
}

/// An opaque object containing the results of compilation.
pub struct CompilationResult {
    raw: *mut ffi::ShadercCompilationResult,
    is_binary: bool,
}

impl CompilationResult {
    fn new(result: *mut ffi::ShadercCompilationResult, is_binary: bool) -> CompilationResult {
        CompilationResult {
            raw: result,
            is_binary: is_binary,
        }
    }

    pub fn len(&self) -> usize {
        unsafe { ffi::shaderc_result_get_length(self.raw) }
    }

    pub fn as_binary(&self) -> &[u32] {
        assert!(self.is_binary);

        let num_words = self.len() / 4;

        unsafe {
            let p = ffi::shaderc_result_get_bytes(self.raw);
            slice::from_raw_parts(p as *const uint32_t, num_words)
        }
    }

    pub fn as_text(&self) -> String {
        assert!(!self.is_binary);
        unsafe {
            let p = ffi::shaderc_result_get_bytes(self.raw);
            let bytes = CStr::from_ptr(p).to_bytes();
            str::from_utf8(bytes).ok().expect("invalid utf-8 string").to_string()
        }
    }
}

impl Drop for CompilationResult {
    fn drop(&mut self) {
        unsafe { ffi::shaderc_result_release(self.raw) }
    }
}

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

    static VOID_MAIN: &'static str = "#version 310 es\nvoid main() {}";
    static VOID_MAIN_ASSEMBLY: &'static str = "\
; SPIR-V
; Version: 1.0
; Generator: Google Shaderc over Glslang; 1
; Bound: 6
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport \"GLSL.std.450\"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Vertex %main \"main\"
               OpSource ESSL 310
               OpSourceExtension \"GL_GOOGLE_cpp_style_line_directive\"
               OpSourceExtension \"GL_GOOGLE_include_directive\"
               OpName %main \"main\"
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
       %main = OpFunction %void None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
";

    #[test]
    fn compile_vertex_shader_into_spirv() {
        let source = VOID_MAIN.to_string();
        let file = "shader.glsl".to_string();
        let entry_point = "main".to_string();

        let mut c = Compiler::new();
        let options = CompileOptions::new();
        let result = c.compile_into_spirv(source,
                                          ShaderKind::GlslVertex,
                                          file,
                                          entry_point,
                                          &options);
        assert!(result.len() > 20);
        assert!(result.as_binary().first() == Some(&0x07230203));
        let function_end_word: u32 = (1 << 16) | 56;
        assert!(result.as_binary().last() == Some(&function_end_word));
    }

    #[test]
    fn compile_vertex_shader_into_spirv_assembly() {
        let source = VOID_MAIN.to_string();
        let file = "shader.glsl".to_string();
        let entry_point = "main".to_string();

        let mut c = Compiler::new();
        let options = CompileOptions::new();
        let result = c.compile_into_spirv_assembly(source,
                                                   ShaderKind::GlslVertex,
                                                   file,
                                                   entry_point,
                                                   &options);
        assert_eq!(VOID_MAIN_ASSEMBLY, result.as_text());
    }
}
<commit_msg>Add documentation for methods in compiler, options, and result.<commit_after>// Copyright 2016 Google Inc.
//
// 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.

extern crate libc;

use libc::{int32_t, uint32_t};
use std::{slice, str};
use std::ffi::{CStr, CString};

mod ffi;

/// Shader kind.
///
/// * The `Glsl<stage>` enumerants are forced shader kinds, which force the
///   compiler to compile the source code as the specified kind of shader,
///   regardless of `#pragma` directives in the source code.
/// * The `GlslDefault<stage>` enumerants are default shader kinds, which
///   allow the compiler to fall back to compile the source code as the
///   specified kind of shader when `#pragma` is not found in the source
///   code.
#[repr(C)]
pub enum ShaderKind {
    GlslVertex,
    GlslFragment,
    GlslCompute,
    GlslGeometry,
    GlslTessControl,
    GlslTessEvaluation,

    /// Deduce the shader kind from `#pragma` directives in the source code.
    ///
    /// Compiler will emit error if `#pragma` annotation is not found.
    InferFromSource,

    GlslDefaultVertex,
    GlslDefaultFragment,
    GlslDefaultCompute,
    GlslDefaultGeometry,
    GlslDefaultTessControl,
    GlslDefaultTessEvaluation,

    SpirvAssembly,
}

/// An opaque object managing all compiler states.
pub struct Compiler {
    raw: *mut ffi::ShadercCompiler,
}

impl Compiler {
    /// Returns an compiler object that can be used to compile SPIR-V modules.
    ///
    /// A return of `None` indicates that there was an error initializing
    /// the underlying compiler.
    pub fn new() -> Option<Compiler> {
        let p = unsafe { ffi::shaderc_compiler_initialize() };
        if p.is_null() {
            None
        } else {
            Some(Compiler { raw: p })
        }
    }

    /// Compiles the given source string `source_text` to a SPIR-V module
    /// according to the given `additional_options`.
    ///
    /// The source string will be compiled into a SPIR-V binary module
    /// contained in a `CompilationResult` object.
    ///
    /// The source string is treated as the given shader kind `shader_kind`.
    /// If `InferFromSource` is given, the compiler will try to deduce the
    /// shader kind from the source string via `#pragma` directives and a
    /// failure in deducing will generate an error. If the shader kind is
    /// set to one of the default shader kinds, the compiler will fall back
    /// to the default shader kind in case it failed to deduce the shader
    /// kind from the source string.
    ///
    /// `input_file_name` is a string used as a tag to identify the source
    /// string in cases like emitting error messages. It doesn't have to be
    /// a canonical "file name".
    ///
    /// `entry_point_name` is a string defines the name of the entry point
    /// to associate with the source string.
    pub fn compile_into_spirv(&mut self,
                              source_text: String,
                              shader_kind: ShaderKind,
                              input_file_name: String,
                              entry_point_name: String,
                              additional_options: &CompileOptions)
                              -> CompilationResult {
        let source_size = source_text.len();
        let c_source = CString::new(source_text).expect("cannot convert source to c string");
        let c_file = CString::new(input_file_name)
                         .expect("cannot convert input_file_name to c string");
        let c_entry_point = CString::new(entry_point_name)
                                .expect("cannot convert entry_point_name to c string");
        let result = unsafe {
            ffi::shaderc_compile_into_spv(self.raw,
                                          c_source.as_ptr(),
                                          source_size,
                                          shader_kind as int32_t,
                                          c_file.as_ptr(),
                                          c_entry_point.as_ptr(),
                                          additional_options.raw)
        };
        CompilationResult::new(result, true)
    }

    /// Like `compile_into_spirv` but the result contains SPIR-V assembly text
    /// instead of binary module.
    pub fn compile_into_spirv_assembly(&mut self,
                                       source_text: String,
                                       shader_kind: ShaderKind,
                                       input_file_name: String,
                                       entry_point_name: String,
                                       additional_options: &CompileOptions)
                                       -> CompilationResult {
        let source_size = source_text.len();
        let c_source = CString::new(source_text).expect("cannot convert source to c string");
        let c_file = CString::new(input_file_name)
                         .expect("cannot convert input_file_name to c string");
        let c_entry_point = CString::new(entry_point_name)
                                .expect("cannot convert entry_point_name to c string");
        let result = unsafe {
            ffi::shaderc_compile_into_spv_assembly(self.raw,
                                                   c_source.as_ptr(),
                                                   source_size,
                                                   shader_kind as int32_t,
                                                   c_file.as_ptr(),
                                                   c_entry_point.as_ptr(),
                                                   additional_options.raw)
        };
        CompilationResult::new(result, false)
    }
}

impl Drop for Compiler {
    fn drop(&mut self) {
        unsafe { ffi::shaderc_compiler_release(self.raw) }
    }
}

/// An opaque object managing options to compilation.
pub struct CompileOptions {
    raw: *mut ffi::ShadercCompileOptions,
}

impl CompileOptions {
    /// Returns a default-initialized compilation options object.
    ///
    /// A return of `None` indicates that there was an error initializing
    /// the underlying options object.
    pub fn new() -> Option<CompileOptions> {
        let p = unsafe { ffi::shaderc_compile_options_initialize() };
        if p.is_null() {
            None
        } else {
            Some(CompileOptions { raw: p })
        }
    }

    /// Returns a copy of the given compilation options object.
    ///
    /// A return of `None` indicates that there was an error copying
    /// the underlying options object.
    pub fn clone(&self) -> Option<CompileOptions> {
        let p = unsafe { ffi::shaderc_compile_options_clone(self.raw) };
        if p.is_null() {
            None
        } else {
            Some(CompileOptions { raw: p })
        }
    }
}

impl Drop for CompileOptions {
    fn drop(&mut self) {
        unsafe { ffi::shaderc_compile_options_release(self.raw) }
    }
}

/// An opaque object containing the results of compilation.
pub struct CompilationResult {
    raw: *mut ffi::ShadercCompilationResult,
    is_binary: bool,
}

impl CompilationResult {
    fn new(result: *mut ffi::ShadercCompilationResult, is_binary: bool) -> CompilationResult {
        CompilationResult {
            raw: result,
            is_binary: is_binary,
        }
    }

    /// Returns the number of bytes of the compilation output data.
    pub fn len(&self) -> usize {
        unsafe { ffi::shaderc_result_get_length(self.raw) }
    }

    /// Returns the compilation output data as a binary slice.
    ///
    /// # Panics
    ///
    /// This method will panic if the compilation does not generate a
    /// binary output.
    pub fn as_binary(&self) -> &[u32] {
        if !self.is_binary {
            panic!("not binary result")
        }

        assert_eq!(0, self.len() % 4);
        let num_words = self.len() / 4;

        unsafe {
            let p = ffi::shaderc_result_get_bytes(self.raw);
            slice::from_raw_parts(p as *const uint32_t, num_words)
        }
    }

    /// Returns the compilation output data as a text string.
    ///
    /// # Panics
    ///
    /// This method will panic if the compilation does not generate a
    /// text output.
    pub fn as_text(&self) -> String {
        if self.is_binary {
            panic!("not text result")
        }
        unsafe {
            let p = ffi::shaderc_result_get_bytes(self.raw);
            let bytes = CStr::from_ptr(p).to_bytes();
            str::from_utf8(bytes).ok().expect("invalid utf-8 string").to_string()
        }
    }
}

impl Drop for CompilationResult {
    fn drop(&mut self) {
        unsafe { ffi::shaderc_result_release(self.raw) }
    }
}

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

    static VOID_MAIN: &'static str = "#version 310 es\nvoid main() {}";
    static VOID_MAIN_ASSEMBLY: &'static str = "\
; SPIR-V
; Version: 1.0
; Generator: Google Shaderc over Glslang; 1
; Bound: 6
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport \"GLSL.std.450\"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Vertex %main \"main\"
               OpSource ESSL 310
               OpSourceExtension \"GL_GOOGLE_cpp_style_line_directive\"
               OpSourceExtension \"GL_GOOGLE_include_directive\"
               OpName %main \"main\"
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
       %main = OpFunction %void None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
";

    #[test]
    fn compile_vertex_shader_into_spirv() {
        let source = VOID_MAIN.to_string();
        let file = "shader.glsl".to_string();
        let entry_point = "main".to_string();

        let mut c = Compiler::new().unwrap();
        let options = CompileOptions::new().unwrap();
        let result = c.compile_into_spirv(source,
                                          ShaderKind::GlslVertex,
                                          file,
                                          entry_point,
                                          &options);
        assert!(result.len() > 20);
        assert!(result.as_binary().first() == Some(&0x07230203));
        let function_end_word: u32 = (1 << 16) | 56;
        assert!(result.as_binary().last() == Some(&function_end_word));
    }

    #[test]
    fn compile_vertex_shader_into_spirv_assembly() {
        let source = VOID_MAIN.to_string();
        let file = "shader.glsl".to_string();
        let entry_point = "main".to_string();

        let mut c = Compiler::new().unwrap();
        let options = CompileOptions::new().unwrap();
        let result = c.compile_into_spirv_assembly(source,
                                                   ShaderKind::GlslVertex,
                                                   file,
                                                   entry_point,
                                                   &options);
        assert_eq!(VOID_MAIN_ASSEMBLY, result.as_text());
    }
}
<|endoftext|>


<commit_before>extern crate graphics;
extern crate input;

use graphics::{ Context, Graphics };
use input::{ GenericEvent };

mod drawutils;

pub struct Timeline {
    pub frames: u32,
    pub current_frame: u32,
    pub hover_frame: Option<u32>,
    pub start_frame: u32,
    pub bounds: [u32; 4],
    pub settings: TimelineSettings,
    pub hover_goto_start: bool,
    pub hover_goto_end: bool,
}

pub struct TimelineSettings {
    pub left_to_frame: f64,
    pub right_to_frame: f64,
    pub top_to_frame: f64,
    pub frame_width: f64,
    pub frame_height: f64,
    pub frame_offset_x: f64,
    pub left_to_goto_start: f64,
    pub right_to_goto_end: f64,
    pub lift_hover_frame: f64,
}

pub struct ComputedTimelineSettings {
    pub width_for_frames: f64,
    pub max_visible_frames: u32,
    pub end_frame: u32,
}

impl TimelineSettings {
    pub fn new() -> TimelineSettings {
        TimelineSettings {
            left_to_frame: 20.0,
            right_to_frame: 20.0,
            top_to_frame: 15.0,
            frame_width: 10.0,
            frame_height: 10.0,
            frame_offset_x: 5.0,
            left_to_goto_start: 5.0,
            right_to_goto_end: 5.0,
            lift_hover_frame: 10.0,
        }
    }
}

impl ComputedTimelineSettings {
    pub fn new(timeline: &Timeline, settings: &TimelineSettings)
        -> ComputedTimelineSettings
    {
        use std::cmp::min;

        let width_for_frames = timeline.bounds[2] as f64
            - settings.left_to_frame - settings.right_to_frame;
        let max_visible_frames: u32 =
            if width_for_frames < settings.frame_width {
                0
            } else {
                1
                + (
                    (width_for_frames - settings.frame_width)
                    / (settings.frame_width + settings.frame_offset_x)
                ) as u32
            };
        let end_frame = min(
            timeline.frames,
            timeline.start_frame + max_visible_frames
        );

        ComputedTimelineSettings {
            width_for_frames: width_for_frames,
            max_visible_frames: max_visible_frames,
            end_frame: end_frame
        }
    }
}

impl Timeline {
    pub fn new_frames_bounds(frames: u32, bounds: [u32; 4]) -> Timeline {
        Timeline {
            frames: frames,
            current_frame: 0,
            hover_frame: None,
            start_frame: 0,
            bounds: bounds,
            settings: TimelineSettings::new(),
            hover_goto_start: false,
            hover_goto_end: false,
        }
    }

    pub fn event<E: GenericEvent>(&mut self, e: &E) {
        use input::{ MouseCursorEvent, PressEvent };

        if let Some(pos) = e.mouse_cursor_args() {
            // Detect hover frame.
            {
                let computed_settings = ComputedTimelineSettings::new(self,
                    &self.settings);

                let left_to_frame: f64 = self.settings.left_to_frame;
                let frame_width: f64 = self.settings.frame_width;
                let frame_offset_x: f64 = self.settings.frame_offset_x;

                let end_frame: u32 = computed_settings.end_frame;

                let (x, y) = (pos[0], pos[1]);

                let left = self.bounds[0] as f64 + left_to_frame;
                let right = left + end_frame as f64 * (frame_width + frame_offset_x);
                let top = self.bounds[1] as f64;
                let bottom = top + self.bounds[3] as f64;

                if x < left || x > right
                || y < top || y > bottom {
                    self.hover_frame = None;
                } else {
                    let i: u32 = ((x - left) / (frame_width + frame_offset_x)) as u32;
                    self.hover_frame = Some(i);
                }
            }

            // Detect hover over goto start and goto end buttons.
            {
                let left_to_goto_start = self.settings.left_to_goto_start;
                let right_to_goto_end = self.settings.right_to_goto_end;
                let top_to_frame = self.settings.top_to_frame;
                let frame_width = self.settings.frame_width;
                let frame_height = self.settings.frame_height;

                let outside = |bounds: [f64; 4]| {
                    let (x, y) = (pos[0], pos[1]);
                    (x < bounds[0] || y < bounds[1]
                    || x > bounds[0] + bounds[2] || y > bounds[1] + bounds[3])
                };

                self.hover_goto_start = !outside([
                    self.bounds[0] as f64 + left_to_goto_start,
                    self.bounds[1] as f64 + top_to_frame,
                    frame_width,
                    frame_height
                ]);
                self.hover_goto_end = !outside([
                    self.bounds[0] as f64 + self.bounds[2] as f64
                        - right_to_goto_end - frame_width,
                    self.bounds[1] as f64 + top_to_frame,
                    frame_width,
                    frame_height
                ]);
            }
        }

        if let Some(button) = e.press_args() {
            use input::{ Button, MouseButton };

            if button == Button::Mouse(MouseButton::Left) {
                if self.hover_goto_start {
                    println!("TEST goto start");
                } else if self.hover_goto_end {
                    println!("TEST goto end");
                }
            }
        }
    }

    pub fn draw_timeline<G: Graphics>(&self, c: &Context, g: &mut G) {
        use std::cmp::min;

        let left_to_frame: f64 = self.settings.left_to_frame;
        let right_to_frame: f64 = self.settings.right_to_frame;
        let top_to_frame: f64 = self.settings.top_to_frame;
        let frame_width: f64 = self.settings.frame_width;
        let frame_height: f64 = self.settings.frame_height;
        let frame_offset_x: f64 = self.settings.frame_offset_x;
        let left_to_goto_start: f64 = self.settings.left_to_goto_start;
        let right_to_goto_end: f64 = self.settings.right_to_goto_end;
        let lift_hover_frame: f64 = self.settings.lift_hover_frame;

        let computed_settings = ComputedTimelineSettings::new(self, &self.settings);

        let slide_offset: f64 = 0.0;

        let width_for_frames = computed_settings.width_for_frames;
        let max_visible_frames: u32 = computed_settings.max_visible_frames;
        let end_frame = computed_settings.end_frame;

        let blue = [0.0, 0.0, 1.0, 1.0];
        let red = [1.0, 0.0, 0.0, 1.0];

        // Draw bounds to see where the control is.
        {
            use graphics::Rectangle;

            let bounds = [
                    self.bounds[0] as f64,
                    self.bounds[1] as f64,
                    self.bounds[2] as f64,
                    self.bounds[3] as f64
                ];
            Rectangle::new_border([0.0, 0.0, 1.0, 1.0], 0.5)
                .draw(bounds, &c.draw_state, c.transform, g);
        }

        // Draw a sequence of squares for each frame.
        {
            use graphics::Rectangle;

            let frame_bounds = |i: u32, lift: f64| [
                self.bounds[0] as f64 + left_to_frame
                    + i as f64 * (frame_width + frame_offset_x)
                    - slide_offset,
                self.bounds[1] as f64 + top_to_frame - lift,
                frame_width,
                frame_height
            ];

            let rect = Rectangle::new_border(blue, 0.5);
            for i in 0..end_frame - self.start_frame {
                // Don't draw the hover frame.
                if Some(i) == self.hover_frame { continue; }

                let bounds = frame_bounds(i, 0.0);
                rect.draw(bounds, &c.draw_state, c.transform, g);
            }

            if let Some(i) = self.hover_frame {
                let bounds = frame_bounds(i, lift_hover_frame);
                rect.draw(bounds, &c.draw_state, c.transform, g);
            }
        }

        // Draw navigate to start or end buttons.
        {
            use graphics::Line;
            use graphics::math::*;

            let line = Line::new([0.0, 0.0, 1.0, 1.0], 0.5);

            let at_beginning: bool = self.start_frame == 0;
            drawutils::draw_goto_end(
                at_beginning,
                [
                    self.bounds[0] as f64 + left_to_goto_start + frame_width,
                    self.bounds[1] as f64 + top_to_frame
                ],
                [
                    -frame_width * 0.5,
                    frame_height
                ],
                &Line::new(if self.hover_goto_start { red } else { blue }, 0.5),
                c, g
            );

            let at_end: bool = end_frame >= self.frames;
            drawutils::draw_goto_end(
                at_end,
                [
                    self.bounds[0] as f64 + self.bounds[2] as f64
                        - right_to_goto_end - frame_width,
                    self.bounds[1] as f64 + top_to_frame
                ],
                [
                    frame_width * 0.5,
                    frame_height
                ],
                &Line::new(if self.hover_goto_end { red } else { blue }, 0.5),
                c, g
            );
        }
    }

    pub fn draw_drag<G: Graphics>(&self, c: &Context, g: &mut G) {

    }
}
<commit_msg>Refactor `frame_width` and `frame_height` into `frame_size`<commit_after>extern crate graphics;
extern crate input;

use graphics::{ Context, Graphics };
use input::{ GenericEvent };

mod drawutils;

pub struct Timeline {
    pub frames: u32,
    pub current_frame: u32,
    pub hover_frame: Option<u32>,
    pub start_frame: u32,
    pub bounds: [u32; 4],
    pub settings: TimelineSettings,
    pub hover_goto_start: bool,
    pub hover_goto_end: bool,
}

pub struct TimelineSettings {
    pub left_to_frame: f64,
    pub right_to_frame: f64,
    pub top_to_frame: f64,
    pub frame_size: [f64; 2],
    pub frame_offset_x: f64,
    pub left_to_goto_start: f64,
    pub right_to_goto_end: f64,
    pub lift_hover_frame: f64,
}

pub struct ComputedTimelineSettings {
    pub width_for_frames: f64,
    pub max_visible_frames: u32,
    pub end_frame: u32,
}

impl TimelineSettings {
    pub fn new() -> TimelineSettings {
        TimelineSettings {
            left_to_frame: 20.0,
            right_to_frame: 20.0,
            top_to_frame: 15.0,
            frame_size: [10.0, 10.0],
            frame_offset_x: 5.0,
            left_to_goto_start: 5.0,
            right_to_goto_end: 5.0,
            lift_hover_frame: 10.0,
        }
    }
}

impl ComputedTimelineSettings {
    pub fn new(timeline: &Timeline, settings: &TimelineSettings)
        -> ComputedTimelineSettings
    {
        use std::cmp::min;

        let width_for_frames = timeline.bounds[2] as f64
            - settings.left_to_frame - settings.right_to_frame;
        let max_visible_frames: u32 =
            if width_for_frames < settings.frame_size[0] {
                0
            } else {
                1
                + (
                    (width_for_frames - settings.frame_size[0])
                    / (settings.frame_size[0] + settings.frame_offset_x)
                ) as u32
            };
        let end_frame = min(
            timeline.frames,
            timeline.start_frame + max_visible_frames
        );

        ComputedTimelineSettings {
            width_for_frames: width_for_frames,
            max_visible_frames: max_visible_frames,
            end_frame: end_frame
        }
    }
}

impl Timeline {
    pub fn new_frames_bounds(frames: u32, bounds: [u32; 4]) -> Timeline {
        Timeline {
            frames: frames,
            current_frame: 0,
            hover_frame: None,
            start_frame: 0,
            bounds: bounds,
            settings: TimelineSettings::new(),
            hover_goto_start: false,
            hover_goto_end: false,
        }
    }

    pub fn event<E: GenericEvent>(&mut self, e: &E) {
        use input::{ MouseCursorEvent, PressEvent };

        if let Some(pos) = e.mouse_cursor_args() {
            // Detect hover frame.
            {
                let computed_settings = ComputedTimelineSettings::new(self,
                    &self.settings);

                let left_to_frame: f64 = self.settings.left_to_frame;
                let frame_width: f64 = self.settings.frame_size[0];
                let frame_offset_x: f64 = self.settings.frame_offset_x;

                let end_frame: u32 = computed_settings.end_frame;

                let (x, y) = (pos[0], pos[1]);

                let left = self.bounds[0] as f64 + left_to_frame;
                let right = left + end_frame as f64 * (frame_width + frame_offset_x);
                let top = self.bounds[1] as f64;
                let bottom = top + self.bounds[3] as f64;

                if x < left || x > right
                || y < top || y > bottom {
                    self.hover_frame = None;
                } else {
                    let i: u32 = ((x - left) / (frame_width + frame_offset_x)) as u32;
                    self.hover_frame = Some(i);
                }
            }

            // Detect hover over goto start and goto end buttons.
            {
                let left_to_goto_start = self.settings.left_to_goto_start;
                let right_to_goto_end = self.settings.right_to_goto_end;
                let top_to_frame = self.settings.top_to_frame;
                let frame_width = self.settings.frame_size[0];
                let frame_height = self.settings.frame_size[1];

                let outside = |bounds: [f64; 4]| {
                    let (x, y) = (pos[0], pos[1]);
                    (x < bounds[0] || y < bounds[1]
                    || x > bounds[0] + bounds[2] || y > bounds[1] + bounds[3])
                };

                self.hover_goto_start = !outside([
                    self.bounds[0] as f64 + left_to_goto_start,
                    self.bounds[1] as f64 + top_to_frame,
                    frame_width,
                    frame_height
                ]);
                self.hover_goto_end = !outside([
                    self.bounds[0] as f64 + self.bounds[2] as f64
                        - right_to_goto_end - frame_width,
                    self.bounds[1] as f64 + top_to_frame,
                    frame_width,
                    frame_height
                ]);
            }
        }

        if let Some(button) = e.press_args() {
            use input::{ Button, MouseButton };

            if button == Button::Mouse(MouseButton::Left) {
                if self.hover_goto_start {
                    println!("TEST goto start");
                } else if self.hover_goto_end {
                    println!("TEST goto end");
                }
            }
        }
    }

    pub fn draw_timeline<G: Graphics>(&self, c: &Context, g: &mut G) {
        use std::cmp::min;

        let left_to_frame: f64 = self.settings.left_to_frame;
        let right_to_frame: f64 = self.settings.right_to_frame;
        let top_to_frame: f64 = self.settings.top_to_frame;
        let frame_width: f64 = self.settings.frame_size[0];
        let frame_height: f64 = self.settings.frame_size[1];
        let frame_offset_x: f64 = self.settings.frame_offset_x;
        let left_to_goto_start: f64 = self.settings.left_to_goto_start;
        let right_to_goto_end: f64 = self.settings.right_to_goto_end;
        let lift_hover_frame: f64 = self.settings.lift_hover_frame;

        let computed_settings = ComputedTimelineSettings::new(self, &self.settings);

        let slide_offset: f64 = 0.0;

        let width_for_frames = computed_settings.width_for_frames;
        let max_visible_frames: u32 = computed_settings.max_visible_frames;
        let end_frame = computed_settings.end_frame;

        let blue = [0.0, 0.0, 1.0, 1.0];
        let red = [1.0, 0.0, 0.0, 1.0];

        // Draw bounds to see where the control is.
        {
            use graphics::Rectangle;

            let bounds = [
                    self.bounds[0] as f64,
                    self.bounds[1] as f64,
                    self.bounds[2] as f64,
                    self.bounds[3] as f64
                ];
            Rectangle::new_border([0.0, 0.0, 1.0, 1.0], 0.5)
                .draw(bounds, &c.draw_state, c.transform, g);
        }

        // Draw a sequence of squares for each frame.
        {
            use graphics::Rectangle;

            let frame_bounds = |i: u32, lift: f64| [
                self.bounds[0] as f64 + left_to_frame
                    + i as f64 * (frame_width + frame_offset_x)
                    - slide_offset,
                self.bounds[1] as f64 + top_to_frame - lift,
                frame_width,
                frame_height
            ];

            let rect = Rectangle::new_border(blue, 0.5);
            for i in 0..end_frame - self.start_frame {
                // Don't draw the hover frame.
                if Some(i) == self.hover_frame { continue; }

                let bounds = frame_bounds(i, 0.0);
                rect.draw(bounds, &c.draw_state, c.transform, g);
            }

            if let Some(i) = self.hover_frame {
                let bounds = frame_bounds(i, lift_hover_frame);
                rect.draw(bounds, &c.draw_state, c.transform, g);
            }
        }

        // Draw navigate to start or end buttons.
        {
            use graphics::Line;
            use graphics::math::*;

            let line = Line::new([0.0, 0.0, 1.0, 1.0], 0.5);

            let at_beginning: bool = self.start_frame == 0;
            drawutils::draw_goto_end(
                at_beginning,
                [
                    self.bounds[0] as f64 + left_to_goto_start + frame_width,
                    self.bounds[1] as f64 + top_to_frame
                ],
                [
                    -frame_width * 0.5,
                    frame_height
                ],
                &Line::new(if self.hover_goto_start { red } else { blue }, 0.5),
                c, g
            );

            let at_end: bool = end_frame >= self.frames;
            drawutils::draw_goto_end(
                at_end,
                [
                    self.bounds[0] as f64 + self.bounds[2] as f64
                        - right_to_goto_end - frame_width,
                    self.bounds[1] as f64 + top_to_frame
                ],
                [
                    frame_width * 0.5,
                    frame_height
                ],
                &Line::new(if self.hover_goto_end { red } else { blue }, 0.5),
                c, g
            );
        }
    }

    pub fn draw_drag<G: Graphics>(&self, c: &Context, g: &mut G) {

    }
}
<|endoftext|>


<commit_before>// Copyright 2017 tokio-jsonrpc Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! A JSON RPC protocol for the [tokio](https://tokio.rs) framework.
//!
//! This implements the handling of the
//! [JSON RPC 2.0](http://www.jsonrpc.org/specification) specification. The low-level parts are in
//! the [`message`](message/index.html) and the [`codec`](codec/index.html) modules. The first
//! draft of the higher-lever API is in the [`endpoint`](endpoint/index.html) module.
//!
//! # Examples
//!
//! A skeleton of reading messages from the other side, mapping them to answers and sending them
//! back.
//!
//! ```rust
//! # extern crate tokio_core;
//! # extern crate tokio_jsonrpc;
//! # extern crate futures;
//! #
//! # use tokio_core::reactor::Core;
//! # use tokio_core::net::TcpListener;
//! # use tokio_core::io::Io;
//! # use tokio_jsonrpc::LineCodec;
//! # use futures::{Stream, Sink, Future};
//! #
//! # fn main() {
//! let mut core = Core::new().unwrap();
//! let handle = core.handle();
//!
//! let listener = TcpListener::bind(&"127.0.0.1:2345".parse().unwrap(), &handle).unwrap();
//! let connections = listener.incoming();
//! let service = connections.for_each(|(stream, _)| {
//!     let messages = stream.framed(LineCodec::new());
//!     let (write, read) = messages.split();
//!     let answers = read.filter_map(|message| {
//!         match message {
//!             _ => unimplemented!(),
//!         }
//!     });
//!     handle.spawn(write.send_all(answers).map(|_| ()).map_err(|_| ()));
//!     Ok(())
//! });
//! # }
//! ```
//!
//! Provide a server that greets through an RPC.
//!
//! ```rust,no_run
//! # extern crate tokio_core;
//! # extern crate tokio_jsonrpc;
//! # extern crate futures;
//! # extern crate serde_json;
//! #
//! # use tokio_core::reactor::Core;
//! # use tokio_core::net::TcpListener;
//! # use tokio_core::io::Io;
//! # use tokio_jsonrpc::{LineCodec, Server, ServerCtl, RpcError, Endpoint};
//! # use futures::{Stream};
//! # use serde_json::Value;
//! #
//! # fn main() {
//! let mut core = Core::new().unwrap();
//! let handle = core.handle();
//!
//! let listener = TcpListener::bind(&"127.0.0.1:2346".parse().unwrap(), &handle).unwrap();
//!
//! struct UselessServer;
//!
//! impl Server for UselessServer {
//!     type Success = String;
//!     type RpcCallResult = Result<String, RpcError>;
//!     type NotificationResult = Result<(), ()>;
//!     fn rpc(&self,
//!            ctl: &ServerCtl,
//!            method: &str,
//!            _params: &Option<Value>)
//!         -> Option<Self::RpcCallResult> {
//!         match method {
//!             // Accept a hello message and finish the greeting
//!             "hello" => Some(Ok("world".to_owned())),
//!             // When the other side says bye, terminate the connection
//!             "bye" => {
//!                 ctl.terminate();
//!                 Some(Ok("bye".to_owned()))
//!             },
//!             _ => None
//!         }
//!     }
//! }
//!
//! let connections = listener.incoming().for_each(|(stream, _)| {
//!     // Greet every new connection
//!     Endpoint::new(stream.framed(LineCodec::new()), UselessServer).start(&handle)
//!         .0
//!         .notify("hello".to_owned(), None);
//!     Ok(())
//! });
//!
//! core.run(connections).unwrap();
//! # }
//! ```

extern crate serde;
// We use the json! macro only in the tests
#[cfg_attr(test, macro_use)]
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate uuid;
extern crate tokio_core;
extern crate futures;
extern crate futures_mpsc;
extern crate relay;

pub mod codec;
pub mod endpoint;
pub mod message;
pub mod server;

pub use codec::{Boundary as BoundaryCodec, Line as LineCodec};
pub use endpoint::{Client, Endpoint, ServerCtl};
pub use message::{Message, Parsed, RpcError};
pub use server::Server;
<commit_msg>Fix an example: the future needs to be used<commit_after>// Copyright 2017 tokio-jsonrpc Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! A JSON RPC protocol for the [tokio](https://tokio.rs) framework.
//!
//! This implements the handling of the
//! [JSON RPC 2.0](http://www.jsonrpc.org/specification) specification. The low-level parts are in
//! the [`message`](message/index.html) and the [`codec`](codec/index.html) modules. The first
//! draft of the higher-lever API is in the [`endpoint`](endpoint/index.html) module.
//!
//! # Examples
//!
//! A skeleton of reading messages from the other side, mapping them to answers and sending them
//! back.
//!
//! ```rust
//! # extern crate tokio_core;
//! # extern crate tokio_jsonrpc;
//! # extern crate futures;
//! #
//! # use tokio_core::reactor::Core;
//! # use tokio_core::net::TcpListener;
//! # use tokio_core::io::Io;
//! # use tokio_jsonrpc::LineCodec;
//! # use futures::{Stream, Sink, Future};
//! #
//! # fn main() {
//! let mut core = Core::new().unwrap();
//! let handle = core.handle();
//!
//! let listener = TcpListener::bind(&"127.0.0.1:2345".parse().unwrap(), &handle).unwrap();
//! let connections = listener.incoming();
//! let service = connections.for_each(|(stream, _)| {
//!     let messages = stream.framed(LineCodec::new());
//!     let (write, read) = messages.split();
//!     let answers = read.filter_map(|message| {
//!         match message {
//!             _ => unimplemented!(),
//!         }
//!     });
//!     handle.spawn(write.send_all(answers).map(|_| ()).map_err(|_| ()));
//!     Ok(())
//! });
//! # }
//! ```
//!
//! Provide a server that greets through an RPC.
//!
//! ```rust,no_run
//! # extern crate tokio_core;
//! # extern crate tokio_jsonrpc;
//! # extern crate futures;
//! # extern crate serde_json;
//! #
//! # use tokio_core::reactor::Core;
//! # use tokio_core::net::TcpListener;
//! # use tokio_core::io::Io;
//! # use tokio_jsonrpc::{LineCodec, Server, ServerCtl, RpcError, Endpoint};
//! # use futures::{Future, Stream};
//! # use serde_json::Value;
//! #
//! # fn main() {
//! let mut core = Core::new().unwrap();
//! let handle = core.handle();
//!
//! let listener = TcpListener::bind(&"127.0.0.1:2346".parse().unwrap(), &handle).unwrap();
//!
//! struct UselessServer;
//!
//! impl Server for UselessServer {
//!     type Success = String;
//!     type RpcCallResult = Result<String, RpcError>;
//!     type NotificationResult = Result<(), ()>;
//!     fn rpc(&self,
//!            ctl: &ServerCtl,
//!            method: &str,
//!            _params: &Option<Value>)
//!         -> Option<Self::RpcCallResult> {
//!         match method {
//!             // Accept a hello message and finish the greeting
//!             "hello" => Some(Ok("world".to_owned())),
//!             // When the other side says bye, terminate the connection
//!             "bye" => {
//!                 ctl.terminate();
//!                 Some(Ok("bye".to_owned()))
//!             },
//!             _ => None
//!         }
//!     }
//! }
//!
//! let connections = listener.incoming().for_each(|(stream, _)| {
//!     // Greet every new connection
//!     let (client, _) = Endpoint::new(stream.framed(LineCodec::new()), UselessServer)
//!         .start(&handle);
//!     let notified = client.notify("hello".to_owned(), None)
//!         .map(|_| ())
//!         .map_err(|_| ());
//!     handle.spawn(notified);
//!     Ok(())
//! });
//!
//! core.run(connections).unwrap();
//! # }
//! ```

extern crate serde;
// We use the json! macro only in the tests
#[cfg_attr(test, macro_use)]
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate uuid;
extern crate tokio_core;
extern crate futures;
extern crate futures_mpsc;
extern crate relay;

pub mod codec;
pub mod endpoint;
pub mod message;
pub mod server;

pub use codec::{Boundary as BoundaryCodec, Line as LineCodec};
pub use endpoint::{Client, Endpoint, ServerCtl};
pub use message::{Message, Parsed, RpcError};
pub use server::Server;
<|endoftext|>


<commit_before>pub use arbitrary;

extern "C" {
    #![allow(improper_ctypes)] // we do not actually cross the FFI bound here

    fn rust_fuzzer_test_input(input: &[u8]);
}

#[export_name = "LLVMFuzzerTestOneInput"]
pub fn test_input_wrap(data: *const u8, size: usize) -> i32 {
    let test_input = ::std::panic::catch_unwind(|| unsafe {
        let data_slice = ::std::slice::from_raw_parts(data, size);
        rust_fuzzer_test_input(data_slice);
    });
    if test_input.err().is_some() {
        // hopefully the custom panic hook will be called before and abort the
        // process before the stack frames are unwinded.
        ::std::process::abort();
    }
    0
}

#[export_name = "LLVMFuzzerInitialize"]
pub fn initialize(_argc: *const isize, _argv: *const *const *const u8) -> isize {
    // Registers a panic hook that aborts the process before unwinding.
    // It is useful to abort before unwinding so that the fuzzer will then be
    // able to analyse the process stack frames to tell different bugs appart.
    //
    // HACK / FIXME: it would be better to use `-C panic=abort` but it's currently
    // impossible to build code using compiler plugins with this flag.
    // We will be able to remove this code when
    // https://github.com/rust-lang/cargo/issues/5423 is fixed.
    ::std::panic::set_hook(Box::new(|_| {
        ::std::process::abort();
    }));
    0
}

#[macro_export]
macro_rules! fuzz_target {
    (|$bytes:ident| $body:block) => {
        #[no_mangle]
        pub extern "C" fn rust_fuzzer_test_input($bytes: &[u8]) {
            $body
        }
    };
    (|$data:ident: &[u8]| $body:block) => {
        fuzz_target!(|$data| $body);
    };
    (|$data:ident: $dty: ty| $body:block) => {
        #[no_mangle]
        pub extern "C" fn rust_fuzzer_test_input(bytes: &[u8]) {
            use libfuzzer_sys::arbitrary::{Arbitrary, RingBuffer};

            let mut buf = match RingBuffer::new(bytes, bytes.len()) {
                Ok(b) => b,
                Err(_) => return,
            };

            let $data: $dty = match Arbitrary::arbitrary(&mut buf) {
                Ok(d) => d,
                Err(_) => return,
            };

            $body
        }
    };
}
<commit_msg>Add docs and little clean ups<commit_after>//! Bindings to [libFuzzer](http://llvm.org/docs/LibFuzzer.html): a runtime for
//! coverage-guided fuzzing.
//!
//! See [the `cargo-fuzz`
//! guide](https://rust-fuzz.github.io/book/cargo-fuzz.html) for a usage
//! tutorial.
//!
//! The main export of this crate is [the `fuzz_target!`
//! macro](./macro.fuzz_target.html), which allows you to define targets for
//! libFuzzer to exercise.

#![deny(missing_docs, missing_debug_implementations)]

pub use arbitrary;

extern "C" {
    // We do not actually cross the FFI bound here.
    #[allow(improper_ctypes)]
    fn rust_fuzzer_test_input(input: &[u8]);
}

#[doc(hidden)]
#[export_name = "LLVMFuzzerTestOneInput"]
pub fn test_input_wrap(data: *const u8, size: usize) -> i32 {
    let test_input = ::std::panic::catch_unwind(|| unsafe {
        let data_slice = ::std::slice::from_raw_parts(data, size);
        rust_fuzzer_test_input(data_slice);
    });
    if test_input.err().is_some() {
        // hopefully the custom panic hook will be called before and abort the
        // process before the stack frames are unwinded.
        ::std::process::abort();
    }
    0
}

#[doc(hidden)]
#[export_name = "LLVMFuzzerInitialize"]
pub fn initialize(_argc: *const isize, _argv: *const *const *const u8) -> isize {
    // Registers a panic hook that aborts the process before unwinding.
    // It is useful to abort before unwinding so that the fuzzer will then be
    // able to analyse the process stack frames to tell different bugs appart.
    //
    // HACK / FIXME: it would be better to use `-C panic=abort` but it's currently
    // impossible to build code using compiler plugins with this flag.
    // We will be able to remove this code when
    // https://github.com/rust-lang/cargo/issues/5423 is fixed.
    ::std::panic::set_hook(Box::new(|_| {
        ::std::process::abort();
    }));
    0
}

/// Define a fuzz target.
///
/// ## Example
///
/// This example takes a `&[u8]` slice and attempts to parse it. The parsing
/// might fail and return an `Err`, but it shouldn't ever panic or segfault.
///
/// ```no_run
/// #![no_main]
///
/// use libfuzzer_sys::fuzz_target;
///
/// // Note: `|input|` is short for `|input: &[u8]|`.
/// fuzz_target!(|input| {
///     let _result: Result<_, _> = my_crate::parse(input);
/// });
/// # mod my_crate { pub fn parse(_: &[u8]) -> Result<(), ()> { unimplemented!() } }
/// ```
///
/// ## Arbitrary Input Types
///
/// The input is a `&[u8]` slice by default, but you can take arbitrary input
/// types, as long as the type implements [the `arbitrary` crate's `Arbitrary`
/// trait](https://docs.rs/arbitrary/*/arbitrary/trait.Arbitrary.html) (which is
/// also re-exported as `libfuzzer_sys::arbitrary::Arbitrary` for convenience).
///
/// For example, if you wanted to take an arbitrary RGB color, you could do the
/// following:
///
/// ```no_run
/// #![no_main]
///
/// use libfuzzer_sys::{arbitrary::{Arbitrary, Unstructured}, fuzz_target};
///
/// #[derive(Debug)]
/// pub struct Rgb {
///     r: u8,
///     g: u8,
///     b: u8,
/// }
///
/// impl Arbitrary for Rgb {
///     fn arbitrary<U>(raw: &mut U) -> Result<Self, U::Error>
///     where
///         U: Unstructured + ?Sized
///     {
///         let mut buf = [0; 3];
///         raw.fill_buffer(&mut buf)?;
///         let r = buf[0];
///         let g = buf[1];
///         let b = buf[2];
///         Ok(Rgb { r, g, b })
///     }
/// }
///
/// // Write a fuzz target that works with RGB colors instead of raw bytes.
/// fuzz_target!(|color: Rgb| {
///     my_crate::convert_color(color);
/// });
/// # mod my_crate { fn convert_color(_: super::Rgb) {} }
#[macro_export]
macro_rules! fuzz_target {
    (|$bytes:ident| $body:block) => {
        #[no_mangle]
        pub extern "C" fn rust_fuzzer_test_input($bytes: &[u8]) {
            $body
        }
    };

    (|$data:ident: &[u8]| $body:block) => {
        fuzz_target!(|$data| $body);
    };

    (|$data:ident: $dty: ty| $body:block) => {
        #[no_mangle]
        pub extern "C" fn rust_fuzzer_test_input(bytes: &[u8]) {
            use libfuzzer_sys::arbitrary::{Arbitrary, RingBuffer};

            let mut buf = match RingBuffer::new(bytes, bytes.len()) {
                Ok(b) => b,
                Err(_) => return,
            };

            let $data: $dty = match Arbitrary::arbitrary(&mut buf) {
                Ok(d) => d,
                Err(_) => return,
            };

            $body
        }
    };
}
<|endoftext|>


<commit_before>extern crate num;
extern crate rand;
extern crate rutorch;

use rutorch::*;
use std::ops::{Index, IndexMut};
use rand::Rng;
//use std::convert::From;
use num::Num;
use std::cmp::max;

struct BaseIter<'a, T, P: 'a + Index<isize>> {
	idx: usize,
	parent: &'a P,
	t: std::marker::PhantomData<T>,
}

impl <'a, T, P: Index<isize> >BaseIter<'a, T, P> {
	fn new(parent: &'a P) -> Self {
		BaseIter { idx: 0, parent: parent, t: std::default::Default::default()}
	}
}

trait Storage {
	fn new() -> Self;
	fn sized(len: isize) -> Self;
}

struct FloatStorage {
	t: *mut THFloatStorage,
}

impl Storage for FloatStorage {
	fn new() -> Self {
		unsafe { FloatStorage  {t : THFloatStorage_new()} }
	}
	fn sized(size: isize) ->Self {
		unsafe { FloatStorage  {t : THFloatStorage_newWithSize(size)} }
	}
}

impl FloatStorage {
	fn iter(&mut self) -> BaseIter<f32, FloatStorage> {
		BaseIter::new(self)
	}
}

impl Index<isize> for FloatStorage {
	type Output = f32;

	fn index(&self, idx: isize) -> &f32 {
		unsafe {&*(*self.t).data.offset(idx)}
	}
}

impl IndexMut<isize> for FloatStorage {
	fn index_mut(&mut self, idx: isize) -> &mut f32 {
		unsafe {&mut *(*self.t).data.offset(idx)}
	}
}

impl <'a, f32, T>Iterator for BaseIter<'a, f32, T>
	where T: std::ops::Index<isize, Output=f32> {
	type Item = f32;

	fn next(&mut self) -> Option<f32> {
		// XXX check length ---
		let ret = *(*self.parent).index(self.idx as isize);
		self.idx += 1;
		Some(ret)
	}
}

//fn from(args: &ArgsArray<T>) -> Self;

trait Tensor<'a> : Index<&'a [isize]> {
	fn new() -> Self;
	fn sized(size: &'a [isize]) -> Self;
	fn randn(dims: &'a [isize]) -> Self;
}

struct FloatTensor {
	t: *mut THFloatTensor,
	storage: FloatStorage,
	dims: Vec<isize>,
}

impl <'a>Tensor<'a> for FloatTensor {
	fn new() -> Self {
		unsafe { FloatTensor { t : THFloatTensor_new(), storage: FloatStorage::new(), dims: Vec::new()  }}
	}
	fn sized(dims: &'a [isize]) -> Self {
		let size = dims.iter().product();
		let storage = FloatStorage::sized(size);
		let strides = vec![1; dims.len()];
		let mut t = THFloatTensor { size : dims.clone().as_ptr() as *mut ::std::os::raw::c_long,
			stride: strides.as_ptr() as *mut ::std::os::raw::c_long,
			nDimension : dims.len() as i32, storage: storage.t, storageOffset: 0, refcount: 1,
			flag: TH_TENSOR_REFCOUNTED as i8};
		FloatTensor {t : &mut t, storage: storage, dims: Vec::from(dims)}
	}
	fn randn(dims: &'a [isize]) -> Self {
		/* XXX */
		let t = Tensor::sized(dims);
//		x = random::<f32>();
		t
	}
}

impl <'a> Index<&'a [isize]> for FloatTensor {
	type Output = f32;

	fn index(&self, idx: &'a [isize]) -> &f32 {
		let mut index : isize = 0;
		let lastidx = max(0, idx.len() as isize - 1) as usize;
		if idx.len() != self.dims.len() { panic!("bad dimlen")}
		for i in 0..lastidx {
			if idx[i] >= self.dims[i] { panic!("bad dimlen")}
			index += idx[i] * self.dims[i]
		}
		if idx[lastidx] >= self.dims[lastidx] { panic!("bad dimlen")}
		index += idx[lastidx];
		&self.storage[index]
	}
}

impl <'a> IndexMut<&'a [isize]> for FloatTensor {
	fn index_mut(&mut self, idx: &'a [isize]) -> &mut f32 {
		let mut index : isize = 0;
		let lastidx = max(0, idx.len() as isize - 1) as usize;
		if idx.len() != self.dims.len() { panic!("bad dimlen")}
		for i in 0..lastidx {
			if idx[i] >= self.dims[i] { panic!("bad dimlen")}
			index += idx[i] * self.dims[i]
		}
		if idx[lastidx] >= self.dims[lastidx] { panic!("bad dimlen")}
		index += idx[lastidx];
		&mut self.storage[index]
	}
}

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

    }
}
<commit_msg>mark output type as Copy<commit_after>extern crate num;
extern crate rand;
extern crate rutorch;

use rutorch::*;
use std::ops::{Index, IndexMut};
use rand::Rng;
//use std::convert::From;
use num::Num;
use std::cmp::max;

struct BaseIter<'a, T, P: 'a + Index<isize>> {
	idx: usize,
	parent: &'a P,
	t: std::marker::PhantomData<T>,
}

impl <'a, T, P: Index<isize> >BaseIter<'a, T, P> {
	fn new(parent: &'a P) -> Self {
		BaseIter { idx: 0, parent: parent, t: std::default::Default::default()}
	}
}

trait Storage {
	fn new() -> Self;
	fn sized(len: isize) -> Self;
}

struct FloatStorage {
	t: *mut THFloatStorage,
}

impl Storage for FloatStorage {
	fn new() -> Self {
		unsafe { FloatStorage  {t : THFloatStorage_new()} }
	}
	fn sized(size: isize) ->Self {
		unsafe { FloatStorage  {t : THFloatStorage_newWithSize(size)} }
	}
}

impl FloatStorage {
	fn iter(&mut self) -> BaseIter<f32, FloatStorage> {
		BaseIter::new(self)
	}
}

impl Index<isize> for FloatStorage {
	type Output = f32;

	fn index(&self, idx: isize) -> &f32 {
		unsafe {&*(*self.t).data.offset(idx)}
	}
}

impl IndexMut<isize> for FloatStorage {
	fn index_mut(&mut self, idx: isize) -> &mut f32 {
		unsafe {&mut *(*self.t).data.offset(idx)}
	}
}

impl <'a, O: Copy, T>Iterator for BaseIter<'a, O, T>
	where T: std::ops::Index<isize, Output=O> {
	type Item = O;

	fn next(&mut self) -> Option<O> {
		// XXX check length ---
		let ret = *(*self.parent).index(self.idx as isize);
		self.idx += 1;
		Some(ret)
	}
}

//fn from(args: &ArgsArray<T>) -> Self;

trait Tensor<'a> : Index<&'a [isize]> {
	fn new() -> Self;
	fn sized(size: &'a [isize]) -> Self;
	fn randn(dims: &'a [isize]) -> Self;
}

struct FloatTensor {
	t: *mut THFloatTensor,
	storage: FloatStorage,
	dims: Vec<isize>,
}

impl <'a>Tensor<'a> for FloatTensor {
	fn new() -> Self {
		unsafe { FloatTensor { t : THFloatTensor_new(), storage: FloatStorage::new(), dims: Vec::new()  }}
	}
	fn sized(dims: &'a [isize]) -> Self {
		let size = dims.iter().product();
		let storage = FloatStorage::sized(size);
		let strides = vec![1; dims.len()];
		let mut t = THFloatTensor { size : dims.clone().as_ptr() as *mut ::std::os::raw::c_long,
			stride: strides.as_ptr() as *mut ::std::os::raw::c_long,
			nDimension : dims.len() as i32, storage: storage.t, storageOffset: 0, refcount: 1,
			flag: TH_TENSOR_REFCOUNTED as i8};
		FloatTensor {t : &mut t, storage: storage, dims: Vec::from(dims)}
	}
	fn randn(dims: &'a [isize]) -> Self {
		/* XXX */
		let t = Tensor::sized(dims);
//		x = random::<f32>();
		t
	}
}

impl <'a> Index<&'a [isize]> for FloatTensor {
	type Output = f32;

	fn index(&self, idx: &'a [isize]) -> &f32 {
		let mut index : isize = 0;
		let lastidx = max(0, idx.len() as isize - 1) as usize;
		if idx.len() != self.dims.len() { panic!("bad dimlen")}
		for i in 0..lastidx {
			if idx[i] >= self.dims[i] { panic!("bad dimlen")}
			index += idx[i] * self.dims[i]
		}
		if idx[lastidx] >= self.dims[lastidx] { panic!("bad dimlen")}
		index += idx[lastidx];
		&self.storage[index]
	}
}

impl <'a> IndexMut<&'a [isize]> for FloatTensor {
	fn index_mut(&mut self, idx: &'a [isize]) -> &mut f32 {
		let mut index : isize = 0;
		let lastidx = max(0, idx.len() as isize - 1) as usize;
		if idx.len() != self.dims.len() { panic!("bad dimlen")}
		for i in 0..lastidx {
			if idx[i] >= self.dims[i] { panic!("bad dimlen")}
			index += idx[i] * self.dims[i]
		}
		if idx[lastidx] >= self.dims[lastidx] { panic!("bad dimlen")}
		index += idx[lastidx];
		&mut self.storage[index]
	}
}

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

    }
}
<|endoftext|>


<commit_before>/*!
# nalgebra

[![Build Status](https://travis-ci.org/sebcrozet/nalgebra.png?branch=master)](https://travis-ci.org/sebcrozet/nalgebra)

**nalgebra** is a linear algebra library written for Rust targeting:

* general-purpose linear algebra (still misses a lot of features…).
* real time computer graphics.
* real time computer physics.

An on-line version of this documentation is available [here](http://www.rust-ci.org/sebcrozet/nalgebra/doc/nalgebra/index.html).

## Using **nalgebra**
All the functionalities of **nalgebra** are grouped in one place: the `na` module.
This module re-exports everything and includes free functions for all traits methods doing
out-of-place modifications.

* You can import the whole prelude using:

```
use nalgebra::na::*;
```

The preferred way to use **nalgebra** is to import types and traits explicitly, and call
free-functions using the `na::` prefix:

```.rust
extern mod nalgebra;
use nalgebra::na::{Vec3, Rot3, Rotation};
use nalgebra::na;

fn main() {
    let     a = Vec3::new(1.0f64, 1.0, 1.0);
    let mut b = Rot3::new(na::zero());

    b.append_rotation(&a);

    assert!(na::approx_eq(&na::rotation(&b), &a));
}
```

## Features
**nalgebra** is meant to be a general-purpose linear algebra library (but is very far from that…),
and keeps an optimized set of tools for computational graphics and physics. Those features include:

* Vectors with static sizes: `Vec0`, `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`.
* Square matrices with static sizes: `Mat1`, `Mat2`, `Mat3`, `Mat4`, `Mat5`, `Mat6 `.
* Rotation matrices: `Rot2`, `Rot3`, `Rot4`.
* Isometries: `Iso2`, `Iso3`, `Iso4`.
* Dynamically sized vector: `DVec`.
* Dynamically sized (square or rectangular) matrix: `DMat`.
* A few methods for data analysis: `Cov`, `Mean`.
* Almost one trait per functionality: useful for generic programming.
* Operator overloading using the double trait dispatch
  [trick](http://smallcultfollowing.com/babysteps/blog/2012/10/04/refining-traits-slash-impls/).
  For example, the following works:

```rust
extern mod nalgebra;
use nalgebra::na::{Vec3, Mat3};
use nalgebra::na;

fn main() {
    let v: Vec3<f64> = na::zero();
    let m: Mat3<f64> = na::one();

    let _ = m * v;   // matrix-vector multiplication.
    let _ = v * m;   // vector-matrix multiplication.
    let _ = m * m;   // matrix-matrix multiplication.
    let _ = v * 2.0; // vector-scalar multiplication.
}
```

## Compilation
You will need the last rust compiler from the master branch.
If you encounter problems, make sure you have the last version before creating an issue.

    git clone git://github.com/sebcrozet/nalgebra.git
    cd nalgebra
    make

You can build the documentation on the `doc` folder using:

```
make doc
```

## **nalgebra** in use
Here are some projects using **nalgebra**.
Feel free to add your project to this list if you happen to use **nalgebra**!

* [nphysics](https://github.com/sebcrozet/nphysics): a real-time physics engine.
* [ncollide](https://github.com/sebcrozet/ncollide): a collision detection library.
* [kiss3d](https://github.com/sebcrozet/kiss3d): a minimalistic graphics engine.
* [frog](https://github.com/natal/frog): a machine learning library.
*/

#[crate_id = "nalgebra#0.1"];
#[crate_type = "lib"];
#[deny(non_camel_case_types)];
#[deny(unnecessary_parens)];
#[deny(non_uppercase_statics)];
#[deny(unnecessary_qualification)];
#[deny(unused_result)];
#[warn(missing_doc)];
#[feature(macro_rules)];
#[doc(html_root_url = "http://www.rust-ci.org/sebcrozet/nalgebra/doc")];

extern mod std;
extern mod extra;

pub mod na;
mod structs;
mod traits;

// mod lower_triangular;
// mod chol;

#[cfg(test)]
mod tests {
    mod vec;
    mod mat;
}

#[cfg(test)]
mod bench {
    mod vec;
    mod mat;
}
<commit_msg>Update to the last Rust.<commit_after>/*!
# nalgebra

[![Build Status](https://travis-ci.org/sebcrozet/nalgebra.png?branch=master)](https://travis-ci.org/sebcrozet/nalgebra)

**nalgebra** is a linear algebra library written for Rust targeting:

* general-purpose linear algebra (still misses a lot of features…).
* real time computer graphics.
* real time computer physics.

An on-line version of this documentation is available [here](http://www.rust-ci.org/sebcrozet/nalgebra/doc/nalgebra/index.html).

## Using **nalgebra**
All the functionalities of **nalgebra** are grouped in one place: the `na` module.
This module re-exports everything and includes free functions for all traits methods doing
out-of-place modifications.

* You can import the whole prelude using:

```
use nalgebra::na::*;
```

The preferred way to use **nalgebra** is to import types and traits explicitly, and call
free-functions using the `na::` prefix:

```.rust
extern mod nalgebra;
use nalgebra::na::{Vec3, Rot3, Rotation};
use nalgebra::na;

fn main() {
    let     a = Vec3::new(1.0f64, 1.0, 1.0);
    let mut b = Rot3::new(na::zero());

    b.append_rotation(&a);

    assert!(na::approx_eq(&na::rotation(&b), &a));
}
```

## Features
**nalgebra** is meant to be a general-purpose linear algebra library (but is very far from that…),
and keeps an optimized set of tools for computational graphics and physics. Those features include:

* Vectors with static sizes: `Vec0`, `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`.
* Square matrices with static sizes: `Mat1`, `Mat2`, `Mat3`, `Mat4`, `Mat5`, `Mat6 `.
* Rotation matrices: `Rot2`, `Rot3`, `Rot4`.
* Isometries: `Iso2`, `Iso3`, `Iso4`.
* Dynamically sized vector: `DVec`.
* Dynamically sized (square or rectangular) matrix: `DMat`.
* A few methods for data analysis: `Cov`, `Mean`.
* Almost one trait per functionality: useful for generic programming.
* Operator overloading using the double trait dispatch
  [trick](http://smallcultfollowing.com/babysteps/blog/2012/10/04/refining-traits-slash-impls/).
  For example, the following works:

```rust
extern mod nalgebra;
use nalgebra::na::{Vec3, Mat3};
use nalgebra::na;

fn main() {
    let v: Vec3<f64> = na::zero();
    let m: Mat3<f64> = na::one();

    let _ = m * v;   // matrix-vector multiplication.
    let _ = v * m;   // vector-matrix multiplication.
    let _ = m * m;   // matrix-matrix multiplication.
    let _ = v * 2.0; // vector-scalar multiplication.
}
```

## Compilation
You will need the last rust compiler from the master branch.
If you encounter problems, make sure you have the last version before creating an issue.

    git clone git://github.com/sebcrozet/nalgebra.git
    cd nalgebra
    make

You can build the documentation on the `doc` folder using:

```
make doc
```

## **nalgebra** in use
Here are some projects using **nalgebra**.
Feel free to add your project to this list if you happen to use **nalgebra**!

* [nphysics](https://github.com/sebcrozet/nphysics): a real-time physics engine.
* [ncollide](https://github.com/sebcrozet/ncollide): a collision detection library.
* [kiss3d](https://github.com/sebcrozet/kiss3d): a minimalistic graphics engine.
* [frog](https://github.com/natal/frog): a machine learning library.
*/

#[crate_id = "nalgebra#0.1"];
#[crate_type = "lib"];
#[deny(non_camel_case_types)];
#[deny(unnecessary_parens)];
#[deny(non_uppercase_statics)];
#[deny(unnecessary_qualification)];
#[deny(unused_result)];
#[warn(missing_doc)];
#[feature(macro_rules)];
#[doc(html_root_url = "http://www.rust-ci.org/sebcrozet/nalgebra/doc")];

extern mod std;
extern mod extra;
extern mod serialize;

pub mod na;
mod structs;
mod traits;

// mod lower_triangular;
// mod chol;

#[cfg(test)]
mod tests {
    mod vec;
    mod mat;
}

#[cfg(test)]
mod bench {
    mod vec;
    mod mat;
}
<|endoftext|>