<commit_before>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{block::Block, common::Author, sync_info::SyncInfo};
use anyhow::{anyhow, ensure, format_err, Context, Result};
use diem_types::validator_verifier::ValidatorVerifier;
use serde::{Deserialize, Serialize};
use short_hex_str::AsShortHexStr;
use std::fmt;

/// ProposalMsg contains the required information for the proposer election protocol to make its
/// choice (typically depends on round and proposer info).
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct ProposalMsg {
    proposal: Block,
    sync_info: SyncInfo,
}

impl ProposalMsg {
    /// Creates a new proposal.
    pub fn new(proposal: Block, sync_info: SyncInfo) -> Self {
        Self {
            proposal,
            sync_info,
        }
    }

    pub fn epoch(&self) -> u64 {
        self.proposal.epoch()
    }

    /// Verifies that the ProposalMsg is well-formed.
    pub fn verify_well_formed(&self) -> Result<()> {
        ensure!(
            !self.proposal.is_nil_block(),
            "Proposal {} for a NIL block",
            self.proposal
        );
        self.proposal
            .verify_well_formed()
            .context("Fail to verify ProposalMsg's block")?;
        ensure!(
            self.proposal.round() > 0,
            "Proposal for {} has an incorrect round of 0",
            self.proposal,
        );
        ensure!(
            self.proposal.epoch() == self.sync_info.epoch(),
            "ProposalMsg has different epoch number from SyncInfo"
        );
        ensure!(
            self.proposal.parent_id()
                == self.sync_info.highest_quorum_cert().certified_block().id(),
            "Proposal HQC in SyncInfo certifies {}, but block parent id is {}",
            self.sync_info.highest_quorum_cert().certified_block().id(),
            self.proposal.parent_id(),
        );
        let previous_round = self
            .proposal
            .round()
            .checked_sub(1)
            .ok_or_else(|| anyhow!("proposal round overflowed!"))?;

        let highest_certified_round = std::cmp::max(
            self.proposal.quorum_cert().certified_block().round(),
            self.sync_info
                .highest_timeout_certificate()
                .map_or(0, |tc| tc.round()),
        );
        ensure!(
            previous_round == highest_certified_round,
            "Proposal {} does not have a certified round {}",
            self.proposal,
            previous_round
        );
        ensure!(
            self.proposal.author().is_some(),
            "Proposal {} does not define an author",
            self.proposal
        );
        Ok(())
    }

    pub fn verify(&self, validator: &ValidatorVerifier) -> Result<()> {
        self.proposal
            .validate_signature(validator)
            .map_err(|e| format_err!("{:?}", e))?;
        // if there is a timeout certificate, verify its signatures
        if let Some(tc) = self.sync_info.highest_timeout_certificate() {
            tc.verify(validator).map_err(|e| format_err!("{:?}", e))?;
        }
        // Note that we postpone the verification of SyncInfo until it's being used.
        self.verify_well_formed()
    }

    pub fn proposal(&self) -> &Block {
        &self.proposal
    }

    pub fn take_proposal(self) -> Block {
        self.proposal
    }

    pub fn sync_info(&self) -> &SyncInfo {
        &self.sync_info
    }

    pub fn proposer(&self) -> Author {
        self.proposal
            .author()
            .expect("Proposal should be verified having an author")
    }
}

impl fmt::Display for ProposalMsg {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[proposal {} from ", self.proposal)?;
        match self.proposal.author() {
            Some(author) => write!(f, "{}]", author.short_str()),
            None => write!(f, "NIL]"),
        }
    }
}
<commit_msg>[2chain] fix a bug in ProposalMsg::verify<commit_after>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{block::Block, common::Author, sync_info::SyncInfo};
use anyhow::{anyhow, ensure, format_err, Context, Result};
use diem_types::validator_verifier::ValidatorVerifier;
use serde::{Deserialize, Serialize};
use short_hex_str::AsShortHexStr;
use std::fmt;

/// ProposalMsg contains the required information for the proposer election protocol to make its
/// choice (typically depends on round and proposer info).
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct ProposalMsg {
    proposal: Block,
    sync_info: SyncInfo,
}

impl ProposalMsg {
    /// Creates a new proposal.
    pub fn new(proposal: Block, sync_info: SyncInfo) -> Self {
        Self {
            proposal,
            sync_info,
        }
    }

    pub fn epoch(&self) -> u64 {
        self.proposal.epoch()
    }

    /// Verifies that the ProposalMsg is well-formed.
    pub fn verify_well_formed(&self) -> Result<()> {
        ensure!(
            !self.proposal.is_nil_block(),
            "Proposal {} for a NIL block",
            self.proposal
        );
        self.proposal
            .verify_well_formed()
            .context("Fail to verify ProposalMsg's block")?;
        ensure!(
            self.proposal.round() > 0,
            "Proposal for {} has an incorrect round of 0",
            self.proposal,
        );
        ensure!(
            self.proposal.epoch() == self.sync_info.epoch(),
            "ProposalMsg has different epoch number from SyncInfo"
        );
        ensure!(
            self.proposal.parent_id()
                == self.sync_info.highest_quorum_cert().certified_block().id(),
            "Proposal HQC in SyncInfo certifies {}, but block parent id is {}",
            self.sync_info.highest_quorum_cert().certified_block().id(),
            self.proposal.parent_id(),
        );
        let previous_round = self
            .proposal
            .round()
            .checked_sub(1)
            .ok_or_else(|| anyhow!("proposal round overflowed!"))?;

        let highest_certified_round = std::cmp::max(
            self.proposal.quorum_cert().certified_block().round(),
            self.sync_info.highest_timeout_round(),
        );
        ensure!(
            previous_round == highest_certified_round,
            "Proposal {} does not have a certified round {}",
            self.proposal,
            previous_round
        );
        ensure!(
            self.proposal.author().is_some(),
            "Proposal {} does not define an author",
            self.proposal
        );
        Ok(())
    }

    pub fn verify(&self, validator: &ValidatorVerifier) -> Result<()> {
        self.proposal
            .validate_signature(validator)
            .map_err(|e| format_err!("{:?}", e))?;
        // if there is a timeout certificate, verify its signatures
        if let Some(tc) = self.sync_info.highest_timeout_certificate() {
            tc.verify(validator).map_err(|e| format_err!("{:?}", e))?;
        }
        if let Some(tc) = self.sync_info.highest_2chain_timeout_cert() {
            tc.verify(validator).map_err(|e| format_err!("{:?}", e))?;
        }
        // Note that we postpone the verification of SyncInfo until it's being used.
        self.verify_well_formed()
    }

    pub fn proposal(&self) -> &Block {
        &self.proposal
    }

    pub fn take_proposal(self) -> Block {
        self.proposal
    }

    pub fn sync_info(&self) -> &SyncInfo {
        &self.sync_info
    }

    pub fn proposer(&self) -> Author {
        self.proposal
            .author()
            .expect("Proposal should be verified having an author")
    }
}

impl fmt::Display for ProposalMsg {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[proposal {} from ", self.proposal)?;
        match self.proposal.author() {
            Some(author) => write!(f, "{}]", author.short_str()),
            None => write!(f, "NIL]"),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

extern crate num;

use self::num::complex::{Complex, Complex32, Complex64};
use std::cmp;
use default::Default;
use pointer::CPtr;
use scalar::Scalar;
use vector;
use vector::BlasVector;

pub trait Copy {
    fn copy(x: &BlasVector<Self>, y: &mut BlasVector<Self>);
}

macro_rules! copy_impl(
    ($t: ty, $copy_fn: ident) => (
        impl Copy for $t {
            fn copy(x: &BlasVector<$t>, y: &mut BlasVector<$t>) {
                unsafe {
                    vector::ll::$copy_fn(x.len(),
                        x.as_ptr().as_c_ptr(),  x.inc(),
                        y.as_mut_ptr().as_c_ptr(), y.inc());
                }
            }
        }
    );
)

copy_impl!(f32,       cblas_scopy)
copy_impl!(f64,       cblas_dcopy)
copy_impl!(Complex32, cblas_ccopy)
copy_impl!(Complex64, cblas_zcopy)

pub trait Axpy {
    fn axpy(alpha: Self, x: &BlasVector<Self>, y: &mut BlasVector<Self>);
}

macro_rules! axpy_impl(
    ($t: ty, $update_fn: ident) => (
        impl Axpy for $t {
            fn axpy(alpha: $t, x: &BlasVector<$t>, y: &mut BlasVector<$t>) {
                unsafe {
                    let n = cmp::min(x.len(), y.len());

                    vector::ll::$update_fn(n,
                        (&alpha).as_const(),
                        x.as_ptr().as_c_ptr(), x.inc(),
                        y.as_mut_ptr().as_c_ptr(), y.inc());
                }
            }
        }
    );
)

axpy_impl!(f32,       cblas_saxpy)
axpy_impl!(f64,       cblas_daxpy)
axpy_impl!(Complex32, cblas_caxpy)
axpy_impl!(Complex64, cblas_zaxpy)

#[cfg(test)]
mod axpy_tests {
    extern crate num;
    extern crate test;

    use self::num::complex::Complex;
    use vector::ops::Axpy;

    #[test]
    fn real() {
        let x = vec![1f32,-2f32,3f32,4f32];
        let y = vec![3f32,7f32,-2f32,2f32];
        let mut z = y.clone();

        Axpy::axpy(1f32, &y, &mut z);
        Axpy::axpy(1f32, &x, &mut z);
        assert_eq!(z, vec![7f32,12f32,-1f32,8f32]);
    }

    #[test]
    fn complex() {
        let x = vec![Complex::new(1f32, 1f32), Complex::new(1f32, 3f32)];
        let y = vec![Complex::new(3f32, -2f32), Complex::new(2f32, 3f32)];
        let mut z = x.clone();

        Axpy::axpy(Complex::new(-1f32, 1f32), &y, &mut z);
        assert_eq!(z, vec![Complex::new(0f32, 6f32), Complex::new(-4f32, 2f32)]);
    }

}

pub trait Scal {
    fn scal(alpha: Self, x: &mut BlasVector<Self>);
}

macro_rules! scal_impl(
    ($t: ty, $scal_fn: ident) => (
        impl Scal for $t {
            #[inline]
            fn scal(alpha: $t, x: &mut BlasVector<$t>) {
                unsafe {
                    vector::ll::$scal_fn(x.len(),
                        alpha,
                        x.as_mut_ptr().as_c_ptr(), x.inc());
                }
            }
        }
    );

    ($t: ty, $scal_fn: ident, $real_scal_fn: ident) => (
        impl Scal for $t {
            #[inline]
            fn scal(alpha: $t, x: &mut BlasVector<$t>) {
                if alpha.im == 0.0 {
                    unsafe {
                        vector::ll::$real_scal_fn(x.len(),
                            alpha.re,
                            x.as_mut_ptr().as_c_ptr(), x.inc());
                    }
                } else {
                    unsafe {
                        vector::ll::$scal_fn(x.len(),
                            (&alpha).as_const(),
                            x.as_mut_ptr().as_c_ptr(), x.inc());
                    }
                }
            }
        }
    );
)

scal_impl!(f32, cblas_sscal)
scal_impl!(f64, cblas_dscal)
scal_impl!(Complex32, cblas_cscal, cblas_csscal)
scal_impl!(Complex64, cblas_zscal, cblas_zdscal)

#[cfg(test)]
mod scal_tests {
    extern crate num;
    extern crate test;

    use self::num::complex::Complex;
    use vector::ops::Scal;

    #[test]
    fn real() {
        let mut x = vec![1f32,-2f32,3f32,4f32];

        Scal::scal(-2f32, &mut x);
        assert_eq!(x, vec![-2f32, 4f32, -6f32, -8f32]);
    }

    #[test]
    fn complex() {
        let mut x = vec![Complex::new(1f32, 1f32), Complex::new(1f32, 3f32)];

        Scal::scal(Complex::new(1f32, 1f32), &mut x);
        assert_eq!(x, vec![Complex::new(0f32, 2f32), Complex::new(-2f32, 4f32)]);
    }

    #[test]
    fn complex_real() {
        let mut x = vec![Complex::new(1f32, 1f32), Complex::new(1f32, 3f32)];

        Scal::scal(Complex::new(2f32, 0f32), &mut x);
        assert_eq!(x, vec![Complex::new(2f32, 2f32), Complex::new(2f32, 6f32)]);
    }

}

pub trait Swap {
    fn swap(x: &mut BlasVector<Self>, y: &mut BlasVector<Self>);
}

macro_rules! swap_impl(
    ($t: ty, $swap_fn: ident) => (
        impl Swap for $t {
            fn swap(x: &mut BlasVector<$t>, y: &mut BlasVector<$t>) {
                unsafe {
                    let n = cmp::min(x.len(), y.len());

                    vector::ll::$swap_fn(n,
                        x.as_mut_ptr().as_c_ptr(), x.inc(),
                        y.as_mut_ptr().as_c_ptr(), y.inc());
                }
            }
        }
    );
)

swap_impl!(f32,       cblas_sswap)
swap_impl!(f64,       cblas_dswap)
swap_impl!(Complex32, cblas_cswap)
swap_impl!(Complex64, cblas_zswap)

#[cfg(test)]
mod swap_tests {
    extern crate num;
    extern crate test;

    use self::num::complex::Complex;
    use vector::ops::Swap;

    #[test]
    fn real() {
        let mut x = vec![1f32,-2f32,3f32,4f32];
        let mut y = vec![2f32,-3f32,4f32,1f32];
        let xr = y.clone();
        let yr = x.clone();

        Swap::swap(&mut x, &mut y);
        assert_eq!(x, xr);
        assert_eq!(y, yr);
    }

    #[test]
    fn complex() {
        let mut x = vec![Complex::new(2f32, -3f32)];
        let mut y = vec![Complex::new(-1f32, 4f32)];
        let xr = y.clone();
        let yr = x.clone();

        Swap::swap(&mut x, &mut y);
        assert_eq!(x, xr);
        assert_eq!(y, yr);
    }

}

pub trait Dot {
    fn dot(x: &BlasVector<Self>, y: &BlasVector<Self>) -> Self;
}

macro_rules! real_dot_impl(
    ($t: ty, $dot_fn: ident) => (
        impl Dot for $t {
            fn dot(x: &BlasVector<$t>, y: &BlasVector<$t>) -> $t {
                unsafe {
                    let n = cmp::min(x.len(), y.len());

                    vector::ll::$dot_fn(n,
                        x.as_ptr().as_c_ptr(), x.inc(),
                        y.as_ptr().as_c_ptr(), y.inc()) as $t
                }
            }
        }
    );
)

macro_rules! complex_dot_impl(
    ($t: ty, $dot_fn: ident) => (
        impl Dot for $t {
            fn dot(x: &BlasVector<$t>, y: &BlasVector<$t>) -> $t {
                let result: $t = Default::zero();

                unsafe {
                    let n = cmp::min(x.len(), y.len());

                    vector::ll::$dot_fn(n,
                        x.as_ptr().as_c_ptr(), x.inc(),
                        y.as_ptr().as_c_ptr(), y.inc(),
                        (&result).as_mut());
                }

                result
            }
        }
    );
)

real_dot_impl!(f32, cblas_sdot)
real_dot_impl!(f64, cblas_ddot)
complex_dot_impl!(Complex32, cblas_cdotu_sub)
complex_dot_impl!(Complex64, cblas_zdotu_sub)

#[cfg(test)]
mod dot_tests {
    extern crate num;
    extern crate test;

    use self::num::complex::Complex;
    use vector::ops::Dot;

    #[test]
    fn real() {
        let x = vec![1f32,-2f32,3f32,4f32];
        let y = vec![1f32,1f32,1f32,1f32];

        let xr: f32 = Dot::dot(&x, &y);
        assert_eq!(xr, 6f32);
    }

    #[test]
    fn complex() {
        let x = vec![Complex::new(1f32, 1f32), Complex::new(1f32, 3f32)];
        let y = vec![Complex::new(1f32, 1f32), Complex::new(1f32, 1f32)];

        let xr: Complex<f32> = Dot::dot(&x, &y);
        assert_eq!(xr, Complex::new(-2f32, 6f32));
    }

}
<commit_msg>Add Dotc trait<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

extern crate num;

use self::num::complex::{Complex, Complex32, Complex64};
use std::cmp;
use default::Default;
use pointer::CPtr;
use scalar::Scalar;
use vector;
use vector::BlasVector;

pub trait Copy {
    fn copy(x: &BlasVector<Self>, y: &mut BlasVector<Self>);
}

macro_rules! copy_impl(
    ($t: ty, $copy_fn: ident) => (
        impl Copy for $t {
            fn copy(x: &BlasVector<$t>, y: &mut BlasVector<$t>) {
                unsafe {
                    vector::ll::$copy_fn(x.len(),
                        x.as_ptr().as_c_ptr(),  x.inc(),
                        y.as_mut_ptr().as_c_ptr(), y.inc());
                }
            }
        }
    );
)

copy_impl!(f32,       cblas_scopy)
copy_impl!(f64,       cblas_dcopy)
copy_impl!(Complex32, cblas_ccopy)
copy_impl!(Complex64, cblas_zcopy)

pub trait Axpy {
    fn axpy(alpha: Self, x: &BlasVector<Self>, y: &mut BlasVector<Self>);
}

macro_rules! axpy_impl(
    ($t: ty, $update_fn: ident) => (
        impl Axpy for $t {
            fn axpy(alpha: $t, x: &BlasVector<$t>, y: &mut BlasVector<$t>) {
                unsafe {
                    let n = cmp::min(x.len(), y.len());

                    vector::ll::$update_fn(n,
                        (&alpha).as_const(),
                        x.as_ptr().as_c_ptr(), x.inc(),
                        y.as_mut_ptr().as_c_ptr(), y.inc());
                }
            }
        }
    );
)

axpy_impl!(f32,       cblas_saxpy)
axpy_impl!(f64,       cblas_daxpy)
axpy_impl!(Complex32, cblas_caxpy)
axpy_impl!(Complex64, cblas_zaxpy)

#[cfg(test)]
mod axpy_tests {
    extern crate num;
    extern crate test;

    use self::num::complex::Complex;
    use vector::ops::Axpy;

    #[test]
    fn real() {
        let x = vec![1f32,-2f32,3f32,4f32];
        let y = vec![3f32,7f32,-2f32,2f32];
        let mut z = y.clone();

        Axpy::axpy(1f32, &y, &mut z);
        Axpy::axpy(1f32, &x, &mut z);
        assert_eq!(z, vec![7f32,12f32,-1f32,8f32]);
    }

    #[test]
    fn complex() {
        let x = vec![Complex::new(1f32, 1f32), Complex::new(1f32, 3f32)];
        let y = vec![Complex::new(3f32, -2f32), Complex::new(2f32, 3f32)];
        let mut z = x.clone();

        Axpy::axpy(Complex::new(-1f32, 1f32), &y, &mut z);
        assert_eq!(z, vec![Complex::new(0f32, 6f32), Complex::new(-4f32, 2f32)]);
    }

}

pub trait Scal {
    fn scal(alpha: Self, x: &mut BlasVector<Self>);
}

macro_rules! scal_impl(
    ($t: ty, $scal_fn: ident) => (
        impl Scal for $t {
            #[inline]
            fn scal(alpha: $t, x: &mut BlasVector<$t>) {
                unsafe {
                    vector::ll::$scal_fn(x.len(),
                        alpha,
                        x.as_mut_ptr().as_c_ptr(), x.inc());
                }
            }
        }
    );

    ($t: ty, $scal_fn: ident, $real_scal_fn: ident) => (
        impl Scal for $t {
            #[inline]
            fn scal(alpha: $t, x: &mut BlasVector<$t>) {
                if alpha.im == 0.0 {
                    unsafe {
                        vector::ll::$real_scal_fn(x.len(),
                            alpha.re,
                            x.as_mut_ptr().as_c_ptr(), x.inc());
                    }
                } else {
                    unsafe {
                        vector::ll::$scal_fn(x.len(),
                            (&alpha).as_const(),
                            x.as_mut_ptr().as_c_ptr(), x.inc());
                    }
                }
            }
        }
    );
)

scal_impl!(f32, cblas_sscal)
scal_impl!(f64, cblas_dscal)
scal_impl!(Complex32, cblas_cscal, cblas_csscal)
scal_impl!(Complex64, cblas_zscal, cblas_zdscal)

#[cfg(test)]
mod scal_tests {
    extern crate num;
    extern crate test;

    use self::num::complex::Complex;
    use vector::ops::Scal;

    #[test]
    fn real() {
        let mut x = vec![1f32,-2f32,3f32,4f32];

        Scal::scal(-2f32, &mut x);
        assert_eq!(x, vec![-2f32, 4f32, -6f32, -8f32]);
    }

    #[test]
    fn complex() {
        let mut x = vec![Complex::new(1f32, 1f32), Complex::new(1f32, 3f32)];

        Scal::scal(Complex::new(1f32, 1f32), &mut x);
        assert_eq!(x, vec![Complex::new(0f32, 2f32), Complex::new(-2f32, 4f32)]);
    }

    #[test]
    fn complex_real() {
        let mut x = vec![Complex::new(1f32, 1f32), Complex::new(1f32, 3f32)];

        Scal::scal(Complex::new(2f32, 0f32), &mut x);
        assert_eq!(x, vec![Complex::new(2f32, 2f32), Complex::new(2f32, 6f32)]);
    }

}

pub trait Swap {
    fn swap(x: &mut BlasVector<Self>, y: &mut BlasVector<Self>);
}

macro_rules! swap_impl(
    ($t: ty, $swap_fn: ident) => (
        impl Swap for $t {
            fn swap(x: &mut BlasVector<$t>, y: &mut BlasVector<$t>) {
                unsafe {
                    let n = cmp::min(x.len(), y.len());

                    vector::ll::$swap_fn(n,
                        x.as_mut_ptr().as_c_ptr(), x.inc(),
                        y.as_mut_ptr().as_c_ptr(), y.inc());
                }
            }
        }
    );
)

swap_impl!(f32,       cblas_sswap)
swap_impl!(f64,       cblas_dswap)
swap_impl!(Complex32, cblas_cswap)
swap_impl!(Complex64, cblas_zswap)

#[cfg(test)]
mod swap_tests {
    extern crate num;
    extern crate test;

    use self::num::complex::Complex;
    use vector::ops::Swap;

    #[test]
    fn real() {
        let mut x = vec![1f32,-2f32,3f32,4f32];
        let mut y = vec![2f32,-3f32,4f32,1f32];
        let xr = y.clone();
        let yr = x.clone();

        Swap::swap(&mut x, &mut y);
        assert_eq!(x, xr);
        assert_eq!(y, yr);
    }

    #[test]
    fn complex() {
        let mut x = vec![Complex::new(2f32, -3f32)];
        let mut y = vec![Complex::new(-1f32, 4f32)];
        let xr = y.clone();
        let yr = x.clone();

        Swap::swap(&mut x, &mut y);
        assert_eq!(x, xr);
        assert_eq!(y, yr);
    }

}

pub trait Dot {
    fn dot(x: &BlasVector<Self>, y: &BlasVector<Self>) -> Self;
}

macro_rules! real_dot_impl(
    ($t: ty, $dot_fn: ident) => (
        impl Dot for $t {
            fn dot(x: &BlasVector<$t>, y: &BlasVector<$t>) -> $t {
                unsafe {
                    let n = cmp::min(x.len(), y.len());

                    vector::ll::$dot_fn(n,
                        x.as_ptr().as_c_ptr(), x.inc(),
                        y.as_ptr().as_c_ptr(), y.inc()) as $t
                }
            }
        }
    );
)

macro_rules! complex_dot_impl(
    ($t: ty, $dot_fn: ident) => (
        impl Dot for $t {
            fn dot(x: &BlasVector<$t>, y: &BlasVector<$t>) -> $t {
                let result: $t = Default::zero();

                unsafe {
                    let n = cmp::min(x.len(), y.len());

                    vector::ll::$dot_fn(n,
                        x.as_ptr().as_c_ptr(), x.inc(),
                        y.as_ptr().as_c_ptr(), y.inc(),
                        (&result).as_mut());
                }

                result
            }
        }
    );
)

real_dot_impl!(f32, cblas_sdot)
real_dot_impl!(f64, cblas_ddot)
complex_dot_impl!(Complex32, cblas_cdotu_sub)
complex_dot_impl!(Complex64, cblas_zdotu_sub)

#[cfg(test)]
mod dot_tests {
    extern crate num;
    extern crate test;

    use self::num::complex::Complex;
    use vector::ops::Dot;

    #[test]
    fn real() {
        let x = vec![1f32,-2f32,3f32,4f32];
        let y = vec![1f32,1f32,1f32,1f32];

        let xr: f32 = Dot::dot(&x, &y);
        assert_eq!(xr, 6f32);
    }

    #[test]
    fn complex() {
        let x = vec![Complex::new(1f32, 1f32), Complex::new(1f32, 3f32)];
        let y = vec![Complex::new(1f32, 1f32), Complex::new(1f32, 1f32)];

        let xr: Complex<f32> = Dot::dot(&x, &y);
        assert_eq!(xr, Complex::new(-2f32, 6f32));
    }

}

pub trait Dotc {
    fn dotc(x: &BlasVector<Self>, y: &BlasVector<Self>) -> Self;
}

macro_rules! dot_impl(
    ($t: ty, $dotc_fn: ident) => (
        impl Dotc for $t {
            fn dotc(x: &BlasVector<$t>, y: &BlasVector<$t>) -> $t {
                let result: $t = Default::zero();

                unsafe {
                    let n = cmp::min(x.len(), y.len());

                    vector::ll::$dotc_fn(n,
                        x.as_ptr().as_c_ptr(), x.inc(),
                        y.as_ptr().as_c_ptr(), y.inc(),
                        (&result).as_mut());
                }

                result
            }
        }
    );
)

dot_impl!(Complex32, cblas_cdotc_sub)
dot_impl!(Complex64, cblas_zdotc_sub)

#[cfg(test)]
mod dotc_tests {
    extern crate num;
    extern crate test;

    use self::num::complex::Complex;
    use vector::ops::Dotc;

    #[test]
    fn complex_conj() {
        let x = vec![Complex::new(1f32, -1f32), Complex::new(1f32, -3f32)];
        let y = vec![Complex::new(1f32, 2f32), Complex::new(1f32, 3f32)];

        let xr: Complex<f32> = Dotc::dotc(&x, &y);
        assert_eq!(xr, Complex::new(-9f32, 9f32));
    }
}
<|endoftext|>


<commit_before>
use std::fmt;
use std::panic;

use data::*;
use generators::*;

/// Configuration that allows the user to override how many tests, skipped-tests etc.
/// are permitted.
#[derive(Debug, Clone)]
pub struct CheckConfig {
    num_tests: usize,
    max_skips: usize,
}

impl Default for CheckConfig {
    fn default() -> Self {
        let num_tests = 100;
        CheckConfig {
            num_tests: num_tests,
            max_skips: num_tests * 10,
        }
    }
}
impl CheckConfig {
    /// Overrides how many tests (either failing or successful) are executed.
    pub fn num_tests(&self, num_tests: usize) -> Self {
        CheckConfig {
            num_tests,
            ..self.clone()
        }
    }
    /// Overrides how many times the generators can skip generation before we
    /// abort the test run.
    pub fn max_skips(&self, max_skips: usize) -> Self {
        CheckConfig {
            max_skips,
            ..self.clone()
        }
    }
    /// This is the main entry point for users of the library.
    pub fn property<G: Generator>(&self, gen: G) -> Property<G> {
        Property {
            config: self.clone(),
            gen: gen,
        }
    }
}

/// This represents a configuration for a particular test, ie: a set of generators
/// and a (currently fixed) set of test parameters.
pub struct Property<G> {
    config: CheckConfig,
    gen: G,
}

/// This represents something that a check can return.
pub trait CheckResult {
    /// Check whether this result witnesses a failure.
    fn is_failure(&self) -> bool;
}

/// See [`CheckConfig::property`](struct.CheckConfig.html#method.property)
/// Initiates a test with default configuration.
pub fn property<G: Generator>(gen: G) -> Property<G> {
    CheckConfig::default().property(gen)
}

impl<G: Generator> Property<G>
where
    G::Item: fmt::Debug,
{
    /// Use this function to sepecify the thing you wish to check. Because we include the
    /// debug representation of the input and the output within the
    pub fn check<R: CheckResult + fmt::Debug, F: Fn(G::Item) -> R>(self, subject: F) {
        let mut tests_run = 0usize;
        let mut items_skipped = 0usize;
        while tests_run < self.config.num_tests {
            let mut pool = InfoPool::new();
            trace!("Tests run: {}; skipped:{}", tests_run, items_skipped);
            match self.gen.generate(&mut pool.tap()) {
                Ok(arg) => {
                    let res = Self::attempt(&subject, arg);
                    trace!(
                        "Result: {:?} -> {:?}",
                        self.gen.generate(&mut pool.replay()),
                        res
                    );
                    tests_run += 1;
                    if res.is_failure() {
                        let minpool = find_minimal(
                            &self.gen,
                            pool,
                            |v| Self::attempt(&subject, v).is_failure(),
                        );
                        panic!(
                            "Predicate failed for argument {:?}; check returned {:?}",
                            self.gen.generate(&mut minpool.replay()),
                            res
                        )
                    }
                }
                Err(DataError::SkipItem) => {
                    trace!("Skip: {:?}", self.gen.generate(&mut pool.replay()));
                    items_skipped += 1;
                    if items_skipped >= self.config.max_skips {
                        panic!(
                            "Could not finish on {}/{} tests (have skipped {} times)",
                            tests_run,
                            self.config.num_tests,
                            items_skipped
                        );
                    }
                }
                Err(e) => {
                    trace!("Gen failure: {:?}", self.gen.generate(&mut pool.replay()));
                    debug!("{:?}", e);
                }
            }
        }
        trace!("Completing okay");
    }

    fn attempt<R: CheckResult, F: Fn(G::Item) -> R>(subject: F, arg: G::Item) -> Result<R, String> {
        let res = panic::catch_unwind(panic::AssertUnwindSafe(|| subject(arg)));
        match res {
            Ok(r) => Ok(r),
            Err(err) => {
                let msg = if let Some(s) = err.downcast_ref::<&str>() {
                    s.to_string()
                } else if let Some(s) = err.downcast_ref::<String>() {
                    s.to_string()
                } else {
                    format!("Unrecognised panic result: {:?}", err)
                };
                Err(msg)
            }
        }
    }
}

impl CheckResult for bool {
    fn is_failure(&self) -> bool {
        !self
    }
}

impl<O: CheckResult, E> CheckResult for Result<O, E> {
    fn is_failure(&self) -> bool {
        self.as_ref().map(|r| r.is_failure()).unwrap_or(true)
    }
}

impl CheckResult for () {
    fn is_failure(&self) -> bool {
        false
    }
}
<commit_msg>Refactor the test driver a tad.<commit_after>
use std::fmt;
use std::panic;

use data::*;
use generators::*;

/// Configuration that allows the user to override how many tests, skipped-tests etc.
/// are permitted.
#[derive(Debug, Clone)]
pub struct CheckConfig {
    num_tests: usize,
    max_skips: usize,
}

impl Default for CheckConfig {
    fn default() -> Self {
        let num_tests = 100;
        CheckConfig {
            num_tests: num_tests,
            max_skips: num_tests * 10,
        }
    }
}
impl CheckConfig {
    /// Overrides how many tests (either failing or successful) are executed.
    pub fn num_tests(&self, num_tests: usize) -> Self {
        CheckConfig {
            num_tests,
            ..self.clone()
        }
    }
    /// Overrides how many times the generators can skip generation before we
    /// abort the test run.
    pub fn max_skips(&self, max_skips: usize) -> Self {
        CheckConfig {
            max_skips,
            ..self.clone()
        }
    }
    /// This is the main entry point for users of the library.
    pub fn property<G: Generator>(&self, gen: G) -> Property<G> {
        Property {
            config: self.clone(),
            gen: gen,
        }
    }
}

/// This represents a configuration for a particular test, ie: a set of generators
/// and a (currently fixed) set of test parameters.
pub struct Property<G> {
    config: CheckConfig,
    gen: G,
}

/// This represents something that a check can return.
pub trait CheckResult {
    /// Check whether this result witnesses a failure.
    fn is_failure(&self) -> bool;
}

/// See [`CheckConfig::property`](struct.CheckConfig.html#method.property)
/// Initiates a test with default configuration.
pub fn property<G: Generator>(gen: G) -> Property<G> {
    CheckConfig::default().property(gen)
}

#[derive(Debug, Clone, Default)]
struct Stats {
    tests_run: usize,
    items_skipped: usize,
}

impl<G: Generator> Property<G>
where
    G::Item: fmt::Debug,
{
    /// Use this function to sepecify the thing you wish to check. Because we include the
    /// debug representation of the input and the output within the
    pub fn check<R: CheckResult + fmt::Debug, F: Fn(G::Item) -> R>(self, subject: F) {
        let mut stats = Stats::default();
        while stats.tests_run < self.config.num_tests {
            trace!("Tests run: {}; skipped:{}", stats.tests_run, stats.items_skipped);
            self.try_one(&mut stats, &subject)
        }
        trace!("Completing okay");
    }

    fn try_one<R: CheckResult + fmt::Debug, F: Fn(G::Item) -> R>(
            &self, stats: &mut Stats, subject: &F) {
        let mut pool = InfoPool::new();
        match self.gen.generate(&mut pool.tap()) {
            Ok(arg) => {
                stats.tests_run += 1;
                self.try_example(subject, pool, arg)
            }
            Err(DataError::SkipItem) => {
                stats.items_skipped += 1;
                trace!("Skip");

                if stats.items_skipped >= self.config.max_skips {
                    panic!(
                        "Could not finish on {}/{} tests (have skipped {} times)",
                        stats.tests_run,
                        self.config.num_tests,
                        stats.items_skipped
                    );
                }
            }
            Err(e) => {
                debug!("Data generation failure: {:?}", e);
            }
        }
    }

    fn try_example<R: CheckResult + fmt::Debug, F: Fn(G::Item) -> R>(&self, subject: &F, pool: InfoPool, arg: G::Item) {
        let res = Self::attempt(&subject, arg);
        trace!(
            "Result: {:?} -> {:?}",
            self.gen.generate(&mut pool.replay()),
            res
        );
        if res.is_failure() {
            let minpool = find_minimal(
                &self.gen,
                pool,
                |v| Self::attempt(&subject, v).is_failure(),
            );
            panic!(
                "Predicate failed for argument {:?}; check returned {:?}",
                self.gen.generate(&mut minpool.replay()),
                res
            )
        }

    }

    fn attempt<R: CheckResult, F: Fn(G::Item) -> R>(subject: F, arg: G::Item) -> Result<R, String> {
        let res = panic::catch_unwind(panic::AssertUnwindSafe(|| subject(arg)));
        match res {
            Ok(r) => Ok(r),
            Err(err) => {
                let msg = if let Some(s) = err.downcast_ref::<&str>() {
                    s.to_string()
                } else if let Some(s) = err.downcast_ref::<String>() {
                    s.to_string()
                } else {
                    format!("Unrecognised panic result: {:?}", err)
                };
                Err(msg)
            }
        }
    }
}

impl CheckResult for bool {
    fn is_failure(&self) -> bool {
        !self
    }
}

impl<O: CheckResult, E> CheckResult for Result<O, E> {
    fn is_failure(&self) -> bool {
        self.as_ref().map(|r| r.is_failure()).unwrap_or(true)
    }
}

impl CheckResult for () {
    fn is_failure(&self) -> bool {
        false
    }
}
<|endoftext|>


<commit_before>//#![crate_name = "mesh"]
#![feature(old_io)]
//mod mesh;

use std::cmp::*;
use std::collections::HashMap;
use std::f32::NAN;
use std::fmt;
use std::num::Float;
use std::old_io::{BufferedReader,IoResult,Reader};
use std::hash::{Hash, Hasher};
use std::mem::{transmute};
use std::vec::Vec;

#[derive(PartialEq, PartialOrd, Copy)] //Show,
pub struct Vector3D {
    x: f32,
    y: f32,
    z: f32,
}

// PartialEq is derived above, but we need to impl Eq since floats don't get
// it by default. This function is just a
impl Eq for Vector3D {
    #[inline(always)]
    fn assert_receiver_is_total_eq(&self) {}
}

impl fmt::Debug for Vector3D {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({},{},{})", self.x, self.y, self.z)
    }
}

impl Vector3D {
    fn read(r: &mut Reader) -> IoResult<Vector3D> {
        let xr = try!(r.read_le_f32());
        let yr = try!(r.read_le_f32());
        let zr = try!(r.read_le_f32());
        return Ok(Vector3D { x: xr, y: yr, z: zr });
    }
    fn minus(&self, o: Vector3D) -> Vector3D {
		let x = self.x - o.x;
		let y = self.y - o.y;
		let z = self.z - o.z;
		Vector3D {
			x: x,
			y: y,
			z: z
		}
	}

	fn cross(a: Vector3D, b:Vector3D) -> Vector3D {
		let cx = a.y * b.z - a.z * b.y;
		let cy = a.z * b.x - a.x * b.z;
		let cz = a.x * b.y - a.y * b.x;
		Vector3D {
		x: cx,
		y: cy,
		z: cz
		}
	}

	fn normalize(&self) -> Vector3D {
		// length = sqrt((ax * ax) + (ay * ay) + (az * az))
		let length = (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
		let x = self.x / length;
		let y = self.y / length;
		let z = self.z / length;
		Vector3D {
			x: x,
		    y: y,
		    z: z
		}
	}
}

// Implement Hash since there is no default for f32. We'll just hash the bits
// since we know the f32s will all be canonical from reading.
impl Hash for Vector3D {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        //println!("V3D hash {:p}", self);
        let x: u32 = unsafe { transmute(self.x) };
        x.hash(state);
        let y: u32 = unsafe { transmute(self.y) };
        y.hash(state);
        let z: u32 = unsafe { transmute(self.z) };
        z.hash(state);
        //println!("V3D hash done {:p}", self);
    }
}

#[derive(PartialEq, Eq, Hash, Copy)]
pub struct StlFacet {
    n : Vector3D,
    v1: Vector3D,
    v2: Vector3D,
    v3: Vector3D,
    abc: u16,
}

impl fmt::Debug for StlFacet {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[{:?}]({:?}-{:?}-{:?})[{:X}]",
            &self.n, &self.v1, &self.v2, &self.v3, self.abc)
    }
}

impl StlFacet {
    fn read(r: &mut Reader) -> IoResult<StlFacet> {
        let n = try!(Vector3D::read(r));
        let v1 = try!(Vector3D::read(r));
        let v2 = try!(Vector3D::read(r));
        let v3 = try!(Vector3D::read(r));
        let abc = try!(r.read_le_u16());
        return Ok(StlFacet { n:n, v1:v1, v2:v2, v3:v3, abc:abc });
    }

    fn calculate_normal_vector(&self) -> Vector3D {
		// Dir = (B - A) x (C - A)
		// Norm = Dir / len(Dir)
        let direction = Vector3D::cross( self.v2.minus(self.v1), self.v3.minus(self.v1) );

		// Normalize is optional in our use case
		direction.normalize()
	}
}

pub struct VertexMap {
    vertices: HashMap<Vector3D,usize>,
}

impl VertexMap {
    pub fn new() -> VertexMap {
        VertexMap {
            vertices: HashMap::new(),
        }
    }

    pub fn len(&self) -> usize {
        self.vertices.len()
    }

    pub fn get(&self, v3d: &Vector3D) -> usize {
        *self.vertices.get(v3d).unwrap()
    }

    pub fn add(&mut self, vertex: Vector3D) -> usize {
        if self.vertices.contains_key(&vertex) {
            //println!("add existing {}", vector3d_str(&vertex));
            *self.vertices.get(&vertex).unwrap()
        } else {
            //println!("add new {}", vector3d_str(&vertex));
            let idx = self.vertices.len();
            self.vertices.insert(vertex, idx);
            idx
        }
    }

    pub fn vector(&self) -> Vec<Vector3D> {
        let mut v: Vec<Vector3D> = Vec::with_capacity(self.vertices.len());
        for (v3d, idx) in self.vertices.iter() {
            v.push(*v3d);  // Funkiness just to get v expanded. Below writes the real values.
        }
        for (v3d, idx) in self.vertices.iter() {
            //println!("v3d:{:?} idx:{}", v3d, idx);
            v[*idx] = *v3d;
        }
        //for i in 0..v.len() {
        //    println!("v3d[{}]: {:?}", i, v[i]);
        //}
        v
    }
}

#[derive(PartialEq, Debug, Eq, Hash, Copy)]
pub struct Facet {
    v1: usize,
    v2: usize,
    v3: usize,
    n: Vector3D
}

pub struct Mesh {
    vertices: Vec<Vector3D>,
    facets: Vec<Facet>,
}

impl Mesh {
    pub fn new() -> Mesh {
        Mesh {
            vertices: Vec::new(),
            facets: Vec::new(),
        }
    }

    fn indexed_vertices(fv: &Vec<StlFacet>, vm: &VertexMap) -> Vec<Facet> {
        let mut v: Vec<Facet> = Vec::with_capacity(fv.len());
        for f in fv.iter() {
            let v1 = vm.get(&f.v1);
            let v2 = vm.get(&f.v2);
            let v3 = vm.get(&f.v3);
			// I wish there was a better place to put this
			let n = f.calculate_normal_vector();
            v.push(Facet{
                v1: v1,
                v2: v2,
                v3: v3,
			    n: n,
            })
        }
        v
    }

    pub fn new_from_stl(fv: &Vec<StlFacet>, vm: &VertexMap) -> Mesh {
        let vs = vm.vector();
        let fs = Mesh::indexed_vertices(fv, vm);
        Mesh {
            vertices: vs,
            facets: fs,
        }
    }

    pub fn read(r: &mut Reader) -> Mesh {

        /*
        let buf = [0; 80];
        let header = match r.read(&buf) {
            Ok(nread) => {
                let hdr = String::from_utf8(&buf).unwrap();
                println!("Header: \"{}\"", hdr);
                hdr
            }
            Err(e) => {
                println!("Truncated file: {}", e);
                return Mesh{vertices: Vec::new(), facets: Vec::new()};
            }
        };

        return if header.starts_with("solid ") {
            println!("Is ASCII STL");
            Mesh::read_ascii(r)
        }
        else {
            println!("Is binary STL");
            Mesh::read_binary(r)
        }
        */
        Mesh::read_binary(r)
    }

    /*
    fn read_ascii(r: &mut Reader) -> Mesh {
        //solid vcg
        //  facet normal 7.733874e-001 -3.151335e-002 6.331499e-001
        //    outer loop
        //      vertex  2.137833e+001 5.385936e+001 1.350253e+001
        //      vertex  2.341920e+001 4.700068e+001 1.066826e+001
        //      vertex  2.859041e+001 5.985682e+001 4.991545e+000
        //    endloop
        //  endfacet
        //endsolid vcg
        for line in r.lines() {
            print!("{}", line.unwrap());
        }
        Mesh::new() // TODO
    }
    */

    fn read_binary(r: &mut Reader) -> Mesh {
        let facet_count = match r.read_le_u32() {
            Ok(c) => { println!("Facets: {}", c); c},
            Err(e) => { println!("Truncated file: {}", e); 0},
        };

        let mut facets: Vec<StlFacet> = Vec::with_capacity(facet_count as usize);
        let mut vertices = VertexMap::new();
        println!("Collections ready");

        for fi in range(0, facet_count) {
            let f = match StlFacet::read(r) {
                Ok(x) => x,
                Err(e) => panic!("file error: {}", e),
            };
            let v1i = vertices.add(f.v1);
            let v2i = vertices.add(f.v2);
            let v3i = vertices.add(f.v3);
            println!("  Facet[{}]: {:?} => {}-{}-{}", fi, f, v1i, v2i, v3i);
            facets.push(f);
        }
        println!("Vertices: {}", vertices.len());

        Mesh::new_from_stl(&facets, &vertices)
    }
}
<commit_msg>Fix tabs<commit_after>//#![crate_name = "mesh"]
#![feature(old_io)]
//mod mesh;

use std::cmp::*;
use std::collections::HashMap;
use std::f32::NAN;
use std::fmt;
use std::num::Float;
use std::old_io::{BufferedReader,IoResult,Reader};
use std::hash::{Hash, Hasher};
use std::mem::{transmute};
use std::vec::Vec;

#[derive(PartialEq, PartialOrd, Copy)] //Show,
pub struct Vector3D {
    x: f32,
    y: f32,
    z: f32,
}

// PartialEq is derived above, but we need to impl Eq since floats don't get
// it by default. This function is just a
impl Eq for Vector3D {
    #[inline(always)]
    fn assert_receiver_is_total_eq(&self) {}
}

impl fmt::Debug for Vector3D {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({},{},{})", self.x, self.y, self.z)
    }
}

impl Vector3D {
    fn read(r: &mut Reader) -> IoResult<Vector3D> {
        let xr = try!(r.read_le_f32());
        let yr = try!(r.read_le_f32());
        let zr = try!(r.read_le_f32());
        return Ok(Vector3D { x: xr, y: yr, z: zr });
    }
    fn minus(&self, o: Vector3D) -> Vector3D {
        let x = self.x - o.x;
        let y = self.y - o.y;
        let z = self.z - o.z;
        Vector3D {
            x: x,
            y: y,
            z: z
        }
    }

    fn cross(a: Vector3D, b:Vector3D) -> Vector3D {
        let cx = a.y * b.z - a.z * b.y;
        let cy = a.z * b.x - a.x * b.z;
        let cz = a.x * b.y - a.y * b.x;
        Vector3D {
        x: cx,
        y: cy,
        z: cz
        }
    }

    fn normalize(&self) -> Vector3D {
        // length = sqrt((ax * ax) + (ay * ay) + (az * az))
        let length = (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
        let x = self.x / length;
        let y = self.y / length;
        let z = self.z / length;
        Vector3D {
            x: x,
            y: y,
            z: z
        }
    }
}

#[test]
fn vectors_can_be_subtracted() {
    //let l = Vector3D{1,1,1}
    //let r = Vector3D{2,3,4}
    assert!(false);
}

// Implement Hash since there is no default for f32. We'll just hash the bits
// since we know the f32s will all be canonical from reading.
impl Hash for Vector3D {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        //println!("V3D hash {:p}", self);
        let x: u32 = unsafe { transmute(self.x) };
        x.hash(state);
        let y: u32 = unsafe { transmute(self.y) };
        y.hash(state);
        let z: u32 = unsafe { transmute(self.z) };
        z.hash(state);
        //println!("V3D hash done {:p}", self);
    }
}

#[derive(PartialEq, Eq, Hash, Copy)]
pub struct StlFacet {
    n : Vector3D,
    v1: Vector3D,
    v2: Vector3D,
    v3: Vector3D,
    abc: u16,
}

impl fmt::Debug for StlFacet {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[{:?}]({:?}-{:?}-{:?})[{:X}]",
            &self.n, &self.v1, &self.v2, &self.v3, self.abc)
    }
}

impl StlFacet {
    fn read(r: &mut Reader) -> IoResult<StlFacet> {
        let n = try!(Vector3D::read(r));
        let v1 = try!(Vector3D::read(r));
        let v2 = try!(Vector3D::read(r));
        let v3 = try!(Vector3D::read(r));
        let abc = try!(r.read_le_u16());
        return Ok(StlFacet { n:n, v1:v1, v2:v2, v3:v3, abc:abc });
    }

    fn calculate_normal_vector(&self) -> Vector3D {
        // Dir = (B - A) x (C - A)
        // Norm = Dir / len(Dir)
        let direction = Vector3D::cross( self.v2.minus(self.v1), self.v3.minus(self.v1) );

        // Normalize is optional in our use case
        direction.normalize()
    }
}

pub struct VertexMap {
    vertices: HashMap<Vector3D,usize>,
}

impl VertexMap {
    pub fn new() -> VertexMap {
        VertexMap {
            vertices: HashMap::new(),
        }
    }

    pub fn len(&self) -> usize {
        self.vertices.len()
    }

    pub fn get(&self, v3d: &Vector3D) -> usize {
        *self.vertices.get(v3d).unwrap()
    }

    pub fn add(&mut self, vertex: Vector3D) -> usize {
        if self.vertices.contains_key(&vertex) {
            //println!("add existing {}", vector3d_str(&vertex));
            *self.vertices.get(&vertex).unwrap()
        } else {
            //println!("add new {}", vector3d_str(&vertex));
            let idx = self.vertices.len();
            self.vertices.insert(vertex, idx);
            idx
        }
    }

    pub fn vector(&self) -> Vec<Vector3D> {
        let mut v: Vec<Vector3D> = Vec::with_capacity(self.vertices.len());
        for (v3d, idx) in self.vertices.iter() {
            v.push(*v3d);  // Funkiness just to get v expanded. Below writes the real values.
        }
        for (v3d, idx) in self.vertices.iter() {
            //println!("v3d:{:?} idx:{}", v3d, idx);
            v[*idx] = *v3d;
        }
        //for i in 0..v.len() {
        //    println!("v3d[{}]: {:?}", i, v[i]);
        //}
        v
    }
}

#[derive(PartialEq, Debug, Eq, Hash, Copy)]
pub struct Facet {
    v1: usize,
    v2: usize,
    v3: usize,
    n: Vector3D
}

pub struct Mesh {
    vertices: Vec<Vector3D>,
    facets: Vec<Facet>,
}

impl Mesh {
    pub fn new() -> Mesh {
        Mesh {
            vertices: Vec::new(),
            facets: Vec::new(),
        }
    }

    fn indexed_vertices(fv: &Vec<StlFacet>, vm: &VertexMap) -> Vec<Facet> {
        let mut v: Vec<Facet> = Vec::with_capacity(fv.len());
        for f in fv.iter() {
            let v1 = vm.get(&f.v1);
            let v2 = vm.get(&f.v2);
            let v3 = vm.get(&f.v3);
            // I wish there was a better place to put this
            let n = f.calculate_normal_vector();
            v.push(Facet{
                v1: v1,
                v2: v2,
                v3: v3,
                n: n,
            })
        }
        v
    }

    pub fn new_from_stl(fv: &Vec<StlFacet>, vm: &VertexMap) -> Mesh {
        let vs = vm.vector();
        let fs = Mesh::indexed_vertices(fv, vm);
        Mesh {
            vertices: vs,
            facets: fs,
        }
    }

    pub fn read(r: &mut Reader) -> Mesh {

        /*
        let buf = [0; 80];
        let header = match r.read(&buf) {
            Ok(nread) => {
                let hdr = String::from_utf8(&buf).unwrap();
                println!("Header: \"{}\"", hdr);
                hdr
            }
            Err(e) => {
                println!("Truncated file: {}", e);
                return Mesh{vertices: Vec::new(), facets: Vec::new()};
            }
        };

        return if header.starts_with("solid ") {
            println!("Is ASCII STL");
            Mesh::read_ascii(r)
        }
        else {
            println!("Is binary STL");
            Mesh::read_binary(r)
        }
        */
        Mesh::read_binary(r)
    }

    /*
    fn read_ascii(r: &mut Reader) -> Mesh {
        //solid vcg
        //  facet normal 7.733874e-001 -3.151335e-002 6.331499e-001
        //    outer loop
        //      vertex  2.137833e+001 5.385936e+001 1.350253e+001
        //      vertex  2.341920e+001 4.700068e+001 1.066826e+001
        //      vertex  2.859041e+001 5.985682e+001 4.991545e+000
        //    endloop
        //  endfacet
        //endsolid vcg
        for line in r.lines() {
            print!("{}", line.unwrap());
        }
        Mesh::new() // TODO
    }
    */

    fn read_binary(r: &mut Reader) -> Mesh {
        let facet_count = match r.read_le_u32() {
            Ok(c) => { println!("Facets: {}", c); c},
            Err(e) => { println!("Truncated file: {}", e); 0},
        };

        let mut facets: Vec<StlFacet> = Vec::with_capacity(facet_count as usize);
        let mut vertices = VertexMap::new();
        println!("Collections ready");

        for fi in range(0, facet_count) {
            let f = match StlFacet::read(r) {
                Ok(x) => x,
                Err(e) => panic!("file error: {}", e),
            };
            let v1i = vertices.add(f.v1);
            let v2i = vertices.add(f.v2);
            let v3i = vertices.add(f.v3);
            println!("  Facet[{}]: {:?} => {}-{}-{}", fi, f, v1i, v2i, v3i);
            facets.push(f);
        }
        println!("Vertices: {}", vertices.len());

        Mesh::new_from_stl(&facets, &vertices)
    }
}
<|endoftext|>


<commit_before>use std::sync::Arc;

use index;
use vertex;

use buffer::{BufferView, ScalarTypedView};

#[derive(Debug, Clone)]
pub struct Submesh {
  pub name: String,
  pub view: Arc<BufferView>,
  pub index_count: usize,
  pub index_format: index::Format,
  pub geometry: index::Geometry
}

impl Submesh {
  pub fn faces<'a>(&'a self) -> FaceIterator<'a> {
    return FaceIterator { submesh: self, current: 0 };
  }
}

pub struct FaceIterator<'a> {
  submesh: &'a Submesh,
  current: usize
}

impl<'a> Iterator for FaceIterator<'a> {
  type Item = Vec<usize>;

  fn next(&mut self) -> Option<Vec<usize>> {
    if self.current >= self.len() {
      return None;
    }

    let mut indices = match self.submesh.geometry {
      index::Geometry::Points => {
        let offset = self.current;
        vec![offset + 0]
      }
      index::Geometry::Lines => {
        let offset = self.current;
        vec![offset + 0, offset + 1]
      }
      index::Geometry::TriangleStrips => {
        let offset = self.current;
        vec![offset + 0, offset + 1, offset + 2]
      }
      index::Geometry::Triangles => {
        let offset = 3 * self.current;
        vec![offset + 0, offset + 1, offset + 2]
      }
    };

    match self.submesh.index_format {
      index::Format::u16 => {
        let view = ScalarTypedView::<u16>::new(None, &self.submesh.view, 0, 0, self.submesh.index_count);

        for i in 0 .. indices.len() {
          indices[i] = view[indices[i]] as usize
        }
      }
      index::Format::u32 => {
        let view = ScalarTypedView::<u32>::new(None, &self.submesh.view, 0, 0, self.submesh.index_count);

        for i in 0 .. indices.len() {
          indices[i] = view[indices[i]] as usize
        }
      }
    }

    self.current += 1;

    return Some(indices);
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let length = self.len();

    return (length, Some(length));
  }
}

impl<'a> ExactSizeIterator for FaceIterator<'a> {
  #[inline(always)]
  fn len(&self) -> usize {
    let index_count = self.submesh.index_count;

    return match self.submesh.geometry {
      index::Geometry::Points => index_count,
      index::Geometry::Lines => index_count - 1,
      index::Geometry::TriangleStrips => index_count - 2,
      index::Geometry::Triangles => index_count / 3
    };
  }
}

#[derive(Debug, Clone)]
pub struct Mesh {
  pub name: String,
  pub vertex_count: usize,
  pub descriptor: vertex::Descriptor,
  pub buffers: Vec<Arc<BufferView>>,
  pub submeshes: Vec<Submesh>
}

impl Mesh {
  pub fn attribute_for(&self, name: &vertex::AttributeName) -> Option<&vertex::Attribute> {
    return self.descriptor.attribute_for(name);
  }
}
<commit_msg>Create untyped views from meshes<commit_after>use std::sync::Arc;

use index;
use vertex;
use vertex::{Format, Scalar};

use buffer::{BufferView, TypedView, ScalarTypedView, UntypedView};

#[derive(Debug, Clone)]
pub struct Submesh {
  pub name: String,
  pub view: Arc<BufferView>,
  pub index_count: usize,
  pub index_format: index::Format,
  pub geometry: index::Geometry
}

impl Submesh {
  pub fn faces<'a>(&'a self) -> FaceIterator<'a> {
    return FaceIterator { submesh: self, current: 0 };
  }
}

pub struct FaceIterator<'a> {
  submesh: &'a Submesh,
  current: usize
}

impl<'a> Iterator for FaceIterator<'a> {
  type Item = Vec<usize>;

  fn next(&mut self) -> Option<Vec<usize>> {
    if self.current >= self.len() {
      return None;
    }

    let mut indices = match self.submesh.geometry {
      index::Geometry::Points => {
        let offset = self.current;
        vec![offset + 0]
      }
      index::Geometry::Lines => {
        let offset = self.current;
        vec![offset + 0, offset + 1]
      }
      index::Geometry::TriangleStrips => {
        let offset = self.current;
        vec![offset + 0, offset + 1, offset + 2]
      }
      index::Geometry::Triangles => {
        let offset = 3 * self.current;
        vec![offset + 0, offset + 1, offset + 2]
      }
    };

    match self.submesh.index_format {
      index::Format::u16 => {
        let view = ScalarTypedView::<u16>::new(None, &self.submesh.view, 0, 0, self.submesh.index_count);

        for i in 0 .. indices.len() {
          indices[i] = view[indices[i]] as usize
        }
      }
      index::Format::u32 => {
        let view = ScalarTypedView::<u32>::new(None, &self.submesh.view, 0, 0, self.submesh.index_count);

        for i in 0 .. indices.len() {
          indices[i] = view[indices[i]] as usize
        }
      }
    }

    self.current += 1;

    return Some(indices);
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let length = self.len();

    return (length, Some(length));
  }
}

impl<'a> ExactSizeIterator for FaceIterator<'a> {
  #[inline(always)]
  fn len(&self) -> usize {
    let index_count = self.submesh.index_count;

    return match self.submesh.geometry {
      index::Geometry::Points => index_count,
      index::Geometry::Lines => index_count - 1,
      index::Geometry::TriangleStrips => index_count - 2,
      index::Geometry::Triangles => index_count / 3
    };
  }
}

#[derive(Debug, Clone)]
pub struct Mesh {
  pub name: String,
  pub vertex_count: usize,
  pub descriptor: vertex::Descriptor,
  pub buffers: Vec<Arc<BufferView>>,
  pub submeshes: Vec<Submesh>
}

impl Mesh {
  pub fn attribute_for(&self, name: &vertex::AttributeName) -> Option<&vertex::Attribute> {
    return self.descriptor.attribute_for(name);
  }

  pub fn untyped_view_for<'a>(&'a self, name: &vertex::AttributeName) -> Option<UntypedView<'a>> {
    if let Some(attribute) = self.attribute_for(name) {

      let view = &self.buffers[attribute.buffer_index];

      let offset = attribute.offset;
      let stride = self.descriptor.layouts[attribute.buffer_index].stride;
      let length = self.vertex_count;

      return Some(match attribute.format {
        Format(Scalar::f16, width) => UntypedView::f16(TypedView::<i16>::new(None, view, width, offset, stride, length)),
        Format(Scalar::f32, width) => UntypedView::f32(TypedView::<f32>::new(None, view, width, offset, stride, length)),
        Format(Scalar::u8, width) => UntypedView::u8(TypedView::<u8>::new(None, view, width, offset, stride, length)),
        Format(Scalar::u16, width) => UntypedView::u16(TypedView::<u16>::new(None, view, width, offset, stride, length)),
        Format(Scalar::u32, width) => UntypedView::u32(TypedView::<u32>::new(None, view, width, offset, stride, length)),
        Format(Scalar::u8_normalized, width) => UntypedView::u8_normalized(TypedView::<u8>::new(None, view, width, offset, stride, length)),
        Format(Scalar::u16_normalized, width) => UntypedView::u16_normalized(TypedView::<u16>::new(None, view, width, offset, stride, length)),
        Format(Scalar::u32_normalized, width) => UntypedView::u32_normalized(TypedView::<u32>::new(None, view, width, offset, stride, length)),
        Format(Scalar::i8, width) => UntypedView::i8(TypedView::<i8>::new(None, view, width, offset, stride, length)),
        Format(Scalar::i16, width) => UntypedView::i16(TypedView::<i16>::new(None, view, width, offset, stride, length)),
        Format(Scalar::i32, width) => UntypedView::i32(TypedView::<i32>::new(None, view, width, offset, stride, length)),
        Format(Scalar::i8_normalized, width) => UntypedView::i8_normalized(TypedView::<i8>::new(None, view, width, offset, stride, length)),
        Format(Scalar::i16_normalized, width) => UntypedView::i16_normalized(TypedView::<i16>::new(None, view, width, offset, stride, length)),
        Format(Scalar::i32_normalized, width) => UntypedView::i32_normalized(TypedView::<i32>::new(None, view, width, offset, stride, length)),
      });
    }

    return None;
  }
}
<|endoftext|>


<commit_before>//! Utility module to generate a GraphiQL interface

/// Generate the HTML source to show a GraphiQL interface
pub fn graphiql_source(graphql_endpoint_url: &str) -> String {
    let stylesheet_source = r#"

    "#;
    let fetcher_source = r#"

    "#;

    format!(r#"
<!DOCTYPE html>

    <title>GraphQL</title>
    {stylesheet_source}
    <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/graphiql@0.17.2/graphiql.min.css">

    {fetcher_source}

"#,
        graphql_url = graphql_endpoint_url,
        stylesheet_source = stylesheet_source,
        fetcher_source = fetcher_source)
}
<commit_msg>Bump to latest graphiql (#489)<commit_after>//! Utility module to generate a GraphiQL interface

/// Generate the HTML source to show a GraphiQL interface
pub fn graphiql_source(graphql_endpoint_url: &str) -> String {
    let stylesheet_source = r#"

    "#;
    let fetcher_source = r#"

    "#;

    format!(r#"
<!DOCTYPE html>

    <title>GraphQL</title>
    {stylesheet_source}
    <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/graphiql@0.17.5/graphiql.min.css">

    {fetcher_source}

"#,
        graphql_url = graphql_endpoint_url,
        stylesheet_source = stylesheet_source,
        fetcher_source = fetcher_source)
}
<|endoftext|>


<commit_before>use error::Error;
use client::Client;
use resources::{Address, CardParams, Currency, Deleted, Discount, Source, Subscription};
use params::{List, Metadata};

#[derive(Debug, Deserialize, Serialize)]
pub struct CustomerShippingDetails {
    pub address: Address,
    pub name: String,
    pub phone: String,
}

#[derive(Serialize)]
#[serde(untagged)]
pub enum CustomerSource<'a> {
    Token(&'a str),
    Card(CardParams<'a>),
}

/// The set of parameters that can be used when creating or updating a customer.
///
/// For more details see https://stripe.com/docs/api#create_customer and https://stripe.com/docs/api#update_customer.
#[derive(Default, Serialize)]
pub struct CustomerParams<'a> {
    #[serde(skip_serializing_if = "Option::is_none")] pub account_balance: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")] pub business_vat_id: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub coupon: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub description: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub email: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub metadata: Option<Metadata>,
    #[serde(skip_serializing_if = "Option::is_none")] pub shipping: Option<CustomerShippingDetails>,
    #[serde(skip_serializing_if = "Option::is_none")] pub source: Option<CustomerSource<'a>>,
}

/// The resource representing a Stripe customer.
///
/// For more details see https://stripe.com/docs/api#customers.
#[derive(Debug, Deserialize)]
pub struct Customer {
    pub id: String,
    pub account_balance: i64,
    pub business_vat_id: Option<String>,
    pub created: u64,
    pub currency: Option<Currency>,
    pub default_source: String,
    pub delinquent: bool,
    pub desc: Option<String>,
    pub discount: Option<Discount>,
    pub email: String,
    pub livemode: bool,
    pub metadata: Metadata,
    pub shipping: Option<CustomerShippingDetails>,
    pub sources: List<Source>,
    pub subscriptions: List<Subscription>,
}

impl Customer {
    /// Creates a new customer.
    ///
    /// For more details see https://stripe.com/docs/api#create_customer.
    pub fn create(client: &Client, params: CustomerParams) -> Result<Customer, Error> {
        client.post("/customers", params)
    }

    /// Retrieves the details of a customer.
    ///
    /// For more details see https://stripe.com/docs/api#retrieve_customer.
    pub fn retrieve(client: &Client, customer_id: &str) -> Result<Customer, Error> {
        client.get(&format!("/customers/{}", customer_id))
    }

    /// Updates a customer's properties.
    ///
    /// For more details see https://stripe.com/docs/api#update_customer.
    pub fn update(client: &Client, customer_id: &str, params: CustomerParams) -> Result<Customer, Error> {
        client.post(&format!("/customers/{}", customer_id), params)
    }

    /// Deletes a customer.
    ///
    /// For more details see https://stripe.com/docs/api#delete_customer.
    pub fn delete(client: &Client, customer_id: &str) -> Result<Deleted, Error> {
        client.delete(&format!("/customers/{}", customer_id))
    }
}
<commit_msg>Customers may not have a default source<commit_after>use error::Error;
use client::Client;
use resources::{Address, CardParams, Currency, Deleted, Discount, Source, Subscription};
use params::{List, Metadata};

#[derive(Debug, Deserialize, Serialize)]
pub struct CustomerShippingDetails {
    pub address: Address,
    pub name: String,
    pub phone: String,
}

#[derive(Serialize)]
#[serde(untagged)]
pub enum CustomerSource<'a> {
    Token(&'a str),
    Card(CardParams<'a>),
}

/// The set of parameters that can be used when creating or updating a customer.
///
/// For more details see https://stripe.com/docs/api#create_customer and https://stripe.com/docs/api#update_customer.
#[derive(Default, Serialize)]
pub struct CustomerParams<'a> {
    #[serde(skip_serializing_if = "Option::is_none")] pub account_balance: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")] pub business_vat_id: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub coupon: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub description: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub email: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub metadata: Option<Metadata>,
    #[serde(skip_serializing_if = "Option::is_none")] pub shipping: Option<CustomerShippingDetails>,
    #[serde(skip_serializing_if = "Option::is_none")] pub source: Option<CustomerSource<'a>>,
}

/// The resource representing a Stripe customer.
///
/// For more details see https://stripe.com/docs/api#customers.
#[derive(Debug, Deserialize)]
pub struct Customer {
    pub id: String,
    pub account_balance: i64,
    pub business_vat_id: Option<String>,
    pub created: u64,
    pub currency: Option<Currency>,
    pub default_source: Option<String>,
    pub delinquent: bool,
    pub desc: Option<String>,
    pub discount: Option<Discount>,
    pub email: String,
    pub livemode: bool,
    pub metadata: Metadata,
    pub shipping: Option<CustomerShippingDetails>,
    pub sources: List<Source>,
    pub subscriptions: List<Subscription>,
}

impl Customer {
    /// Creates a new customer.
    ///
    /// For more details see https://stripe.com/docs/api#create_customer.
    pub fn create(client: &Client, params: CustomerParams) -> Result<Customer, Error> {
        client.post("/customers", params)
    }

    /// Retrieves the details of a customer.
    ///
    /// For more details see https://stripe.com/docs/api#retrieve_customer.
    pub fn retrieve(client: &Client, customer_id: &str) -> Result<Customer, Error> {
        client.get(&format!("/customers/{}", customer_id))
    }

    /// Updates a customer's properties.
    ///
    /// For more details see https://stripe.com/docs/api#update_customer.
    pub fn update(client: &Client, customer_id: &str, params: CustomerParams) -> Result<Customer, Error> {
        client.post(&format!("/customers/{}", customer_id), params)
    }

    /// Deletes a customer.
    ///
    /// For more details see https://stripe.com/docs/api#delete_customer.
    pub fn delete(client: &Client, customer_id: &str) -> Result<Deleted, Error> {
        client.delete(&format!("/customers/{}", customer_id))
    }
}
<|endoftext|>


<commit_before>use std::cmp::{max, min};
use std::io::BufRead;

use rustbox::{RustBox, Style, Color};

pub struct MsgArea {
    msgs   : Vec<String>,
    height : i32,

    /// Vertical scroll
    scroll : i32,

    // TODO: logging
}

impl MsgArea {
    pub fn new(height : i32) -> MsgArea {
        MsgArea {
            msgs: Vec::new(),
            height: height,
            scroll: 0,
        }
    }

    pub fn add_msg(&mut self, msg : &Vec<char>) {
        // The vector shouldn't have newlines ('\n'), but we don't check it here
        // for now.

        let msg_str : String = msg.iter().cloned().collect();

        // Decide whether to scroll
        let need_to_scroll = self.scroll + self.height == self.msgs.len() as i32;
        if need_to_scroll {
            self.scroll = (self.msgs.len() as i32) + 1 - self.height;
        }

        self.msgs.push(msg_str);
    }

    pub fn draw(&self, rustbox : &RustBox, pos_x : i32, pos_y : i32) {
        let mut row = self.height - 1;
        let mut line_idx = min(self.scroll + self.height, self.msgs.len() as i32 - 1);
        while line_idx >= 0 {
            rustbox.print(pos_x as usize, (pos_y + row) as usize,
                          Style::empty(), Color::Blue, Color::Default,
                          &self.msgs[line_idx as usize]);
            row -= 1;
            line_idx -= 1;
        }
    }
}
<commit_msg>fix some warnings<commit_after>use std::cmp::min;

use rustbox::{RustBox, Style, Color};

pub struct MsgArea {
    msgs   : Vec<String>,
    height : i32,

    /// Vertical scroll
    scroll : i32,

    // TODO: logging
}

impl MsgArea {
    pub fn new(height : i32) -> MsgArea {
        MsgArea {
            msgs: Vec::new(),
            height: height,
            scroll: 0,
        }
    }

    pub fn add_msg(&mut self, msg : &Vec<char>) {
        // The vector shouldn't have newlines ('\n'), but we don't check it here
        // for now.

        let msg_str : String = msg.iter().cloned().collect();

        // Decide whether to scroll
        let need_to_scroll = self.scroll + self.height == self.msgs.len() as i32;
        if need_to_scroll {
            self.scroll = (self.msgs.len() as i32) + 1 - self.height;
        }

        self.msgs.push(msg_str);
    }

    pub fn draw(&self, rustbox : &RustBox, pos_x : i32, pos_y : i32) {
        let mut row = self.height - 1;
        let mut line_idx = min(self.scroll + self.height, self.msgs.len() as i32 - 1);
        while line_idx >= 0 {
            rustbox.print(pos_x as usize, (pos_y + row) as usize,
                          Style::empty(), Color::Blue, Color::Default,
                          &self.msgs[line_idx as usize]);
            row -= 1;
            line_idx -= 1;
        }
    }
}
<|endoftext|>


<commit_before>use boxed::Box;
use string::String;

use sync::{Arc, Weak};

use sync::spin::{RwLock, RwLockReadGuard, RwLockWriteGuard};

use net::defs::{HwAddr, Ipv4Addr, Device};

use hal::net::HwInterface;

// XXX: Should this be in net::defs ?
/// IPv4 configuration of an interface
pub struct V4Configuration {
    /// Main IPv4 address
    pub ipv4: Ipv4Addr,
    /// Subnet mask
    pub ipv4_mask: Ipv4Addr,
    /// Gateway IPv4 address
    pub ipv4_gateway: Ipv4Addr,
}

#[derive(Clone)]
/// A shareable network interface.
///
/// This is backed by an Arc and a RwLock so that accesses are safe and the
/// entity can be shared.
pub struct Interface(Arc<RwLock<InterfaceRaw>>);

unsafe impl Send for Interface {}

#[derive(Clone)]
/// A interface weak reference
pub struct InterfaceWeak(Weak<RwLock<InterfaceRaw>>);

unsafe impl Send for InterfaceWeak {}

/// The raw network interface
pub struct InterfaceRaw {
    /// Name of the interface
    name: String,
    /// Hardware address of the interface
    hw_addr: HwAddr,
    /// IPv4 configuration of the interface
    conf: V4Configuration,
    /// Underlying driver
    pv_device: Option<Box<HwInterface>>,
}

impl Interface {
    /// Creates a new network interface
    pub fn new() -> Self {
        let inner = InterfaceRaw {
            name: String::new(),
            hw_addr: HwAddr::empty(),
            conf: V4Configuration {
                ipv4: Ipv4Addr::new(0, 0, 0, 0),
                ipv4_mask: Ipv4Addr::new(0, 0, 0, 0),
                ipv4_gateway: Ipv4Addr::new(0, 0, 0, 0),
            },
            pv_device: None,
        };

        Interface(Arc::new(RwLock::new(inner)))
    }

    /// Get a weak reference over the interface
    pub fn downgrade(&self) -> InterfaceWeak {
        InterfaceWeak(Arc::downgrade(&self.0))
    }

    /// Lock the interface with shared read access
    ///
    /// For more info see spin::RwLock::read()
    pub fn read<'a>(&'a self) -> RwLockReadGuard<'a, InterfaceRaw> {
        self.0.read()
    }

    /// Lock the interface with exclusive write access
    ///
    /// For more info see spin::RwLock::write()
    pub fn write<'a>(&'a self) -> RwLockWriteGuard<'a, InterfaceRaw> {
        self.0.write()
    }
}

impl InterfaceWeak {
    /// Upgrade the weak reference to a real reference
    pub fn upgrade(&self) -> Option<Interface> {
        self.0.upgrade().map(|arc| Interface(arc))
    }
}

impl InterfaceRaw {
    #[inline]
    /// Returns a reference over the name of the interface
    pub fn name_ref(&self) -> &str {
        &self.name
    }

    #[inline]
    /// Returns a reference over the hardware of the interface
    pub fn hw_addr_ref(&self) -> &HwAddr {
        &self.hw_addr
    }

    #[inline]
    /// Returns a reference over the IPv4 configuration of the interface
    pub fn v4_configuration_ref(&self) -> &V4Configuration {
        &self.conf
    }

    #[inline]
    /// Returns a mutable reference over the name of the interface
    pub fn name_mut(&mut self) -> &mut String {
        &mut self.name
    }

    #[inline]
    /// Returns a mutable reference over the hardware of the interface
    pub fn hw_addr_mut(&mut self) -> &mut HwAddr {
        &mut self.hw_addr
    }

    #[inline]
    /// Returns a mutable reference over the IPv4 configuration of the interface
    pub fn v4_configuration_mut(&mut self) -> &mut V4Configuration {
        &mut self.conf
    }

    #[inline]
    #[doc(hidden)]
    pub fn pv_device_set(&mut self, pv: Box<HwInterface>) {
        self.pv_device = Some(pv);
    }

    #[inline]
    /// Refresh underlying driver
    pub fn refresh(&mut self) {
        self.pv_device.as_mut().unwrap().refresh();
    }
}
<commit_msg>net/intf: Fix some issues detected by clippy<commit_after>use boxed::Box;
use string::String;

use sync::{Arc, Weak};

use sync::spin::{RwLock, RwLockReadGuard, RwLockWriteGuard};

use net::defs::{HwAddr, Ipv4Addr, Device};

use hal::net::HwInterface;

// XXX: Should this be in net::defs ?
/// IPv4 configuration of an interface
pub struct V4Configuration {
    /// Main IPv4 address
    pub ipv4: Ipv4Addr,
    /// Subnet mask
    pub ipv4_mask: Ipv4Addr,
    /// Gateway IPv4 address
    pub ipv4_gateway: Ipv4Addr,
}

#[derive(Clone)]
/// A shareable network interface.
///
/// This is backed by an Arc and a RwLock so that accesses are safe and the
/// entity can be shared.
pub struct Interface(Arc<RwLock<InterfaceRaw>>);

unsafe impl Send for Interface {}

#[derive(Clone)]
/// A interface weak reference
pub struct InterfaceWeak(Weak<RwLock<InterfaceRaw>>);

unsafe impl Send for InterfaceWeak {}

/// The raw network interface
pub struct InterfaceRaw {
    /// Name of the interface
    name: String,
    /// Hardware address of the interface
    hw_addr: HwAddr,
    /// IPv4 configuration of the interface
    conf: V4Configuration,
    /// Underlying driver
    pv_device: Option<Box<HwInterface>>,
}

impl Interface {
    /// Creates a new network interface
    pub fn new() -> Self {
        let inner = InterfaceRaw {
            name: String::new(),
            hw_addr: HwAddr::empty(),
            conf: V4Configuration {
                ipv4: Ipv4Addr::new(0, 0, 0, 0),
                ipv4_mask: Ipv4Addr::new(0, 0, 0, 0),
                ipv4_gateway: Ipv4Addr::new(0, 0, 0, 0),
            },
            pv_device: None,
        };

        Interface(Arc::new(RwLock::new(inner)))
    }

    /// Get a weak reference over the interface
    pub fn downgrade(&self) -> InterfaceWeak {
        InterfaceWeak(Arc::downgrade(&self.0))
    }

    /// Lock the interface with shared read access
    ///
    /// For more info see spin::RwLock::read()
    pub fn read(&self) -> RwLockReadGuard<InterfaceRaw> {
        self.0.read()
    }

    /// Lock the interface with exclusive write access
    ///
    /// For more info see spin::RwLock::write()
    pub fn write(&self) -> RwLockWriteGuard<InterfaceRaw> {
        self.0.write()
    }
}

impl InterfaceWeak {
    /// Upgrade the weak reference to a real reference
    pub fn upgrade(&self) -> Option<Interface> {
        self.0.upgrade().map(Interface)
    }
}

impl InterfaceRaw {
    #[inline]
    /// Returns a reference over the name of the interface
    pub fn name_ref(&self) -> &str {
        &self.name
    }

    #[inline]
    /// Returns a reference over the hardware of the interface
    pub fn hw_addr_ref(&self) -> &HwAddr {
        &self.hw_addr
    }

    #[inline]
    /// Returns a reference over the IPv4 configuration of the interface
    pub fn v4_configuration_ref(&self) -> &V4Configuration {
        &self.conf
    }

    #[inline]
    /// Returns a mutable reference over the name of the interface
    pub fn name_mut(&mut self) -> &mut String {
        &mut self.name
    }

    #[inline]
    /// Returns a mutable reference over the hardware of the interface
    pub fn hw_addr_mut(&mut self) -> &mut HwAddr {
        &mut self.hw_addr
    }

    #[inline]
    /// Returns a mutable reference over the IPv4 configuration of the interface
    pub fn v4_configuration_mut(&mut self) -> &mut V4Configuration {
        &mut self.conf
    }

    #[inline]
    #[doc(hidden)]
    pub fn pv_device_set(&mut self, pv: Box<HwInterface>) {
        self.pv_device = Some(pv);
    }

    #[inline]
    /// Refresh underlying driver
    pub fn refresh(&mut self) {
        self.pv_device.as_mut().unwrap().refresh();
    }
}
<|endoftext|>


<commit_before>pub use self::emitter::EmitterResult as EventWriterResult;
pub use self::config::EmitterConfig;

use std::io::MemWriter;

use self::emitter::Emitter;
use self::events::XmlEvent;

mod emitter;
pub mod config;
pub mod events;

pub struct EventWriter<W> {
    sink: W,
    emitter: Emitter
}

impl<W: Writer> EventWriter<W> {
    #[inline]
    pub fn new(sink: W) -> EventWriter<W> {
        EventWriter::new_with_config(sink, EmitterConfig::new())
    }

    #[inline]
    pub fn new_with_config(sink: W, config: EmitterConfig) -> EventWriter<W> {
        EventWriter {
            sink: sink,
            emitter: Emitter::new(config)
        }
    }

    pub fn write(&mut self, event: XmlEvent) -> EventWriterResult<()> {
        match event {
            events::StartDocument { version, encoding, standalone } =>
                self.emitter.emit_start_document(&mut self.sink, version, encoding.unwrap_or("UTF-8"), standalone),
            events::ProcessingInstruction { name, data } =>
                self.emitter.emit_processing_instruction(&mut self.sink, name, data),
            events::StartElement { name, attributes, namespace } =>
                self.emitter.emit_start_element(&mut self.sink, name, attributes, namespace),
            events::EndElement { name } =>
                self.emitter.emit_end_element(&mut self.sink, name),
            events::Comment(content) =>
                self.emitter.emit_comment(&mut self.sink, content),
            events::CData(content) =>
                self.emitter.emit_cdata(&mut self.sink, content),
            events::Characters(content) =>
                self.emitter.emit_characters(&mut self.sink, content)
        }
    }
}

impl EventWriter<MemWriter> {
    #[inline]
    pub fn new_into_mem(sink: MemWriter) -> EventWriter<MemWriter> {
        EventWriter::new_into_mem_config(sink, EmitterConfig::new())
    }

    #[inline]
    pub fn new_into_mem_config(sink: MemWriter, config: EmitterConfig) -> EventWriter<MemWriter> {
        EventWriter::new_with_config(sink, config)
    }
}

#[cfg(test)]
mod tests {
    use std::io;
    use std::io::{File, BufferedReader, MemWriter};

    use reader::EventReader;
    use writer::EventWriter;

    #[inline]
    fn reader_by_ref<R: Reader>(r: &mut R) -> io::RefReader<R> { r.by_ref() }

    #[ignore]
    fn writer_test() {
        let mut f = File::open(&Path::new("data/sample_1.xml")).unwrap();
        let mut b = MemWriter::new();

        {
            let mut r = EventReader::new(BufferedReader::new(reader_by_ref(&mut f)));
            let mut w = EventWriter::new(b.by_ref());

            for e in r.events() {
                match e.as_writer_event() {
                    Some(e) => match w.write(e) {
                        Ok(_) => {},
                        Err(e) => fail!("Writer error: {}", e)
                    },
                    None => println!("Non-writer event: {}", e)
                }
            }
        }

        f.seek(0, io::SeekSet);
        let fs = f.read_to_string().unwrap();

        let bs = String::from_utf8(b.unwrap()).unwrap();

        assert_eq!(fs, bs)
    }
}
<commit_msg>Fixed tests<commit_after>pub use self::emitter::EmitterResult as EventWriterResult;
pub use self::config::EmitterConfig;

use std::io::MemWriter;

use self::emitter::Emitter;
use self::events::XmlEvent;

mod emitter;
pub mod config;
pub mod events;

pub struct EventWriter<W> {
    sink: W,
    emitter: Emitter
}

impl<W: Writer> EventWriter<W> {
    #[inline]
    pub fn new(sink: W) -> EventWriter<W> {
        EventWriter::new_with_config(sink, EmitterConfig::new())
    }

    #[inline]
    pub fn new_with_config(sink: W, config: EmitterConfig) -> EventWriter<W> {
        EventWriter {
            sink: sink,
            emitter: Emitter::new(config)
        }
    }

    pub fn write(&mut self, event: XmlEvent) -> EventWriterResult<()> {
        match event {
            events::StartDocument { version, encoding, standalone } =>
                self.emitter.emit_start_document(&mut self.sink, version, encoding.unwrap_or("UTF-8"), standalone),
            events::ProcessingInstruction { name, data } =>
                self.emitter.emit_processing_instruction(&mut self.sink, name, data),
            events::StartElement { name, attributes, namespace } =>
                self.emitter.emit_start_element(&mut self.sink, name, attributes, namespace),
            events::EndElement { name } =>
                self.emitter.emit_end_element(&mut self.sink, name),
            events::Comment(content) =>
                self.emitter.emit_comment(&mut self.sink, content),
            events::CData(content) =>
                self.emitter.emit_cdata(&mut self.sink, content),
            events::Characters(content) =>
                self.emitter.emit_characters(&mut self.sink, content)
        }
    }
}

impl EventWriter<MemWriter> {
    #[inline]
    pub fn new_into_mem(sink: MemWriter) -> EventWriter<MemWriter> {
        EventWriter::new_into_mem_config(sink, EmitterConfig::new())
    }

    #[inline]
    pub fn new_into_mem_config(sink: MemWriter, config: EmitterConfig) -> EventWriter<MemWriter> {
        EventWriter::new_with_config(sink, config)
    }
}

#[cfg(test)]
mod tests {
    use std::io;
    use std::io::{File, BufferedReader, MemWriter, AsRefReader, AsRefWriter};

    use reader::EventReader;
    use writer::EventWriter;

    #[inline]
    fn reader_by_ref<R: Reader>(r: &mut R) -> io::RefReader<R> { r.by_ref() }

    #[ignore]
    #[test]
    fn writer_test() {
        let mut f = File::open(&Path::new("data/sample_1.xml")).unwrap();
        let mut b = MemWriter::new();

        {
            let mut r = EventReader::new(BufferedReader::new(reader_by_ref(&mut f)));
            let mut w = EventWriter::new(b.by_ref());

            for e in r.events() {
                match e.as_writer_event() {
                    Some(e) => match w.write(e) {
                        Ok(_) => {},
                        Err(e) => panic!("Writer error: {}", e)
                    },
                    None => println!("Non-writer event: {}", e)
                }
            }
        }

        f.seek(0, io::SeekSet);
        let fs = f.read_to_string().unwrap();

        let bs = String::from_utf8(b.unwrap()).unwrap();

        assert_eq!(fs, bs)
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "aead-cipher-2022")]
use std::time::Duration;

use cfg_if::cfg_if;
#[cfg(feature = "aead-cipher-2022")]
use lru_time_cache::LruCache;

#[cfg(feature = "aead-cipher-2022")]
use crate::relay::tcprelay::proxy_stream::protocol::v2::SERVER_STREAM_TIMESTAMP_MAX_DIFF;
use crate::{config::ServerType, crypto::CipherKind};

#[cfg(feature = "security-replay-attack-detect")]
use self::ppbloom::PingPongBloom;

#[cfg(feature = "security-replay-attack-detect")]
mod ppbloom;

/// A Bloom Filter based protector against replay attach
pub struct ReplayProtector {
    // Check for duplicated IV/Nonce, for prevent replay attack
    // https://github.com/shadowsocks/shadowsocks-org/issues/44
    #[cfg(feature = "security-replay-attack-detect")]
    nonce_ppbloom: spin::Mutex<PingPongBloom>,

    // AEAD 2022 specific filter.
    // AEAD 2022 TCP protocol has a timestamp, which can already reject most of the replay requests,
    // so we only need to remember nonce that are in the valid time range
    #[cfg(feature = "aead-cipher-2022")]
    nonce_set: spin::Mutex<LruCache<Vec<u8>, ()>>,
}

impl ReplayProtector {
    /// Create a new ReplayProtector
    #[allow(unused_variables)]
    pub fn new(config_type: ServerType) -> ReplayProtector {
        ReplayProtector {
            #[cfg(feature = "security-replay-attack-detect")]
            nonce_ppbloom: spin::Mutex::new(PingPongBloom::new(config_type)),
            #[cfg(feature = "aead-cipher-2022")]
            nonce_set: spin::Mutex::new(LruCache::with_expiry_duration(Duration::from_secs(
                SERVER_STREAM_TIMESTAMP_MAX_DIFF * 2,
            ))),
        }
    }

    /// Check if nonce exist or not
    #[inline(always)]
    pub fn check_nonce_and_set(&self, method: CipherKind, nonce: &[u8]) -> bool {
        // Plain cipher doesn't have a nonce
        // Always treated as non-duplicated
        if nonce.is_empty() {
            return false;
        }

        #[cfg(feature = "aead-cipher-2022")]
        if method.is_aead_2022() {
            let mut set = self.nonce_set.lock();
            if set.get(nonce).is_some() {
                return true;
            }
            set.insert(nonce.to_vec(), ());
            return false;
        }

        cfg_if! {
            if #[cfg(feature = "security-replay-attack-detect")] {
                let mut ppbloom = self.nonce_ppbloom.lock();
                ppbloom.check_and_set(nonce)
            } else {
                false
            }
        }
    }
}
<commit_msg>fixed warning<commit_after>#[cfg(feature = "aead-cipher-2022")]
use std::time::Duration;

use cfg_if::cfg_if;
#[cfg(feature = "aead-cipher-2022")]
use lru_time_cache::LruCache;

#[cfg(feature = "aead-cipher-2022")]
use crate::relay::tcprelay::proxy_stream::protocol::v2::SERVER_STREAM_TIMESTAMP_MAX_DIFF;
use crate::{config::ServerType, crypto::CipherKind};

#[cfg(feature = "security-replay-attack-detect")]
use self::ppbloom::PingPongBloom;

#[cfg(feature = "security-replay-attack-detect")]
mod ppbloom;

/// A Bloom Filter based protector against replay attach
pub struct ReplayProtector {
    // Check for duplicated IV/Nonce, for prevent replay attack
    // https://github.com/shadowsocks/shadowsocks-org/issues/44
    #[cfg(feature = "security-replay-attack-detect")]
    nonce_ppbloom: spin::Mutex<PingPongBloom>,

    // AEAD 2022 specific filter.
    // AEAD 2022 TCP protocol has a timestamp, which can already reject most of the replay requests,
    // so we only need to remember nonce that are in the valid time range
    #[cfg(feature = "aead-cipher-2022")]
    nonce_set: spin::Mutex<LruCache<Vec<u8>, ()>>,
}

impl ReplayProtector {
    /// Create a new ReplayProtector
    #[allow(unused_variables)]
    pub fn new(config_type: ServerType) -> ReplayProtector {
        ReplayProtector {
            #[cfg(feature = "security-replay-attack-detect")]
            nonce_ppbloom: spin::Mutex::new(PingPongBloom::new(config_type)),
            #[cfg(feature = "aead-cipher-2022")]
            nonce_set: spin::Mutex::new(LruCache::with_expiry_duration(Duration::from_secs(
                SERVER_STREAM_TIMESTAMP_MAX_DIFF * 2,
            ))),
        }
    }

    /// Check if nonce exist or not
    #[inline(always)]
    pub fn check_nonce_and_set(&self, method: CipherKind, nonce: &[u8]) -> bool {
        // Plain cipher doesn't have a nonce
        // Always treated as non-duplicated
        if nonce.is_empty() {
            return false;
        }

        #[cfg(feature = "aead-cipher-2022")]
        if method.is_aead_2022() {
            let mut set = self.nonce_set.lock();
            if set.get(nonce).is_some() {
                return true;
            }
            set.insert(nonce.to_vec(), ());
            return false;
        }

        let _ = method;

        cfg_if! {
            if #[cfg(feature = "security-replay-attack-detect")] {
                let mut ppbloom = self.nonce_ppbloom.lock();
                ppbloom.check_and_set(nonce)
            } else {
                false
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::iter::{Enumerate, ExactSizeIterator};

pub(crate) struct EnumerateAndAdjust<I> {
    enumerate: Enumerate<I>,
    gap_pos: usize,
    gap_len: usize,
}

impl<I> Iterator for EnumerateAndAdjust<I>
where
    I: Iterator,
{
    type Item = (usize, <I as Iterator>::Item);

    fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
        self.enumerate
            .next()
            .map(|(i, elem)| (if i < self.gap_pos { i } else { i + self.gap_len }, elem))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.enumerate.size_hint()
    }
}

pub(crate) trait EnumerateAndAdjustIterator {
    fn enumerate_and_adjust(
        self,
        expected_len: usize,
        gap_pos: Option<usize>,
    ) -> EnumerateAndAdjust<Self>
    where
        Self: Sized;
}

impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
    fn enumerate_and_adjust(
        self,
        expected_len: usize,
        gap_pos: Option<usize>,
    ) -> EnumerateAndAdjust<Self>
    where
        Self: Sized,
    {
        let actual_len = self.len();
        EnumerateAndAdjust {
            enumerate: self.enumerate(),
            gap_pos: gap_pos.unwrap_or(expected_len),
            gap_len: expected_len - actual_len,
        }
    }
}
<commit_msg>minor: doc comment pat_util<commit_after>//! Pattern untilities.
//!
//! Originates from `rustc_hir::pat_util`

use std::iter::{Enumerate, ExactSizeIterator};

pub(crate) struct EnumerateAndAdjust<I> {
    enumerate: Enumerate<I>,
    gap_pos: usize,
    gap_len: usize,
}

impl<I> Iterator for EnumerateAndAdjust<I>
where
    I: Iterator,
{
    type Item = (usize, <I as Iterator>::Item);

    fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
        self.enumerate
            .next()
            .map(|(i, elem)| (if i < self.gap_pos { i } else { i + self.gap_len }, elem))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.enumerate.size_hint()
    }
}

pub(crate) trait EnumerateAndAdjustIterator {
    fn enumerate_and_adjust(
        self,
        expected_len: usize,
        gap_pos: Option<usize>,
    ) -> EnumerateAndAdjust<Self>
    where
        Self: Sized;
}

impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
    fn enumerate_and_adjust(
        self,
        expected_len: usize,
        gap_pos: Option<usize>,
    ) -> EnumerateAndAdjust<Self>
    where
        Self: Sized,
    {
        let actual_len = self.len();
        EnumerateAndAdjust {
            enumerate: self.enumerate(),
            gap_pos: gap_pos.unwrap_or(expected_len),
            gap_len: expected_len - actual_len,
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Parse and ignore GNU find optimization levels (-On)<commit_after><|endoftext|>


<commit_before><commit_msg>rustfmt<commit_after><|endoftext|>