<commit_before>extern crate active_validators;
extern crate bytes;
extern crate hashing;
extern crate types;

use active_validators::validator_is_active;
use bytes::{BufMut, BytesMut};
use hashing::canonical_hash;
use std::cmp::max;
use types::{Hash256, ValidatorRecord, ValidatorStatus};

pub enum UpdateValidatorSetError {
    ArithmeticOverflow,
}

const VALIDATOR_FLAG_ENTRY: u8 = 0;
const VALIDATOR_FLAG_EXIT: u8 = 1;

pub fn update_validator_set(
    validators: &mut Vec<ValidatorRecord>,
    hash_chain: Hash256,
    present_slot: u64,
    deposit_size_gwei: u64,
    max_validator_churn_quotient: u64,
) -> Result<(), UpdateValidatorSetError> {
    /*
     * Total balance of all active validators.
     *
     * Return an error if an overflow occurs.
     */
    let total_balance = {
        let mut bal: u64 = 0;
        for v in validators.iter() {
            if validator_is_active(&v) {
                bal = bal
                    .checked_add(v.balance)
                    .ok_or(UpdateValidatorSetError::ArithmeticOverflow)?;
            }
        }
        bal
    };

    /*
     * Note: this is not the maximum allowable change, it can actually be higher.
     */
    let max_allowable_change = {
        let double_deposit_size = deposit_size_gwei
            .checked_mul(2)
            .ok_or(UpdateValidatorSetError::ArithmeticOverflow)?;
        max(
            double_deposit_size,
            total_balance / max_validator_churn_quotient,
        )
    };

    let mut hasher = ValidatorChangeHashChain {
        bytes: hash_chain.to_vec(),
    };
    let mut total_changed: u64 = 0;
    for (i, v) in validators.iter_mut().enumerate() {
        match v.status {
            /*
             * Validator is pending activiation.
             */
            ValidatorStatus::PendingActivation => {
                let new_total_changed = total_changed
                    .checked_add(deposit_size_gwei)
                    .ok_or(UpdateValidatorSetError::ArithmeticOverflow)?;
                /*
                 * If entering this validator would not exceed the max balance delta,
                 * activate the validator.
                 */
                if new_total_changed <= max_allowable_change {
                    v.status = ValidatorStatus::Active;
                    hasher.extend(i, &v.pubkey.as_bytes(), VALIDATOR_FLAG_ENTRY);
                    total_changed = new_total_changed;
                } else {
                    // Entering the validator would exceed the balance delta.
                    break;
                }
            }
            /*
             * Validator is pending exit.
             */
            ValidatorStatus::PendingExit => {
                let new_total_changed = total_changed
                    .checked_add(v.balance)
                    .ok_or(UpdateValidatorSetError::ArithmeticOverflow)?;
                /*
                 * If exiting this validator would not exceed the max balance delta,
                 * exit the validator
                 */
                if new_total_changed <= max_allowable_change {
                    v.status = ValidatorStatus::PendingWithdraw;
                    v.exit_slot = present_slot;
                    hasher.extend(i, &v.pubkey.as_bytes(), VALIDATOR_FLAG_EXIT);
                    total_changed = new_total_changed;
                } else {
                    // Exiting the validator would exceed the balance delta.
                    break;
                }
            }
            _ => (),
        };
        if total_changed >= max_allowable_change {
            break;
        }
    }
    Ok(())
}

pub struct ValidatorChangeHashChain {
    bytes: Vec<u8>,
}

impl ValidatorChangeHashChain {
    pub fn extend(&mut self, index: usize, pubkey: &Vec<u8>, flag: u8) {
        let mut message = self.bytes.clone();
        message.append(&mut serialize_validator_change_record(index, pubkey, flag));
        self.bytes = canonical_hash(&message);
    }
}

fn serialize_validator_change_record(index: usize, pubkey: &Vec<u8>, flag: u8) -> Vec<u8> {
    let mut buf = BytesMut::with_capacity(68);
    buf.put_u8(flag);
    let index_bytes = {
        let mut buf = BytesMut::with_capacity(8);
        buf.put_u64_be(index as u64);
        buf.take()[8 - 3..8].to_vec()
    };
    buf.put(index_bytes);
    buf.put(pubkey);
    buf.take().to_vec()
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}
<commit_msg>fix build by patching up import and usage<commit_after>extern crate active_validators;
extern crate bytes;
extern crate hashing;
extern crate types;

use bytes::{BufMut, BytesMut};
use hashing::canonical_hash;
use std::cmp::max;
use types::{Hash256, ValidatorRecord, ValidatorStatus};

pub enum UpdateValidatorSetError {
    ArithmeticOverflow,
}

const VALIDATOR_FLAG_ENTRY: u8 = 0;
const VALIDATOR_FLAG_EXIT: u8 = 1;

pub fn update_validator_set(
    validators: &mut Vec<ValidatorRecord>,
    hash_chain: Hash256,
    present_slot: u64,
    deposit_size_gwei: u64,
    max_validator_churn_quotient: u64,
) -> Result<(), UpdateValidatorSetError> {
    /*
     * Total balance of all active validators.
     *
     * Return an error if an overflow occurs.
     */
    let total_balance = {
        let mut bal: u64 = 0;
        for v in validators.iter() {
            if v.status_is(ValidatorStatus::Active) {
                bal = bal
                    .checked_add(v.balance)
                    .ok_or(UpdateValidatorSetError::ArithmeticOverflow)?;
            }
        }
        bal
    };

    /*
     * Note: this is not the maximum allowable change, it can actually be higher.
     */
    let max_allowable_change = {
        let double_deposit_size = deposit_size_gwei
            .checked_mul(2)
            .ok_or(UpdateValidatorSetError::ArithmeticOverflow)?;
        max(
            double_deposit_size,
            total_balance / max_validator_churn_quotient,
        )
    };

    let mut hasher = ValidatorChangeHashChain {
        bytes: hash_chain.to_vec(),
    };
    let mut total_changed: u64 = 0;
    for (i, v) in validators.iter_mut().enumerate() {
        match v.status {
            /*
             * Validator is pending activiation.
             */
            ValidatorStatus::PendingActivation => {
                let new_total_changed = total_changed
                    .checked_add(deposit_size_gwei)
                    .ok_or(UpdateValidatorSetError::ArithmeticOverflow)?;
                /*
                 * If entering this validator would not exceed the max balance delta,
                 * activate the validator.
                 */
                if new_total_changed <= max_allowable_change {
                    v.status = ValidatorStatus::Active;
                    hasher.extend(i, &v.pubkey.as_bytes(), VALIDATOR_FLAG_ENTRY);
                    total_changed = new_total_changed;
                } else {
                    // Entering the validator would exceed the balance delta.
                    break;
                }
            }
            /*
             * Validator is pending exit.
             */
            ValidatorStatus::PendingExit => {
                let new_total_changed = total_changed
                    .checked_add(v.balance)
                    .ok_or(UpdateValidatorSetError::ArithmeticOverflow)?;
                /*
                 * If exiting this validator would not exceed the max balance delta,
                 * exit the validator
                 */
                if new_total_changed <= max_allowable_change {
                    v.status = ValidatorStatus::PendingWithdraw;
                    v.exit_slot = present_slot;
                    hasher.extend(i, &v.pubkey.as_bytes(), VALIDATOR_FLAG_EXIT);
                    total_changed = new_total_changed;
                } else {
                    // Exiting the validator would exceed the balance delta.
                    break;
                }
            }
            _ => (),
        };
        if total_changed >= max_allowable_change {
            break;
        }
    }
    Ok(())
}

pub struct ValidatorChangeHashChain {
    bytes: Vec<u8>,
}

impl ValidatorChangeHashChain {
    pub fn extend(&mut self, index: usize, pubkey: &Vec<u8>, flag: u8) {
        let mut message = self.bytes.clone();
        message.append(&mut serialize_validator_change_record(index, pubkey, flag));
        self.bytes = canonical_hash(&message);
    }
}

fn serialize_validator_change_record(index: usize, pubkey: &Vec<u8>, flag: u8) -> Vec<u8> {
    let mut buf = BytesMut::with_capacity(68);
    buf.put_u8(flag);
    let index_bytes = {
        let mut buf = BytesMut::with_capacity(8);
        buf.put_u64_be(index as u64);
        buf.take()[8 - 3..8].to_vec()
    };
    buf.put(index_bytes);
    buf.put(pubkey);
    buf.take().to_vec()
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}
<|endoftext|>


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

use core::prelude::*;

use boxed::Box;
use cmp;
use io::{self, SeekFrom, Read, Write, Seek, BufRead};
use mem;
use slice;
use vec::Vec;

// =============================================================================
// Forwarding implementations

impl<'a, R: Read + ?Sized> Read for &'a mut R {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) }
}
impl<'a, W: Write + ?Sized> Write for &'a mut W {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
    fn flush(&mut self) -> io::Result<()> { (**self).flush() }
}
impl<'a, S: Seek + ?Sized> Seek for &'a mut S {
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
}
impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
    fn consume(&mut self, amt: usize) { (**self).consume(amt) }
}

impl<R: Read + ?Sized> Read for Box<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) }
}
impl<W: Write + ?Sized> Write for Box<W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
    fn flush(&mut self) -> io::Result<()> { (**self).flush() }
}
impl<S: Seek + ?Sized> Seek for Box<S> {
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
}
impl<B: BufRead + ?Sized> BufRead for Box<B> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
    fn consume(&mut self, amt: usize) { (**self).consume(amt) }
}

// =============================================================================
// In-memory buffer implementations

impl<'a> Read for &'a [u8] {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let amt = cmp::min(buf.len(), self.len());
        let (a, b) = self.split_at(amt);
        slice::bytes::copy_memory(buf, a);
        *self = b;
        Ok(amt)
    }
}

impl<'a> BufRead for &'a [u8] {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) }
    fn consume(&mut self, amt: usize) { *self = &self[amt..]; }
}

impl<'a> Write for &'a mut [u8] {
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        let amt = cmp::min(data.len(), self.len());
        let (a, b) = mem::replace(self, &mut []).split_at_mut(amt);
        slice::bytes::copy_memory(a, &data[..amt]);
        *self = b;
        Ok(amt)
    }
    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}

impl Write for Vec<u8> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.push_all(buf);
        Ok(buf.len())
    }
    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
<commit_msg>Rollup merge of #22428 - erickt:io-wrappers, r=aturon<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::prelude::*;

use boxed::Box;
use cmp;
use io::{self, SeekFrom, Read, Write, Seek, BufRead, Error, ErrorKind};
use fmt;
use mem;
use slice;
use string::String;
use vec::Vec;

// =============================================================================
// Forwarding implementations

impl<'a, R: Read + ?Sized> Read for &'a mut R {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> { (**self).read_to_end(buf) }

    fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
        (**self).read_to_string(buf)
    }
}
impl<'a, W: Write + ?Sized> Write for &'a mut W {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { (**self).write_all(buf) }

    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { (**self).write_fmt(fmt) }

    fn flush(&mut self) -> io::Result<()> { (**self).flush() }
}
impl<'a, S: Seek + ?Sized> Seek for &'a mut S {
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
}
impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }

    fn consume(&mut self, amt: usize) { (**self).consume(amt) }

    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<()> {
        (**self).read_until(byte, buf)
    }

    fn read_line(&mut self, buf: &mut String) -> io::Result<()> { (**self).read_line(buf) }
}

impl<R: Read + ?Sized> Read for Box<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) }
}
impl<W: Write + ?Sized> Write for Box<W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
    fn flush(&mut self) -> io::Result<()> { (**self).flush() }
}
impl<S: Seek + ?Sized> Seek for Box<S> {
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
}
impl<B: BufRead + ?Sized> BufRead for Box<B> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
    fn consume(&mut self, amt: usize) { (**self).consume(amt) }
}

// =============================================================================
// In-memory buffer implementations

impl<'a> Read for &'a [u8] {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let amt = cmp::min(buf.len(), self.len());
        let (a, b) = self.split_at(amt);
        slice::bytes::copy_memory(buf, a);
        *self = b;
        Ok(amt)
    }
}

impl<'a> BufRead for &'a [u8] {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) }
    fn consume(&mut self, amt: usize) { *self = &self[amt..]; }
}

impl<'a> Write for &'a mut [u8] {
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        let amt = cmp::min(data.len(), self.len());
        let (a, b) = mem::replace(self, &mut []).split_at_mut(amt);
        slice::bytes::copy_memory(a, &data[..amt]);
        *self = b;
        Ok(amt)
    }

    fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
        if try!(self.write(data)) == data.len() {
            Ok(())
        } else {
            Err(Error::new(ErrorKind::WriteZero, "failed to write whole buffer", None))
        }
    }

    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}

impl Write for Vec<u8> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.push_all(buf);
        Ok(buf.len())
    }

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        try!(self.write(buf));
        Ok(())
    }

    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
<|endoftext|>


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

//! Temporal quantification.

#![stable(feature = "time", since = "1.3.0")]

use error::Error;
use fmt;
use ops::{Add, Sub};
use sys::time;

#[stable(feature = "time", since = "1.3.0")]
pub use self::duration::Duration;

mod duration;

/// A measurement of a monotonically increasing clock which is suitable for
/// measuring the amount of time that an operation takes.
///
/// Instants are guaranteed always be greater than any previously measured
/// instant when created, and are often useful for tasks such as measuring
/// benchmarks or timing how long an operation takes.
///
/// Note, however, that instants are not guaranteed to be **steady**.  In other
/// words each tick of the underlying clock may not be the same length (e.g.
/// some seconds may be longer than others). An instant may jump forwards or
/// experience time dilation (slow down or speed up), but it will never go
/// backwards.
///
/// Instants are opaque types that can only be compared to one another. There is
/// no method to get "the number of seconds" from an instant but instead it only
/// allow learning the duration between two instants (or comparing two
/// instants).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
pub struct Instant(time::Instant);

/// A measurement of the system clock appropriate for timestamps such as those
/// on files on the filesystem.
///
/// Distinct from the `Instant` type, this time measurement **is not
/// monotonic**. This means that you can save a file to the file system, then
/// save another file to the file system, **and the second file has a
/// `SystemTime` measurement earlier than the second**. In other words, an
/// operation that happens after another operation in real time may have an
/// earlier `SystemTime`!
///
/// Consequently, comparing two `SystemTime` instances to learn about the
/// duration between them returns a `Result` instead of an infallible `Duration`
/// to indicate that this sort of time drift may happen and needs to be handled.
///
/// Although a `SystemTime` cannot be directly inspected, the `UNIX_EPOCH`
/// constant is provided in this module as an anchor in time to learn
/// information about a `SystemTime`. By calculating the duration from this
/// fixed point in time a `SystemTime` can be converted to a human-readable time
/// or perhaps some other string representation.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
pub struct SystemTime(time::SystemTime);

/// An error returned from the `duration_from_earlier` method on `SystemTime`,
/// used to learn about why how far in the opposite direction a timestamp lies.
#[derive(Clone, Debug)]
#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
pub struct SystemTimeError(Duration);

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl Instant {
    /// Returns an instant corresponding to "now".
    pub fn now() -> Instant {
        Instant(time::Instant::now())
    }

    /// Returns the amount of time elapsed from another instant to this one.
    ///
    /// # Panics
    ///
    /// This function will panic if `earlier` is later than `self`, which should
    /// only be possible if `earlier` was created after `self`. Because
    /// `Instant` is monotonic, the only time that this should happen should be
    /// a bug.
    pub fn duration_from_earlier(&self, earlier: Instant) -> Duration {
        self.0.sub_instant(&earlier.0)
    }

    /// Returns the amount of time elapsed since this instant was created.
    ///
    /// # Panics
    ///
    /// This function may panic if the current time is earlier than this instant
    /// which can happen if an `Instant` is produced synthetically.
    pub fn elapsed(&self) -> Duration {
        Instant::now().duration_from_earlier(*self)
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl Add<Duration> for Instant {
    type Output = Instant;

    fn add(self, other: Duration) -> Instant {
        Instant(self.0.add_duration(&other))
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl Sub<Duration> for Instant {
    type Output = Instant;

    fn sub(self, other: Duration) -> Instant {
        Instant(self.0.sub_duration(&other))
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl fmt::Debug for Instant {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl SystemTime {
    /// Returns the system time corresponding to "now".
    pub fn now() -> SystemTime {
        SystemTime(time::SystemTime::now())
    }

    /// Returns the amount of time elapsed from an earlier point in time.
    ///
    /// This function may fail because measurements taken earlier are not
    /// guaranteed to always be before later measurements (due to anomalies such
    /// as the system clock being adjusted either forwards or backwards).
    ///
    /// If successful, `Ok(duration)` is returned where the duration represents
    /// the amount of time elapsed from the specified measurement to this one.
    ///
    /// Returns an `Err` if `earlier` is later than `self`, and the error
    /// contains how far from `self` the time is.
    pub fn duration_from_earlier(&self, earlier: SystemTime)
                                 -> Result<Duration, SystemTimeError> {
        self.0.sub_time(&earlier.0).map_err(SystemTimeError)
    }

    /// Returns the amount of time elapsed since this system time was created.
    ///
    /// This function may fail as the underlying system clock is susceptible to
    /// drift and updates (e.g. the system clock could go backwards), so this
    /// function may not always succeed. If successful, `Ok(duration)` is
    /// returned where the duration represents the amount of time elapsed from
    /// this time measurement to the current time.
    ///
    /// Returns an `Err` if `self` is later than the current system time, and
    /// the error contains how far from the current system time `self` is.
    pub fn elapsed(&self) -> Result<Duration, SystemTimeError> {
        SystemTime::now().duration_from_earlier(*self)
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl Add<Duration> for SystemTime {
    type Output = SystemTime;

    fn add(self, dur: Duration) -> SystemTime {
        SystemTime(self.0.add_duration(&dur))
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl Sub<Duration> for SystemTime {
    type Output = SystemTime;

    fn sub(self, dur: Duration) -> SystemTime {
        SystemTime(self.0.sub_duration(&dur))
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl fmt::Debug for SystemTime {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// An anchor in time which can be used to create new `SystemTime` instances or
/// learn about where in time a `SystemTime` lies.
///
/// This constant is defined to be "1970-01-01 00:00:00 UTC" on all systems with
/// respect to the system clock. Using `duration_from_earlier` on an existing
/// `SystemTime` instance can tell how far away from this point in time a
/// measurement lies, and using `UNIX_EPOCH + duration` can be used to create a
/// `SystemTime` instance to represent another fixed point in time.
#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
pub const UNIX_EPOCH: SystemTime = SystemTime(time::UNIX_EPOCH);

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl SystemTimeError {
    /// Returns the positive duration which represents how far forward the
    /// second system time was from the first.
    ///
    /// A `SystemTimeError` is returned from the `duration_from_earlier`
    /// operation whenever the second duration, `earlier`, actually represents a
    /// point later in time than the `self` of the method call. This function
    /// will extract and return the amount of time later `earlier` actually is.
    pub fn duration(&self) -> Duration {
        self.0
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl Error for SystemTimeError {
    fn description(&self) -> &str { "other time was not earlier than self" }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl fmt::Display for SystemTimeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "second time provided was later than self")
    }
}

#[cfg(test)]
mod tests {
    use super::{Instant, SystemTime, Duration, UNIX_EPOCH};

    #[test]
    fn instant_monotonic() {
        let a = Instant::now();
        let b = Instant::now();
        assert!(b >= a);
    }

    #[test]
    fn instant_elapsed() {
        let a = Instant::now();
        a.elapsed();
    }

    #[test]
    fn instant_math() {
        let a = Instant::now();
        let b = Instant::now();
        let dur = b.duration_from_earlier(a);
        assert_eq!(b - dur, a);
        assert_eq!(a + dur, b);

        let second = Duration::new(1, 0);
        assert_eq!(a - second + second, a);
    }

    #[test]
    #[should_panic]
    fn instant_duration_panic() {
        let a = Instant::now();
        (a - Duration::new(1, 0)).duration_from_earlier(a);
    }

    #[test]
    fn system_time_math() {
        let a = SystemTime::now();
        let b = SystemTime::now();
        match b.duration_from_earlier(a) {
            Ok(dur) if dur == Duration::new(0, 0) => {
                assert_eq!(a, b);
            }
            Ok(dur) => {
                assert!(b > a);
                assert_eq!(b - dur, a);
                assert_eq!(a + dur, b);
            }
            Err(dur) => {
                let dur = dur.duration();
                assert!(a > b);
                assert_eq!(b + dur, a);
                assert_eq!(b - dur, a);
            }
        }

        let second = Duration::new(1, 0);
        assert_eq!(a.duration_from_earlier(a - second).unwrap(), second);
        assert_eq!(a.duration_from_earlier(a + second).unwrap_err().duration(),
                   second);

        assert_eq!(a - second + second, a);

        let eighty_years = second * 60 * 60 * 24 * 365 * 80;
        assert_eq!(a - eighty_years + eighty_years, a);
        assert_eq!(a - (eighty_years * 10) + (eighty_years * 10), a);
    }

    #[test]
    fn system_time_elapsed() {
        let a = SystemTime::now();
        drop(a.elapsed());
    }

    #[test]
    fn since_epoch() {
        let ts = SystemTime::now();
        let a = ts.duration_from_earlier(UNIX_EPOCH).unwrap();
        let b = ts.duration_from_earlier(UNIX_EPOCH - Duration::new(1, 0)).unwrap();
        assert!(b > a);
        assert_eq!(b - a, Duration::new(1, 0));

        // let's assume that we're all running computers later than 2000
        let thirty_years = Duration::new(1, 0) * 60 * 60 * 24 * 365 * 30;
        assert!(a > thirty_years);

        // let's assume that we're all running computers earlier than 2090.
        // Should give us ~70 years to fix this!
        let hundred_twenty_years = thirty_years * 4;
        assert!(a < hundred_twenty_years);
    }
}
<commit_msg>std: Tweak tests of std::time<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Temporal quantification.

#![stable(feature = "time", since = "1.3.0")]

use error::Error;
use fmt;
use ops::{Add, Sub};
use sys::time;

#[stable(feature = "time", since = "1.3.0")]
pub use self::duration::Duration;

mod duration;

/// A measurement of a monotonically increasing clock which is suitable for
/// measuring the amount of time that an operation takes.
///
/// Instants are guaranteed always be greater than any previously measured
/// instant when created, and are often useful for tasks such as measuring
/// benchmarks or timing how long an operation takes.
///
/// Note, however, that instants are not guaranteed to be **steady**.  In other
/// words each tick of the underlying clock may not be the same length (e.g.
/// some seconds may be longer than others). An instant may jump forwards or
/// experience time dilation (slow down or speed up), but it will never go
/// backwards.
///
/// Instants are opaque types that can only be compared to one another. There is
/// no method to get "the number of seconds" from an instant but instead it only
/// allow learning the duration between two instants (or comparing two
/// instants).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
pub struct Instant(time::Instant);

/// A measurement of the system clock appropriate for timestamps such as those
/// on files on the filesystem.
///
/// Distinct from the `Instant` type, this time measurement **is not
/// monotonic**. This means that you can save a file to the file system, then
/// save another file to the file system, **and the second file has a
/// `SystemTime` measurement earlier than the second**. In other words, an
/// operation that happens after another operation in real time may have an
/// earlier `SystemTime`!
///
/// Consequently, comparing two `SystemTime` instances to learn about the
/// duration between them returns a `Result` instead of an infallible `Duration`
/// to indicate that this sort of time drift may happen and needs to be handled.
///
/// Although a `SystemTime` cannot be directly inspected, the `UNIX_EPOCH`
/// constant is provided in this module as an anchor in time to learn
/// information about a `SystemTime`. By calculating the duration from this
/// fixed point in time a `SystemTime` can be converted to a human-readable time
/// or perhaps some other string representation.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
pub struct SystemTime(time::SystemTime);

/// An error returned from the `duration_from_earlier` method on `SystemTime`,
/// used to learn about why how far in the opposite direction a timestamp lies.
#[derive(Clone, Debug)]
#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
pub struct SystemTimeError(Duration);

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl Instant {
    /// Returns an instant corresponding to "now".
    pub fn now() -> Instant {
        Instant(time::Instant::now())
    }

    /// Returns the amount of time elapsed from another instant to this one.
    ///
    /// # Panics
    ///
    /// This function will panic if `earlier` is later than `self`, which should
    /// only be possible if `earlier` was created after `self`. Because
    /// `Instant` is monotonic, the only time that this should happen should be
    /// a bug.
    pub fn duration_from_earlier(&self, earlier: Instant) -> Duration {
        self.0.sub_instant(&earlier.0)
    }

    /// Returns the amount of time elapsed since this instant was created.
    ///
    /// # Panics
    ///
    /// This function may panic if the current time is earlier than this instant
    /// which can happen if an `Instant` is produced synthetically.
    pub fn elapsed(&self) -> Duration {
        Instant::now().duration_from_earlier(*self)
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl Add<Duration> for Instant {
    type Output = Instant;

    fn add(self, other: Duration) -> Instant {
        Instant(self.0.add_duration(&other))
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl Sub<Duration> for Instant {
    type Output = Instant;

    fn sub(self, other: Duration) -> Instant {
        Instant(self.0.sub_duration(&other))
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl fmt::Debug for Instant {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl SystemTime {
    /// Returns the system time corresponding to "now".
    pub fn now() -> SystemTime {
        SystemTime(time::SystemTime::now())
    }

    /// Returns the amount of time elapsed from an earlier point in time.
    ///
    /// This function may fail because measurements taken earlier are not
    /// guaranteed to always be before later measurements (due to anomalies such
    /// as the system clock being adjusted either forwards or backwards).
    ///
    /// If successful, `Ok(duration)` is returned where the duration represents
    /// the amount of time elapsed from the specified measurement to this one.
    ///
    /// Returns an `Err` if `earlier` is later than `self`, and the error
    /// contains how far from `self` the time is.
    pub fn duration_from_earlier(&self, earlier: SystemTime)
                                 -> Result<Duration, SystemTimeError> {
        self.0.sub_time(&earlier.0).map_err(SystemTimeError)
    }

    /// Returns the amount of time elapsed since this system time was created.
    ///
    /// This function may fail as the underlying system clock is susceptible to
    /// drift and updates (e.g. the system clock could go backwards), so this
    /// function may not always succeed. If successful, `Ok(duration)` is
    /// returned where the duration represents the amount of time elapsed from
    /// this time measurement to the current time.
    ///
    /// Returns an `Err` if `self` is later than the current system time, and
    /// the error contains how far from the current system time `self` is.
    pub fn elapsed(&self) -> Result<Duration, SystemTimeError> {
        SystemTime::now().duration_from_earlier(*self)
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl Add<Duration> for SystemTime {
    type Output = SystemTime;

    fn add(self, dur: Duration) -> SystemTime {
        SystemTime(self.0.add_duration(&dur))
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl Sub<Duration> for SystemTime {
    type Output = SystemTime;

    fn sub(self, dur: Duration) -> SystemTime {
        SystemTime(self.0.sub_duration(&dur))
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl fmt::Debug for SystemTime {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// An anchor in time which can be used to create new `SystemTime` instances or
/// learn about where in time a `SystemTime` lies.
///
/// This constant is defined to be "1970-01-01 00:00:00 UTC" on all systems with
/// respect to the system clock. Using `duration_from_earlier` on an existing
/// `SystemTime` instance can tell how far away from this point in time a
/// measurement lies, and using `UNIX_EPOCH + duration` can be used to create a
/// `SystemTime` instance to represent another fixed point in time.
#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
pub const UNIX_EPOCH: SystemTime = SystemTime(time::UNIX_EPOCH);

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl SystemTimeError {
    /// Returns the positive duration which represents how far forward the
    /// second system time was from the first.
    ///
    /// A `SystemTimeError` is returned from the `duration_from_earlier`
    /// operation whenever the second duration, `earlier`, actually represents a
    /// point later in time than the `self` of the method call. This function
    /// will extract and return the amount of time later `earlier` actually is.
    pub fn duration(&self) -> Duration {
        self.0
    }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl Error for SystemTimeError {
    fn description(&self) -> &str { "other time was not earlier than self" }
}

#[unstable(feature = "time2", reason = "recently added", issue = "29866")]
impl fmt::Display for SystemTimeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "second time provided was later than self")
    }
}

#[cfg(test)]
mod tests {
    use super::{Instant, SystemTime, Duration, UNIX_EPOCH};

    macro_rules! assert_almost_eq {
        ($a:expr, $b:expr) => ({
            let (a, b) = ($a, $b);
            if a != b {
                let (a, b) = if a > b {(a, b)} else {(b, a)};
                assert!(a - Duration::new(0, 1) <= b);
            }
        })
    }

    #[test]
    fn instant_monotonic() {
        let a = Instant::now();
        let b = Instant::now();
        assert!(b >= a);
    }

    #[test]
    fn instant_elapsed() {
        let a = Instant::now();
        a.elapsed();
    }

    #[test]
    fn instant_math() {
        let a = Instant::now();
        let b = Instant::now();
        let dur = b.duration_from_earlier(a);
        assert_almost_eq!(b - dur, a);
        assert_almost_eq!(a + dur, b);

        let second = Duration::new(1, 0);
        assert_almost_eq!(a - second + second, a);
    }

    #[test]
    #[should_panic]
    fn instant_duration_panic() {
        let a = Instant::now();
        (a - Duration::new(1, 0)).duration_from_earlier(a);
    }

    #[test]
    fn system_time_math() {
        let a = SystemTime::now();
        let b = SystemTime::now();
        match b.duration_from_earlier(a) {
            Ok(dur) if dur == Duration::new(0, 0) => {
                assert_almost_eq!(a, b);
            }
            Ok(dur) => {
                assert!(b > a);
                assert_almost_eq!(b - dur, a);
                assert_almost_eq!(a + dur, b);
            }
            Err(dur) => {
                let dur = dur.duration();
                assert!(a > b);
                assert_almost_eq!(b + dur, a);
                assert_almost_eq!(b - dur, a);
            }
        }

        let second = Duration::new(1, 0);
        assert_almost_eq!(a.duration_from_earlier(a - second).unwrap(), second);
        assert_almost_eq!(a.duration_from_earlier(a + second).unwrap_err()
                           .duration(), second);

        assert_almost_eq!(a - second + second, a);

        let eighty_years = second * 60 * 60 * 24 * 365 * 80;
        assert_almost_eq!(a - eighty_years + eighty_years, a);
        assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), a);
    }

    #[test]
    fn system_time_elapsed() {
        let a = SystemTime::now();
        drop(a.elapsed());
    }

    #[test]
    fn since_epoch() {
        let ts = SystemTime::now();
        let a = ts.duration_from_earlier(UNIX_EPOCH).unwrap();
        let b = ts.duration_from_earlier(UNIX_EPOCH - Duration::new(1, 0)).unwrap();
        assert!(b > a);
        assert_eq!(b - a, Duration::new(1, 0));

        // let's assume that we're all running computers later than 2000
        let thirty_years = Duration::new(1, 0) * 60 * 60 * 24 * 365 * 30;
        assert!(a > thirty_years);

        // let's assume that we're all running computers earlier than 2090.
        // Should give us ~70 years to fix this!
        let hundred_twenty_years = thirty_years * 4;
        assert!(a < hundred_twenty_years);
    }
}
<|endoftext|>


<commit_before>/*!

Run time length encoding and decoding based on byte streams, see
https://en.wikipedia.org/wiki/Run-length_encoding.

A run is defined as a sequence of identical bytes of length two or greater.
A run of byte a and length n is encoded by a two repitions of a, followed
by a length specification which describes how much often these bytes are
repeated. Such a specification is a string of bytes with dynamic length.
The most significat bit of each byte in this string indicates if the byte is
the last byte in the string. The rest of the bits are concatenated using
the Little Endian convention.

# Example

```rust
use compress::rle;
use std::io::{Write, Read};

let input = b"Helloooo world!!";

let mut encoder = rle::Encoder::new(Vec::new());
encoder.write_all(&input[..]).unwrap();
let (buf, _): (Vec<u8>, _) = encoder.finish();

let mut decoder = rle::Decoder::new(&buf[..]);
let mut decoder_buf = Vec::new();
decoder.read_to_end(&mut decoder_buf).unwrap();

assert_eq!(&input[..], &decoder_buf[..]);
```

!*/

use std::io::{self, Write, Read, BufReader, Bytes};

/// This structure is used to compress a stream of bytes using a RLE
/// compression algorithm. This is a wrapper around an internal writer which
/// bytes will be written to.
pub struct Encoder<W> {
    w: W,
    reps: u64,
    byte: u8,
    in_run: bool
}

impl<W: Write> Encoder<W> {
    /// Creates a new encoder which will have its output written to the given
    /// output stream.
    pub fn new(w: W) -> Encoder<W> {
        Encoder {
            w: w,
            reps: 0,
            byte: 0,
            in_run: false
        }
    }

    /// This function is used to flag that this session of compression is done
    /// with. The stream is finished up (final bytes are written), and then the
    /// wrapped writer is returned.
    pub fn finish(mut self) -> (W, io::Result<()>) {
        let result = self.flush();

        (self.w, result)
    }

    fn process_byte(&mut self, byte: u8) -> io::Result<()> {
        if self.byte == byte {
            self.reps += 1;
        } else if self.byte != byte {
            try!(self.flush());
            self.reps = 1;
            self.byte = byte;
        }

        Ok(())
    }
}

impl<W: Write> Write for Encoder<W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        if ! self.in_run && buf.len() > 0 {
            self.byte = buf[0];
            self.reps = 1;
            self.in_run = true;
        }

        for byte in &buf[1..] {
            try!(self.process_byte(*byte));
        }

        Ok(buf.len())
    }

    fn flush(&mut self) -> io::Result<()> {
        if self.reps == 1 {
            try!(self.w.write(&[self.byte]));
        } else if self.reps > 1 {
            let mut buf = [0; 11];
            let mut reps_encode = self.reps - 2;
            let mut index = 2;
            buf[0] = self.byte;
            buf[1] = self.byte;

            loop {
                buf[index] = (reps_encode & 0b0111_1111) as u8;
                reps_encode = reps_encode >> 7;

                if reps_encode == 0 {
                    buf[index] = buf[index] | 0b1000_0000;
                    break;
                }

                index += 1;
            }

            try!(self.w.write(&buf[..(index + 1)]));
        }

        Ok(())
    }
}

struct RunBuilder {
    byte: u8,
    slice: [u8; 9],
    byte_count: u8
}

impl RunBuilder {
    fn new(byte: u8) -> RunBuilder {
        RunBuilder {
            byte: byte,
            slice: [0; 9],
            byte_count: 0
        }
    }

    fn to_run(&mut self) -> Run {
        let reps = 2 + self.slice.iter().enumerate().fold(0u64, |reps, (i, &byte)| {
            reps | (((byte & 0b0111_1111) as u64) << (i as u32 * 7))
        });

        Run {
            byte: self.byte,
            reps: reps
        }
    }

    fn add_byte(&mut self, byte: u8) -> io::Result<()> {
        if self.byte_count >= 9 {
            Err(io::Error::new(io::ErrorKind::Other, "Overly long run"))
        } else {
            self.slice[self.byte_count as usize] = byte;
            self.byte_count += 1;
            Ok(())
        }
    }
}

struct Run {
    byte: u8,
    reps: u64
}

enum DecoderState {
    Clean,
    Single(u8),
    Run(RunBuilder)
}

/// This structure is used to decode a run length encoded stream. This wraps
/// an internal reader which is read from when this decoder's read method is
/// called.
pub struct Decoder<R> {
    buf: Bytes<R>,
    state: DecoderState,
    run: Option<Run>
}

impl<R: Read> Decoder<R> {
    /// Creates a new decoder which will read data from the given stream. The
    /// inner stream can be re-acquired by moving out of the `r` field of this
    /// structure.
    pub fn new(r: R) -> Decoder<R> {
        Decoder {
            buf: r.bytes(),
            state: DecoderState::Clean,
            run: None
        }
    }

    fn read_byte(&mut self) -> io::Result<Option<u8>> {
        if let None = self.run {
            try!(self.read_run());
        }

        if let Some(Run { byte: b, reps: r }) = self.run {
            if r <= 1 {
                self.run = None;
            } else {
                self.run = Some(Run { byte: b, reps: r - 1 });
            }

            return Ok(Some(b))
        }

        Ok(None)
    }

    fn read_run(&mut self) -> io::Result<()> {
        let mut reset = false;

        while let Some(result) = self.buf.next() {
            let byte = try!(result);

            match self.state {
                DecoderState::Clean => {
                    self.state = DecoderState::Single(byte);
                },
                DecoderState::Single(current) => {
                    if byte == current {
                        self.state = DecoderState::Run(RunBuilder::new(byte));
                    } else {
                        self.run = Some(Run { byte: current, reps: 1 });
                        self.state = DecoderState::Single(byte);
                        break;
                    }
                },
                DecoderState::Run(ref mut run_builder) => {
                    try!(run_builder.add_byte(byte));

                    if Self::is_final_run_byte(byte) {
                        self.run = Some(run_builder.to_run());
                        reset = true;
                        break;
                    }
                }
            }
        }

        if reset {
            self.state = DecoderState::Clean;
        }

        // internal read object exhausted -- flush remaining state into run
        if let None = self.run {
            self.run = match self.state {
                DecoderState::Clean => None,
                DecoderState::Single(byte) => Some(Run { byte: byte, reps: 1 }),
                DecoderState::Run(ref mut run_builder) => Some(run_builder.to_run())
            };

            self.state = DecoderState::Clean;
        }

        Ok(())
    }

    fn is_final_run_byte(byte: u8) -> bool {
        0b1000_0000 & byte != 0
    }
}

impl<R: Read> Read for Decoder<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let mut bytes_read = 0;

        for slot in buf {
            match try!(self.read_byte()) {
                Some(b) => *slot = b,
                None => break
            }

            bytes_read += 1;
        }

        Ok(bytes_read)
    }
}

#[cfg(test)]
mod test {
    use super::{Decoder, Encoder};
    use super::super::rand::{OsRng, Rng};
    use std::io::{Write, Read};
    use std::iter::{Iterator, repeat};
    use test;

    fn test_encode(input: &[u8], output: &[u8]) {
        let mut encoder = Encoder::new(Vec::new());
        encoder.write_all(input).unwrap();
        let (buf, _) = encoder.finish();

        assert_eq!(output, &buf[..]);
    }

    fn test_decode(input: &[u8], output: &[u8]) {
        let mut decoder = Decoder::new(input);
        let mut buf = Vec::new();
        decoder.read_to_end(&mut buf).unwrap();

        assert_eq!(output, &buf[..]);
    }

    fn test_roundtrip(input: &[u8]) {
        let mut encoder = Encoder::new(Vec::new());
        encoder.write_all(input).unwrap();
        let (buf, _) = encoder.finish();

        let mut decoder = Decoder::new(&buf[..]);
        let mut decoder_buf = Vec::new();
        decoder.read_to_end(&mut decoder_buf).unwrap();

        assert_eq!(input, &decoder_buf[..]);
    }

    #[test]
    fn simple_encoding() {
        test_encode(b"", b"");
        test_encode(b"a", b"a");
        test_encode(b"abca123", b"abca123");
        test_encode(&[20, 20, 20, 20, 20, 15], &[20, 20, 5 - 2 + 128, 15]);
        test_encode(&[0, 0], &[0, 0, 2 - 2 + 128]);
    }

    #[test]
    fn long_run_encoding() {
        let mut data = repeat(5).take(129).collect::<Vec<_>>();
        test_encode(&data[..], &[5, 5, 255]);

        data = [1, 3, 4, 4].iter().map(|&x| x).chain(repeat(100).take(2 + 52 + 128)).collect::<Vec<_>>();
        test_encode(&data[..], &[1, 3, 4, 4, 0 + 128, 100, 100, 52, 1 + 128]);
    }

    #[test]
    fn simple_decoding() {
        test_decode(b"", b"");
        test_decode(b"a", b"a");
        test_decode(b"abca123", b"abca123");
        test_decode(&[20, 20, 5 - 2 + 128, 15], &[20, 20, 20, 20, 20, 15]);
        test_decode(&[0, 0, 2 - 2 + 128], &[0, 0]);
    }

    #[test]
    fn long_run_decoding() {
        let data = [1, 3, 4, 4].iter().map(|&x| x).chain(repeat(100).take(2 + 52 + 128)).collect::<Vec<_>>();

        test_decode(&[1, 3, 4, 4, 0 + 128, 100, 100, 52, 1 + 128], &data[..]);
    }

    #[test]
    fn random_roundtrips() {
        let mut rng = OsRng::new().unwrap();

        for _ in 0..100 {
            let mut buf = [0; 13579];
            rng.fill_bytes(&mut buf[..]);
            test_roundtrip(&buf);
        }
    }
}
<commit_msg>Add benchmarks for run length encoding/ decoding<commit_after>/*!

Run time length encoding and decoding based on byte streams, see
https://en.wikipedia.org/wiki/Run-length_encoding.

A run is defined as a sequence of identical bytes of length two or greater.
A run of byte a and length n is encoded by a two repitions of a, followed
by a length specification which describes how much often these bytes are
repeated. Such a specification is a string of bytes with dynamic length.
The most significat bit of each byte in this string indicates if the byte is
the last byte in the string. The rest of the bits are concatenated using
the Little Endian convention.

# Example

```rust
use compress::rle;
use std::io::{Write, Read};

let input = b"Helloooo world!!";

let mut encoder = rle::Encoder::new(Vec::new());
encoder.write_all(&input[..]).unwrap();
let (buf, _): (Vec<u8>, _) = encoder.finish();

let mut decoder = rle::Decoder::new(&buf[..]);
let mut decoder_buf = Vec::new();
decoder.read_to_end(&mut decoder_buf).unwrap();

assert_eq!(&input[..], &decoder_buf[..]);
```

!*/

use std::io::{self, Write, Read, Bytes};

/// This structure is used to compress a stream of bytes using a RLE
/// compression algorithm. This is a wrapper around an internal writer which
/// bytes will be written to.
pub struct Encoder<W> {
    w: W,
    reps: u64,
    byte: u8,
    in_run: bool
}

impl<W: Write> Encoder<W> {
    /// Creates a new encoder which will have its output written to the given
    /// output stream.
    pub fn new(w: W) -> Encoder<W> {
        Encoder {
            w: w,
            reps: 0,
            byte: 0,
            in_run: false
        }
    }

    /// This function is used to flag that this session of compression is done
    /// with. The stream is finished up (final bytes are written), and then the
    /// wrapped writer is returned.
    pub fn finish(mut self) -> (W, io::Result<()>) {
        let result = self.flush();

        (self.w, result)
    }

    fn process_byte(&mut self, byte: u8) -> io::Result<()> {
        if self.byte == byte {
            self.reps += 1;
        } else if self.byte != byte {
            try!(self.flush());
            self.reps = 1;
            self.byte = byte;
        }

        Ok(())
    }
}

impl<W: Write> Write for Encoder<W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        if ! self.in_run && buf.len() > 0 {
            self.byte = buf[0];
            self.reps = 1;
            self.in_run = true;
        }

        for byte in &buf[1..] {
            try!(self.process_byte(*byte));
        }

        Ok(buf.len())
    }

    fn flush(&mut self) -> io::Result<()> {
        if self.reps == 1 {
            try!(self.w.write(&[self.byte]));
        } else if self.reps > 1 {
            let mut buf = [0; 11];
            let mut reps_encode = self.reps - 2;
            let mut index = 2;
            buf[0] = self.byte;
            buf[1] = self.byte;

            loop {
                buf[index] = (reps_encode & 0b0111_1111) as u8;
                reps_encode = reps_encode >> 7;

                if reps_encode == 0 {
                    buf[index] = buf[index] | 0b1000_0000;
                    break;
                }

                index += 1;
            }

            try!(self.w.write(&buf[..(index + 1)]));
        }

        Ok(())
    }
}

struct RunBuilder {
    byte: u8,
    slice: [u8; 9],
    byte_count: u8
}

impl RunBuilder {
    fn new(byte: u8) -> RunBuilder {
        RunBuilder {
            byte: byte,
            slice: [0; 9],
            byte_count: 0
        }
    }

    fn to_run(&mut self) -> Run {
        let reps = 2 + self.slice.iter().enumerate().fold(0u64, |reps, (i, &byte)| {
            reps | (((byte & 0b0111_1111) as u64) << (i as u32 * 7))
        });

        Run {
            byte: self.byte,
            reps: reps
        }
    }

    fn add_byte(&mut self, byte: u8) -> io::Result<()> {
        if self.byte_count >= 9 {
            Err(io::Error::new(io::ErrorKind::Other, "Overly long run"))
        } else {
            self.slice[self.byte_count as usize] = byte;
            self.byte_count += 1;
            Ok(())
        }
    }
}

struct Run {
    byte: u8,
    reps: u64
}

enum DecoderState {
    Clean,
    Single(u8),
    Run(RunBuilder)
}

/// This structure is used to decode a run length encoded stream. This wraps
/// an internal reader which is read from when this decoder's read method is
/// called.
pub struct Decoder<R> {
    buf: Bytes<R>,
    state: DecoderState,
    run: Option<Run>
}

impl<R: Read> Decoder<R> {
    /// Creates a new decoder which will read data from the given stream. The
    /// inner stream can be re-acquired by moving out of the `r` field of this
    /// structure.
    pub fn new(r: R) -> Decoder<R> {
        Decoder {
            buf: r.bytes(),
            state: DecoderState::Clean,
            run: None
        }
    }

    fn read_byte(&mut self) -> io::Result<Option<u8>> {
        if let None = self.run {
            try!(self.read_run());
        }

        if let Some(Run { byte: b, reps: r }) = self.run {
            if r <= 1 {
                self.run = None;
            } else {
                self.run = Some(Run { byte: b, reps: r - 1 });
            }

            return Ok(Some(b))
        }

        Ok(None)
    }

    fn read_run(&mut self) -> io::Result<()> {
        let mut reset = false;

        while let Some(result) = self.buf.next() {
            let byte = try!(result);

            match self.state {
                DecoderState::Clean => {
                    self.state = DecoderState::Single(byte);
                },
                DecoderState::Single(current) => {
                    if byte == current {
                        self.state = DecoderState::Run(RunBuilder::new(byte));
                    } else {
                        self.run = Some(Run { byte: current, reps: 1 });
                        self.state = DecoderState::Single(byte);
                        break;
                    }
                },
                DecoderState::Run(ref mut run_builder) => {
                    try!(run_builder.add_byte(byte));

                    if Self::is_final_run_byte(byte) {
                        self.run = Some(run_builder.to_run());
                        reset = true;
                        break;
                    }
                }
            }
        }

        if reset {
            self.state = DecoderState::Clean;
        }

        // internal read object exhausted -- flush remaining state into run
        if let None = self.run {
            self.run = match self.state {
                DecoderState::Clean => None,
                DecoderState::Single(byte) => Some(Run { byte: byte, reps: 1 }),
                DecoderState::Run(ref mut run_builder) => Some(run_builder.to_run())
            };

            self.state = DecoderState::Clean;
        }

        Ok(())
    }

    fn is_final_run_byte(byte: u8) -> bool {
        0b1000_0000 & byte != 0
    }
}

impl<R: Read> Read for Decoder<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let mut bytes_read = 0;

        for slot in buf {
            match try!(self.read_byte()) {
                Some(b) => *slot = b,
                None => break
            }

            bytes_read += 1;
        }

        Ok(bytes_read)
    }
}

#[cfg(test)]
mod test {
    use super::{Decoder, Encoder};
    use super::super::rand::{OsRng, Rng};
    use std::io::{Write, Read};
    use std::iter::{Iterator, repeat};
    use test;

    fn test_encode(input: &[u8], output: &[u8]) {
        let mut encoder = Encoder::new(Vec::new());
        encoder.write_all(input).unwrap();
        let (buf, _) = encoder.finish();

        assert_eq!(output, &buf[..]);
    }

    fn test_decode(input: &[u8], output: &[u8]) {
        let mut decoder = Decoder::new(input);
        let mut buf = Vec::new();
        decoder.read_to_end(&mut buf).unwrap();

        assert_eq!(output, &buf[..]);
    }

    fn test_roundtrip(input: &[u8]) {
        let mut encoder = Encoder::new(Vec::new());
        encoder.write_all(input).unwrap();
        let (buf, _) = encoder.finish();

        let mut decoder = Decoder::new(&buf[..]);
        let mut decoder_buf = Vec::new();
        decoder.read_to_end(&mut decoder_buf).unwrap();

        assert_eq!(input, &decoder_buf[..]);
    }

    #[test]
    fn simple_encoding() {
        test_encode(b"", b"");
        test_encode(b"a", b"a");
        test_encode(b"abca123", b"abca123");
        test_encode(&[20, 20, 20, 20, 20, 15], &[20, 20, 5 - 2 + 128, 15]);
        test_encode(&[0, 0], &[0, 0, 2 - 2 + 128]);
    }

    #[test]
    fn long_run_encoding() {
        let mut data = repeat(5).take(129).collect::<Vec<_>>();
        test_encode(&data[..], &[5, 5, 255]);

        data = [1, 3, 4, 4].iter().map(|&x| x).chain(repeat(100).take(2 + 52 + 128)).collect::<Vec<_>>();
        test_encode(&data[..], &[1, 3, 4, 4, 0 + 128, 100, 100, 52, 1 + 128]);
    }

    #[test]
    fn simple_decoding() {
        test_decode(b"", b"");
        test_decode(b"a", b"a");
        test_decode(b"abca123", b"abca123");
        test_decode(&[20, 20, 5 - 2 + 128, 15], &[20, 20, 20, 20, 20, 15]);
        test_decode(&[0, 0, 2 - 2 + 128], &[0, 0]);
    }

    #[test]
    fn long_run_decoding() {
        let data = [1, 3, 4, 4].iter().map(|&x| x).chain(repeat(100).take(2 + 52 + 128)).collect::<Vec<_>>();

        test_decode(&[1, 3, 4, 4, 0 + 128, 100, 100, 52, 1 + 128], &data[..]);
    }

    #[test]
    fn random_roundtrips() {
        let mut rng = OsRng::new().unwrap();

        for _ in 0..100 {
            let mut buf = [0; 13579];
            rng.fill_bytes(&mut buf[..]);
            test_roundtrip(&buf);
        }
    }

    // initial speed: 145 MB/s
    // after moving check to write: 145 MB/s

    #[bench]
    fn compress_speed(bh: &mut test::Bencher) {
        let input = include_bytes!("data/test.txt");
        bh.bytes = input.len() as u64;
        let output_size = Encoder::new(Vec::new()).write(&input[..]).unwrap();
        let mut buf = Vec::with_capacity(output_size);

        bh.iter(|| {
            let mut encoder = Encoder::new(&mut buf[..]);
            encoder.write(&input[..]).unwrap();
        });
    }

    // initial speed: 91 MB/s
    // after using a BufReader instead of VecDeque: 20 MB/s
    // after using a byte iterator on a BufReader: 20 MB/s
    // after using a byte iterator on the raw read object: 80 MB/s

    #[bench]
    fn decompress_speed(bh: &mut test::Bencher) {
        let input = include_bytes!("data/test.txt");
        let mut encoder = Encoder::new(Vec::new());
        encoder.write_all(&input[..]).unwrap();
        let (buf, _): (Vec<u8>, _) = encoder.finish();

        let mut output = [0u8; 65536];
        let mut output_size = 0;

        bh.iter(|| {
            let mut decoder = Decoder::new(& buf[..]);
            output_size = decoder.read(&mut output[..]).unwrap();
        });

        bh.bytes = output_size as u64;
    }
}
<|endoftext|>


<commit_before>use std::cast;
use std::str;

// Setup linking for all targets.
#[cfg(target_os="macos")]
mod mac {
    #[cfg(mac_framework)]
    #[link_args="-framework SDL2"]
    extern {}

    #[cfg(mac_dylib)]
    #[link_args="-lSDL2"]
    extern {}
}

#[cfg(target_os="win32")]
#[cfg(target_os="linux")]
#[cfg(target_os="freebsd")]
mod others {
    #[link_args="-lSDL2"]
    extern {}
}

pub mod ll {
    use std::libc::{c_int, c_uint, c_schar, uint32_t};

    pub type SDL_errorcode = c_uint;
    pub static SDL_ENOMEM: SDL_errorcode = 0;
    pub static SDL_EFREAD: SDL_errorcode = 1;
    pub static SDL_EFWRITE: SDL_errorcode = 2;
    pub static SDL_EFSEEK: SDL_errorcode = 3;
    pub static SDL_UNSUPPORTED: SDL_errorcode = 4;
    pub static SDL_LASTERROR: SDL_errorcode = 5;

    pub type SDL_InitFlag = uint32_t;
    pub static SDL_INIT_TIMER: SDL_InitFlag = 0x00000001;
    pub static SDL_INIT_AUDIO: SDL_InitFlag = 0x00000010;
    pub static SDL_INIT_VIDEO: SDL_InitFlag = 0x00000020;
    pub static SDL_INIT_JOYSTICK: SDL_InitFlag = 0x00000200;
    pub static SDL_INIT_HAPTIC: SDL_InitFlag = 0x00001000;
    pub static SDL_INIT_GAMECONTROLLER: SDL_InitFlag = 0x00002000;
    pub static SDL_INIT_EVENTS: SDL_InitFlag = 0x00004000;
    pub static SDL_INIT_NOPARACHUTE: SDL_InitFlag = 0x00100000;
    pub static SDL_INIT_EVERYTHING: SDL_InitFlag = 0x0000FFFF;

    //SDL_error.h
    extern "C" {
        pub fn SDL_ClearError();
        pub fn SDL_Error(code: SDL_errorcode) -> c_int;
        pub fn SDL_SetError(fmt: *c_schar) -> c_int;
        pub fn SDL_GetError() -> *c_schar;

        //SDL.h
        pub fn SDL_Init(flags: uint32_t) -> c_int;
        pub fn SDL_InitSubSystem(flags: SDL_InitFlag) -> c_int;
        pub fn SDL_QuitSubSystem(flags: SDL_InitFlag);
        pub fn SDL_WasInit(flags: SDL_InitFlag) -> SDL_InitFlag;
        pub fn SDL_Quit();

        //SDL_timer.h
        pub fn SDL_GetTicks() -> uint32_t;
    }
}

#[deriving(Eq)]
pub enum InitFlag {
    InitTimer = ll::SDL_INIT_TIMER as int,
    InitAudio = ll::SDL_INIT_AUDIO as int,
    InitVideo = ll::SDL_INIT_VIDEO as int,
    InitJoystick = ll::SDL_INIT_JOYSTICK as int,
    InitHaptic = ll::SDL_INIT_HAPTIC as int,
    InitGameController = ll::SDL_INIT_GAMECONTROLLER as int,
    InitEvents = ll::SDL_INIT_EVENTS as int,
    InitNoParachute = ll::SDL_INIT_NOPARACHUTE as int,
    InitEverything = ll::SDL_INIT_EVERYTHING as int,
}

#[deriving(Eq)]
pub enum Error {
    NoMemError = ll::SDL_ENOMEM as int,
    ReadError = ll::SDL_EFREAD as int,
    WriteError = ll::SDL_EFWRITE as int,
    SeekError = ll::SDL_EFSEEK as int,
    UnsupportedError = ll::SDL_UNSUPPORTED as int
}

pub fn init(flags: &[InitFlag]) -> bool {
    unsafe {
        ll::SDL_Init(do flags.iter().fold(0u32) |flags, &flag| {
            flags | flag as ll::SDL_InitFlag
        }) == 0
    }
}

pub fn init_subsystem(flags: &[InitFlag]) -> bool {
    unsafe {
        ll::SDL_InitSubSystem(do flags.iter().fold(0u32) |flags, &flag| {
            flags | flag as ll::SDL_InitFlag
        }) == 0
    }
}

pub fn quit_subsystem(flags: &[InitFlag]) {
    let flags = do flags.iter().fold(0u32) |flags, &flag| {
        flags | flag as ll::SDL_InitFlag
    };

    unsafe { ll::SDL_QuitSubSystem(flags); }
}

pub fn quit() {
    unsafe { ll::SDL_Quit(); }
}

pub fn was_inited(flags: &[InitFlag]) -> ~[InitFlag] {
    let flags = do flags.iter().fold(0u32) |flags, &flag| {
        flags | flag as ll::SDL_InitFlag
    };
    let bitflags = unsafe { ll::SDL_WasInit(flags) };

    let flags = [InitTimer,
        InitAudio,
        InitVideo,
        InitJoystick,
        InitHaptic,
        InitGameController,
        InitEvents,
        InitNoParachute,
        InitEverything];

    do flags.iter().filter_map |&flag| {
        if bitflags & (flag as ll::SDL_InitFlag) != 0 { Some(flag) }
        else { None }
    }.collect()
}

pub fn get_error() -> ~str {
    unsafe {
        let cstr = ll::SDL_GetError();

        str::raw::from_c_str(cast::transmute_copy(&cstr))
    }
}

pub fn set_error(err: &str) {
    do err.with_c_str |buf| {
        unsafe { ll::SDL_SetError(buf); }
    }
}

pub fn set_error_from_code(err: Error) {
    unsafe { ll::SDL_Error(err as ll::SDL_errorcode); }
}

pub fn clear_error() {
    unsafe { ll::SDL_ClearError(); }
}

pub fn get_ticks() -> uint {
    unsafe { ll::SDL_GetTicks() as uint }
}
<commit_msg>Mirrored config changes in brson/rust-sdl#111<commit_after>use std::cast;
use std::str;

// Setup linking for all targets.
#[cfg(target_os="macos")]
mod mac {
    #[cfg(mac_framework)]
    #[link_args="-framework SDL2"]
    extern {}

    #[cfg(not(mac_framework))]
    #[link_args="-lSDL2"]
    extern {}
}

#[cfg(target_os="win32")]
#[cfg(target_os="linux")]
#[cfg(target_os="freebsd")]
mod others {
    #[link_args="-lSDL2"]
    extern {}
}

pub mod ll {
    use std::libc::{c_int, c_uint, c_schar, uint32_t};

    pub type SDL_errorcode = c_uint;
    pub static SDL_ENOMEM: SDL_errorcode = 0;
    pub static SDL_EFREAD: SDL_errorcode = 1;
    pub static SDL_EFWRITE: SDL_errorcode = 2;
    pub static SDL_EFSEEK: SDL_errorcode = 3;
    pub static SDL_UNSUPPORTED: SDL_errorcode = 4;
    pub static SDL_LASTERROR: SDL_errorcode = 5;

    pub type SDL_InitFlag = uint32_t;
    pub static SDL_INIT_TIMER: SDL_InitFlag = 0x00000001;
    pub static SDL_INIT_AUDIO: SDL_InitFlag = 0x00000010;
    pub static SDL_INIT_VIDEO: SDL_InitFlag = 0x00000020;
    pub static SDL_INIT_JOYSTICK: SDL_InitFlag = 0x00000200;
    pub static SDL_INIT_HAPTIC: SDL_InitFlag = 0x00001000;
    pub static SDL_INIT_GAMECONTROLLER: SDL_InitFlag = 0x00002000;
    pub static SDL_INIT_EVENTS: SDL_InitFlag = 0x00004000;
    pub static SDL_INIT_NOPARACHUTE: SDL_InitFlag = 0x00100000;
    pub static SDL_INIT_EVERYTHING: SDL_InitFlag = 0x0000FFFF;

    //SDL_error.h
    extern "C" {
        pub fn SDL_ClearError();
        pub fn SDL_Error(code: SDL_errorcode) -> c_int;
        pub fn SDL_SetError(fmt: *c_schar) -> c_int;
        pub fn SDL_GetError() -> *c_schar;

        //SDL.h
        pub fn SDL_Init(flags: uint32_t) -> c_int;
        pub fn SDL_InitSubSystem(flags: SDL_InitFlag) -> c_int;
        pub fn SDL_QuitSubSystem(flags: SDL_InitFlag);
        pub fn SDL_WasInit(flags: SDL_InitFlag) -> SDL_InitFlag;
        pub fn SDL_Quit();

        //SDL_timer.h
        pub fn SDL_GetTicks() -> uint32_t;
    }
}

#[deriving(Eq)]
pub enum InitFlag {
    InitTimer = ll::SDL_INIT_TIMER as int,
    InitAudio = ll::SDL_INIT_AUDIO as int,
    InitVideo = ll::SDL_INIT_VIDEO as int,
    InitJoystick = ll::SDL_INIT_JOYSTICK as int,
    InitHaptic = ll::SDL_INIT_HAPTIC as int,
    InitGameController = ll::SDL_INIT_GAMECONTROLLER as int,
    InitEvents = ll::SDL_INIT_EVENTS as int,
    InitNoParachute = ll::SDL_INIT_NOPARACHUTE as int,
    InitEverything = ll::SDL_INIT_EVERYTHING as int,
}

#[deriving(Eq)]
pub enum Error {
    NoMemError = ll::SDL_ENOMEM as int,
    ReadError = ll::SDL_EFREAD as int,
    WriteError = ll::SDL_EFWRITE as int,
    SeekError = ll::SDL_EFSEEK as int,
    UnsupportedError = ll::SDL_UNSUPPORTED as int
}

pub fn init(flags: &[InitFlag]) -> bool {
    unsafe {
        ll::SDL_Init(do flags.iter().fold(0u32) |flags, &flag| {
            flags | flag as ll::SDL_InitFlag
        }) == 0
    }
}

pub fn init_subsystem(flags: &[InitFlag]) -> bool {
    unsafe {
        ll::SDL_InitSubSystem(do flags.iter().fold(0u32) |flags, &flag| {
            flags | flag as ll::SDL_InitFlag
        }) == 0
    }
}

pub fn quit_subsystem(flags: &[InitFlag]) {
    let flags = do flags.iter().fold(0u32) |flags, &flag| {
        flags | flag as ll::SDL_InitFlag
    };

    unsafe { ll::SDL_QuitSubSystem(flags); }
}

pub fn quit() {
    unsafe { ll::SDL_Quit(); }
}

pub fn was_inited(flags: &[InitFlag]) -> ~[InitFlag] {
    let flags = do flags.iter().fold(0u32) |flags, &flag| {
        flags | flag as ll::SDL_InitFlag
    };
    let bitflags = unsafe { ll::SDL_WasInit(flags) };

    let flags = [InitTimer,
        InitAudio,
        InitVideo,
        InitJoystick,
        InitHaptic,
        InitGameController,
        InitEvents,
        InitNoParachute,
        InitEverything];

    do flags.iter().filter_map |&flag| {
        if bitflags & (flag as ll::SDL_InitFlag) != 0 { Some(flag) }
        else { None }
    }.collect()
}

pub fn get_error() -> ~str {
    unsafe {
        let cstr = ll::SDL_GetError();

        str::raw::from_c_str(cast::transmute_copy(&cstr))
    }
}

pub fn set_error(err: &str) {
    do err.with_c_str |buf| {
        unsafe { ll::SDL_SetError(buf); }
    }
}

pub fn set_error_from_code(err: Error) {
    unsafe { ll::SDL_Error(err as ll::SDL_errorcode); }
}

pub fn clear_error() {
    unsafe { ll::SDL_ClearError(); }
}

pub fn get_ticks() -> uint {
    unsafe { ll::SDL_GetTicks() as uint }
}
<|endoftext|>


<commit_before>use std::iter;
use byteorder::{BigEndian, ByteOrder};

pub const K: [u64; 80] = [
    0x428a2f98d728ae22,
    0x7137449123ef65cd,
    0xb5c0fbcfec4d3b2f,
    0xe9b5dba58189dbbc,
    0x3956c25bf348b538,
    0x59f111f1b605d019,
    0x923f82a4af194f9b,
    0xab1c5ed5da6d8118,
    0xd807aa98a3030242,
    0x12835b0145706fbe,
    0x243185be4ee4b28c,
    0x550c7dc3d5ffb4e2,
    0x72be5d74f27b896f,
    0x80deb1fe3b1696b1,
    0x9bdc06a725c71235,
    0xc19bf174cf692694,
    0xe49b69c19ef14ad2,
    0xefbe4786384f25e3,
    0x0fc19dc68b8cd5b5,
    0x240ca1cc77ac9c65,
    0x2de92c6f592b0275,
    0x4a7484aa6ea6e483,
    0x5cb0a9dcbd41fbd4,
    0x76f988da831153b5,
    0x983e5152ee66dfab,
    0xa831c66d2db43210,
    0xb00327c898fb213f,
    0xbf597fc7beef0ee4,
    0xc6e00bf33da88fc2,
    0xd5a79147930aa725,
    0x06ca6351e003826f,
    0x142929670a0e6e70,
    0x27b70a8546d22ffc,
    0x2e1b21385c26c926,
    0x4d2c6dfc5ac42aed,
    0x53380d139d95b3df,
    0x650a73548baf63de,
    0x766a0abb3c77b2a8,
    0x81c2c92e47edaee6,
    0x92722c851482353b,
    0xa2bfe8a14cf10364,
    0xa81a664bbc423001,
    0xc24b8b70d0f89791,
    0xc76c51a30654be30,
    0xd192e819d6ef5218,
    0xd69906245565a910,
    0xf40e35855771202a,
    0x106aa07032bbd1b8,
    0x19a4c116b8d2d0c8,
    0x1e376c085141ab53,
    0x2748774cdf8eeb99,
    0x34b0bcb5e19b48a8,
    0x391c0cb3c5c95a63,
    0x4ed8aa4ae3418acb,
    0x5b9cca4f7763e373,
    0x682e6ff3d6b2b8a3,
    0x748f82ee5defb2fc,
    0x78a5636f43172f60,
    0x84c87814a1f0ab72,
    0x8cc702081a6439ec,
    0x90befffa23631e28,
    0xa4506cebde82bde9,
    0xbef9a3f7b2c67915,
    0xc67178f2e372532b,
    0xca273eceea26619c,
    0xd186b8c721c0c207,
    0xeada7dd6cde0eb1e,
    0xf57d4f7fee6ed178,
    0x06f067aa72176fba,
    0x0a637dc5a2c898a6,
    0x113f9804bef90dae,
    0x1b710b35131c471b,
    0x28db77f523047d84,
    0x32caab7b40c72493,
    0x3c9ebe0a15c9bebc,
    0x431d67c49c100d4c,
    0x4cc5d4becb3e42b6,
    0x597f299cfc657e2a,
    0x5fcb6fab3ad6faec,
    0x6c44198c4a475817,
];

pub struct SHA512 {}

impl SHA512 {
    pub fn digest(message: &[u8]) -> [u8; 64] {
        let mut message = message.to_vec();
        Self::pad(&mut message);
        let mut hash: [u64; 8] = [
            0x6a09e667f3bcc908,
            0xbb67ae8584caa73b,
            0x3c6ef372fe94f82b,
            0xa54ff53a5f1d36f1,
            0x510e527fade682d1,
            0x9b05688c2b3e6c1f,
            0x1f83d9abfb41bd6b,
            0x5be0cd19137e2179,
        ];
        let mut w = [0; 80];
        for chunk in message.chunks(128) {
            for (wt, long) in w.iter_mut().zip(chunk.chunks(8)) {
                *wt = BigEndian::read_u64(long);
            }
            for t in 16..80 {
                w[t] = Self::ssig1(w[t - 2])
                    .wrapping_add(w[t - 7])
                    .wrapping_add(Self::ssig0(w[t - 15]))
                    .wrapping_add(w[t - 16]);
            }
            let mut a = hash[0];
            let mut b = hash[1];
            let mut c = hash[2];
            let mut d = hash[3];
            let mut e = hash[4];
            let mut f = hash[5];
            let mut g = hash[6];
            let mut h = hash[7];
            for (&kt, &wt) in K.iter().zip(w.iter()) {
                let t1 = h.wrapping_add(Self::bsig1(e))
                    .wrapping_add(Self::ch(e, f, g))
                    .wrapping_add(kt)
                    .wrapping_add(wt);
                let t2 = Self::bsig0(a).wrapping_add(Self::maj(a, b, c));
                h = g;
                g = f;
                f = e;
                e = d.wrapping_add(t1);
                d = c;
                c = b;
                b = a;
                a = t1.wrapping_add(t2);
            }
            hash[0] = hash[0].wrapping_add(a);
            hash[1] = hash[1].wrapping_add(b);
            hash[2] = hash[2].wrapping_add(c);
            hash[3] = hash[3].wrapping_add(d);
            hash[4] = hash[4].wrapping_add(e);
            hash[5] = hash[5].wrapping_add(f);
            hash[6] = hash[6].wrapping_add(g);
            hash[7] = hash[7].wrapping_add(h);
        }
        let mut digest = [0; 64];
        for (chunk, &long) in digest.chunks_mut(8).zip(&hash) {
            BigEndian::write_u64(chunk, long);
        }
        digest
    }
    pub fn ch(x: u64, y: u64, z: u64) -> u64 {
        (x & y) ^ (!x & z)
    }

    pub fn maj(x: u64, y: u64, z: u64) -> u64 {
        (x & y) ^ (x & z) ^ (y & z)
    }

    pub fn bsig0(x: u64) -> u64 {
        x.rotate_right(28) ^ x.rotate_right(34) ^ x.rotate_right(39)
    }

    pub fn bsig1(x: u64) -> u64 {
        x.rotate_right(14) ^ x.rotate_right(18) ^ x.rotate_right(41)
    }

    pub fn ssig0(x: u64) -> u64 {
        x.rotate_right(1) ^ x.rotate_right(8) ^ (x >> 7)
    }

    pub fn ssig1(x: u64) -> u64 {
        x.rotate_right(19) ^ x.rotate_right(61) ^ (x >> 6)
    }

    /// Only supports messages with at most 2^64 - 1 bits for now
    pub fn pad(bytes: &mut Vec<u8>) {
        let len = len(bytes);
        bytes.push(0x80);
        let padding = (128 + 112 - bytes.len() % 128) % 128;
        bytes.extend(iter::repeat(0).take(padding));
        bytes.extend_from_slice(&[0; 8]);
        bytes.extend_from_slice(&len);
    }
}

fn len(bytes: &[u8]) -> [u8; 8] {
    let mut len = [0; 8];
    BigEndian::write_u64(&mut len, 8 * bytes.len() as u64);
    len
}

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

    #[test]
    fn test_pad() {
        let mut message = vec![0b01100001, 0b01100010, 0b01100011, 0b01100100, 0b01100101];
        let expected = h2b(
            "6162636465800000000000000000000000000000000000000000000000000000\
             0000000000000000000000000000000000000000000000000000000000000000\
             0000000000000000000000000000000000000000000000000000000000000000\
             0000000000000000000000000000000000000000000000000000000000000028",
        );
        SHA512::pad(&mut message);
        assert_eq!(expected, message);
    }

    #[test]
    fn test_digest() {
        let expected = h2b(
            "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce\
             47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
        );
        let actual = SHA512::digest(&[]);
        assert_eq!(64, actual.len());
        for (lhs, rhs) in expected.iter().zip(actual.iter()) {
            assert_eq!(lhs, rhs);
        }
    }
}
<commit_msg>sha: make helpers private<commit_after>use std::iter;
use byteorder::{BigEndian, ByteOrder};

pub const K: [u64; 80] = [
    0x428a2f98d728ae22,
    0x7137449123ef65cd,
    0xb5c0fbcfec4d3b2f,
    0xe9b5dba58189dbbc,
    0x3956c25bf348b538,
    0x59f111f1b605d019,
    0x923f82a4af194f9b,
    0xab1c5ed5da6d8118,
    0xd807aa98a3030242,
    0x12835b0145706fbe,
    0x243185be4ee4b28c,
    0x550c7dc3d5ffb4e2,
    0x72be5d74f27b896f,
    0x80deb1fe3b1696b1,
    0x9bdc06a725c71235,
    0xc19bf174cf692694,
    0xe49b69c19ef14ad2,
    0xefbe4786384f25e3,
    0x0fc19dc68b8cd5b5,
    0x240ca1cc77ac9c65,
    0x2de92c6f592b0275,
    0x4a7484aa6ea6e483,
    0x5cb0a9dcbd41fbd4,
    0x76f988da831153b5,
    0x983e5152ee66dfab,
    0xa831c66d2db43210,
    0xb00327c898fb213f,
    0xbf597fc7beef0ee4,
    0xc6e00bf33da88fc2,
    0xd5a79147930aa725,
    0x06ca6351e003826f,
    0x142929670a0e6e70,
    0x27b70a8546d22ffc,
    0x2e1b21385c26c926,
    0x4d2c6dfc5ac42aed,
    0x53380d139d95b3df,
    0x650a73548baf63de,
    0x766a0abb3c77b2a8,
    0x81c2c92e47edaee6,
    0x92722c851482353b,
    0xa2bfe8a14cf10364,
    0xa81a664bbc423001,
    0xc24b8b70d0f89791,
    0xc76c51a30654be30,
    0xd192e819d6ef5218,
    0xd69906245565a910,
    0xf40e35855771202a,
    0x106aa07032bbd1b8,
    0x19a4c116b8d2d0c8,
    0x1e376c085141ab53,
    0x2748774cdf8eeb99,
    0x34b0bcb5e19b48a8,
    0x391c0cb3c5c95a63,
    0x4ed8aa4ae3418acb,
    0x5b9cca4f7763e373,
    0x682e6ff3d6b2b8a3,
    0x748f82ee5defb2fc,
    0x78a5636f43172f60,
    0x84c87814a1f0ab72,
    0x8cc702081a6439ec,
    0x90befffa23631e28,
    0xa4506cebde82bde9,
    0xbef9a3f7b2c67915,
    0xc67178f2e372532b,
    0xca273eceea26619c,
    0xd186b8c721c0c207,
    0xeada7dd6cde0eb1e,
    0xf57d4f7fee6ed178,
    0x06f067aa72176fba,
    0x0a637dc5a2c898a6,
    0x113f9804bef90dae,
    0x1b710b35131c471b,
    0x28db77f523047d84,
    0x32caab7b40c72493,
    0x3c9ebe0a15c9bebc,
    0x431d67c49c100d4c,
    0x4cc5d4becb3e42b6,
    0x597f299cfc657e2a,
    0x5fcb6fab3ad6faec,
    0x6c44198c4a475817,
];

pub struct SHA512 {}

impl SHA512 {
    pub fn digest(message: &[u8]) -> [u8; 64] {
        let mut message = message.to_vec();
        Self::pad(&mut message);
        let mut hash: [u64; 8] = [
            0x6a09e667f3bcc908,
            0xbb67ae8584caa73b,
            0x3c6ef372fe94f82b,
            0xa54ff53a5f1d36f1,
            0x510e527fade682d1,
            0x9b05688c2b3e6c1f,
            0x1f83d9abfb41bd6b,
            0x5be0cd19137e2179,
        ];
        let mut w = [0; 80];
        for chunk in message.chunks(128) {
            for (wt, long) in w.iter_mut().zip(chunk.chunks(8)) {
                *wt = BigEndian::read_u64(long);
            }
            for t in 16..80 {
                w[t] = Self::ssig1(w[t - 2])
                    .wrapping_add(w[t - 7])
                    .wrapping_add(Self::ssig0(w[t - 15]))
                    .wrapping_add(w[t - 16]);
            }
            let mut a = hash[0];
            let mut b = hash[1];
            let mut c = hash[2];
            let mut d = hash[3];
            let mut e = hash[4];
            let mut f = hash[5];
            let mut g = hash[6];
            let mut h = hash[7];
            for (&kt, &wt) in K.iter().zip(w.iter()) {
                let t1 = h.wrapping_add(Self::bsig1(e))
                    .wrapping_add(Self::ch(e, f, g))
                    .wrapping_add(kt)
                    .wrapping_add(wt);
                let t2 = Self::bsig0(a).wrapping_add(Self::maj(a, b, c));
                h = g;
                g = f;
                f = e;
                e = d.wrapping_add(t1);
                d = c;
                c = b;
                b = a;
                a = t1.wrapping_add(t2);
            }
            hash[0] = hash[0].wrapping_add(a);
            hash[1] = hash[1].wrapping_add(b);
            hash[2] = hash[2].wrapping_add(c);
            hash[3] = hash[3].wrapping_add(d);
            hash[4] = hash[4].wrapping_add(e);
            hash[5] = hash[5].wrapping_add(f);
            hash[6] = hash[6].wrapping_add(g);
            hash[7] = hash[7].wrapping_add(h);
        }
        let mut digest = [0; 64];
        for (chunk, &long) in digest.chunks_mut(8).zip(&hash) {
            BigEndian::write_u64(chunk, long);
        }
        digest
    }
    fn ch(x: u64, y: u64, z: u64) -> u64 {
        (x & y) ^ (!x & z)
    }

    fn maj(x: u64, y: u64, z: u64) -> u64 {
        (x & y) ^ (x & z) ^ (y & z)
    }

    fn bsig0(x: u64) -> u64 {
        x.rotate_right(28) ^ x.rotate_right(34) ^ x.rotate_right(39)
    }

    fn bsig1(x: u64) -> u64 {
        x.rotate_right(14) ^ x.rotate_right(18) ^ x.rotate_right(41)
    }

    fn ssig0(x: u64) -> u64 {
        x.rotate_right(1) ^ x.rotate_right(8) ^ (x >> 7)
    }

    fn ssig1(x: u64) -> u64 {
        x.rotate_right(19) ^ x.rotate_right(61) ^ (x >> 6)
    }

    /// Only supports messages with at most 2^64 - 1 bits for now
    fn pad(bytes: &mut Vec<u8>) {
        let len = len(bytes);
        bytes.push(0x80);
        let padding = (128 + 112 - bytes.len() % 128) % 128;
        bytes.extend(iter::repeat(0).take(padding));
        bytes.extend_from_slice(&[0; 8]);
        bytes.extend_from_slice(&len);
    }
}

fn len(bytes: &[u8]) -> [u8; 8] {
    let mut len = [0; 8];
    BigEndian::write_u64(&mut len, 8 * bytes.len() as u64);
    len
}

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

    #[test]
    fn test_pad() {
        let mut message = vec![0b01100001, 0b01100010, 0b01100011, 0b01100100, 0b01100101];
        let expected = h2b(
            "6162636465800000000000000000000000000000000000000000000000000000\
             0000000000000000000000000000000000000000000000000000000000000000\
             0000000000000000000000000000000000000000000000000000000000000000\
             0000000000000000000000000000000000000000000000000000000000000028",
        );
        SHA512::pad(&mut message);
        assert_eq!(expected, message);
    }

    #[test]
    fn test_digest() {
        let expected = h2b(
            "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce\
             47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
        );
        let actual = SHA512::digest(&[]);
        assert_eq!(64, actual.len());
        for (lhs, rhs) in expected.iter().zip(actual.iter()) {
            assert_eq!(lhs, rhs);
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::VecMap;
use std::rand;

use poly::*;

/// Split a secret into N shares, of which K are required to re-combine. Returns
/// a map of share IDs to share values.
pub fn split<'a, T: rand::Rng>(n: u8, k: u8, secret: &'a Vec<u8>, rng: &mut T) -> VecMap<Vec<u8>> {
    // Generate a random K-degree polynomial for each byte of the secret.
    let polys: Vec<Vec<u8>> = secret.iter().map(|b| {
        generate(k-1, *b, rng)
    }).collect();

    // Collect the evaluation of each polynomial with the share ID as the input.
    (1..n+1).map(|id| {
        (id as usize, polys.iter().map(|p| eval(p, id)).collect())
    }).collect()
}

/// Combine a map of share IDs into the original secret.
///
/// N.B.: There is no way to know if this is successful or not.
pub fn combine<'a>(shares: &'a VecMap<Vec<u8>>) -> Vec<u8> {
    let mut points: Vec<Vec<(u8, u8)>> = Vec::new();
    for (id, share) in shares.iter() {
        for (i, v) in share.iter().enumerate() {
            if points.len() <= i {
                points.push(Vec::new())
            }
            points[i].push((id as u8, *v));
        }
    }
    return points.iter().map(|v| interpolate(v, 0)).collect();
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::collections::VecMap;
    use std::rand;

    #[test]
    fn test_split() {
        let mut rng = rand::ChaChaRng::new_unseeded();
        let actual = split(5, 3, &vec![1, 2, 3, 4, 5], &mut rng);

        let mut expected: VecMap<Vec<u8>> = VecMap::new();
        expected.insert(1, vec![118, 163, 66, 80, 187]);
        expected.insert(2, vec![239, 91, 129, 172, 98]);
        expected.insert(3, vec![152, 250, 192, 248, 220]);
        expected.insert(4, vec![198, 176, 28, 79, 203]);
        expected.insert(5, vec![177, 17, 93, 27, 117]);

        assert_eq!(actual, expected)
    }

    #[test]
    fn test_combine() {
        let mut shares: VecMap<Vec<u8>> = VecMap::new();
        shares.insert(1, vec![118, 163, 66, 80, 187]);
        shares.insert(2, vec![239, 91, 129, 172, 98]);
        shares.insert(3, vec![152, 250, 192, 248, 220]);

        assert_eq!(combine(&shares), vec![1, 2, 3, 4, 5])
    }
}
<commit_msg>Don't use return, I guess.<commit_after>use std::collections::VecMap;
use std::rand;

use poly::*;

/// Split a secret into N shares, of which K are required to re-combine. Returns
/// a map of share IDs to share values.
pub fn split<'a, T: rand::Rng>(n: u8, k: u8, secret: &'a Vec<u8>, rng: &mut T) -> VecMap<Vec<u8>> {
    // Generate a random K-degree polynomial for each byte of the secret.
    let polys: Vec<Vec<u8>> = secret.iter().map(|b| {
        generate(k-1, *b, rng)
    }).collect();

    // Collect the evaluation of each polynomial with the share ID as the input.
    (1..n+1).map(|id| {
        (id as usize, polys.iter().map(|p| eval(p, id)).collect())
    }).collect()
}

/// Combine a map of share IDs into the original secret.
///
/// N.B.: There is no way to know if this is successful or not.
pub fn combine<'a>(shares: &'a VecMap<Vec<u8>>) -> Vec<u8> {
    let mut points: Vec<Vec<(u8, u8)>> = Vec::new();
    for (id, share) in shares.iter() {
        for (i, v) in share.iter().enumerate() {
            if points.len() <= i {
                points.push(Vec::new())
            }
            points[i].push((id as u8, *v));
        }
    }
    points.iter().map(|v| interpolate(v, 0)).collect()
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::collections::VecMap;
    use std::rand;

    #[test]
    fn test_split() {
        let mut rng = rand::ChaChaRng::new_unseeded();
        let actual = split(5, 3, &vec![1, 2, 3, 4, 5], &mut rng);

        let mut expected: VecMap<Vec<u8>> = VecMap::new();
        expected.insert(1, vec![118, 163, 66, 80, 187]);
        expected.insert(2, vec![239, 91, 129, 172, 98]);
        expected.insert(3, vec![152, 250, 192, 248, 220]);
        expected.insert(4, vec![198, 176, 28, 79, 203]);
        expected.insert(5, vec![177, 17, 93, 27, 117]);

        assert_eq!(actual, expected)
    }

    #[test]
    fn test_combine() {
        let mut shares: VecMap<Vec<u8>> = VecMap::new();
        shares.insert(1, vec![118, 163, 66, 80, 187]);
        shares.insert(2, vec![239, 91, 129, 172, 98]);
        shares.insert(3, vec![152, 250, 192, 248, 220]);

        assert_eq!(combine(&shares), vec![1, 2, 3, 4, 5])
    }
}
<|endoftext|>