<commit_before>pub enum CoResult<YieldT, CoroT, ReturnT> {
    Yield(YieldT, CoroT),
    Return(ReturnT)
}

trait Coroutine<Input> : Sized {
    type Yield;
    type Return;

    fn next(self, i: Input) -> CoResult<Self::Yield, Self, Self::Return>;
}

macro_rules! each {
    ($iter:expr => $elem:ident $loop_body:block then $then:ident $then_body:block else $else_body:block) => {{
        let mut iter_ = $iter;
        let fin;
        #[allow(unused_assignments)]
        'outer: loop {
            loop {
                match iter_.next(()) {
                    CoResult::Yield($elem, tail) => {
                        iter_ = tail;
                        $loop_body;
                    },
                    CoResult::Return($then) => {
                        fin = $then_body;
                        break 'outer;
                    }
                };
            }
            fin = $else_body;
            break;
        }
        fin
    }};
}

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

    struct Counter<T>{
        i: T,
        lim: T
    }

    impl Coroutine<()> for Counter<i64> {
        type Yield = i64;
        type Return = &'static str;

        fn next(self, _: ()) -> CoResult<Self::Yield, Self, Self::Return> {
            if self.i < self.lim {
                CoResult::Yield(self.i, Counter{i: self.i + 1, lim: self.lim})
            } else {
                CoResult::Return("I'm done!")
            }
        }
    }

    #[test]
    fn it_works() {
        let bart = Counter::<i64>{i: 3, lim: 10};
        assert!(
        match bart.next(()) {
            CoResult::Yield(i, Counter::<i64>{i: j, lim: k}) => {
                assert_eq!(i, 3);
                assert_eq!(j, 4);
                assert_eq!(k, 10);
                true
            },
            CoResult::Return(_) => {
                false
            }
        });
    }

    #[test]
    fn each_works() {
        let bart = Counter::<i64>{i: 3, lim: 10};
        let mut cnt = 3;
        let message = each!(bart => i {
            assert_eq!(i, cnt);
            cnt += 1;
            break;
        } then msg {
            msg
        } else {
            "I got broken"
        });
        assert_eq!(cnt, 4);
        assert_eq!(message, "I got broken");
    }
}
<commit_msg>Allow components of every! to be optional<commit_after>#![feature(never_type)]

pub enum CoResult<YieldT, CoroT, ReturnT> {
    Yield(YieldT, CoroT),
    Return(ReturnT)
}

trait Coroutine<Input> : Sized {
    type Yield;
    type Return;

    fn next(self, i: Input) -> CoResult<Self::Yield, Self, Self::Return>;
}

macro_rules! each {
    ($iter:expr => $elem:ident $loop_body:block then with $then:ident $then_body:block else $else_body:block) => {{
        let mut iter_ = $iter;
        let fin;
        'outer: loop {
            loop {
                #[allow(unused_assignments)]
                match iter_.next(()) {
                    CoResult::Yield($elem, tail) => {
                        iter_ = tail;
                        $loop_body;
                    },
                    CoResult::Return($then) => {
                        fin = $then_body;
                        break 'outer;
                    }
                };
            }
            fin = $else_body;
            break;
        }
        fin
    }};

    ($iter:expr => $elem:ident $loop_body:block then $then_body:block else $else_body:block) => {{
        let mut iter_ = $iter;
        let fin;
        'outer: loop {
            loop {
                #[allow(unused_assignments)]
                match iter_.next(()) {
                    CoResult::Yield($elem, tail) => {
                        iter_ = tail;
                        $loop_body;
                    },
                    CoResult::Return(_) => {
                        fin = $then_body;
                        break 'outer;
                    }
                };
            }
            fin = $else_body;
            break;
        }
        fin
    }};

    ($iter:expr => $elem:ident $loop_body:block then with $then:ident $then_body:block) => {{
        let mut iter_ = $iter;
        let fin;
        'outer: loop {
            #[allow(unused_assignments)]
            match iter_.next(()) {
                CoResult::Yield($elem, tail) => {
                    iter_ = tail;
                    $loop_body;
                },
                CoResult::Return($then) => {
                    fin = $then_body;
                    break 'outer;
                }
            };
        }
        fin
    }};

    ($iter:expr => $elem:ident $loop_body:block then $then_body:block) => {{
        let mut iter_ = $iter;
        let fin;
        'outer: loop {
            #[allow(unused_assignments)]
            match iter_.next(()) {
                CoResult::Yield($elem, tail) => {
                    iter_ = tail;
                    $loop_body;
                },
                CoResult::Return(_) => {
                    fin = $then_body;
                    break 'outer;
                }
            };
        }
        fin
    }};

    ($iter:expr => $elem:ident $loop_body:block else $else_body:block) => {{
        let mut iter_ = $iter;
        let fin;
        'outer: loop {
            loop {
                #[allow(unused_assignments, unreachable_patterns, unreachable_code)]
                match iter_.next(()) {
                    CoResult::Yield($elem, tail) => {
                        iter_ = tail;
                        $loop_body;
                    },
                    CoResult::Return(ret) => {
                        fin = ret;
                        break 'outer;
                    }
                };
            }
            fin = $else_body;
            break;
        }
        fin
    }};

    ($iter:expr => $elem:ident $loop_body:block) => {{
        let mut iter_ = $iter;
        let fin;
        loop {
            #[allow(unused_assignments)]
            match iter_.next(()) {
                CoResult::Yield($elem, tail) => {
                    iter_ = tail;
                    $loop_body;
                },
                CoResult::Return(ret) => {
                    fin = ret;
                    break;
                }
            };
        }
        fin
    }};
}

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

    struct Counter<T>{
        i: T,
        lim: T
    }

    impl Coroutine<()> for Counter<i64> {
        type Yield = i64;
        type Return = &'static str;

        fn next(self, _: ()) -> CoResult<Self::Yield, Self, Self::Return> {
            if self.i < self.lim {
                CoResult::Yield(self.i, Counter{i: self.i + 1, lim: self.lim})
            } else {
                CoResult::Return("I'm done!")
            }
        }
    }

    struct InfiniteCounter<T>{
        i: T
    }

    impl Coroutine<()> for InfiniteCounter<i64> {
        type Yield = i64;
        type Return = !;

        fn next(self, _: ()) -> CoResult<Self::Yield, Self, Self::Return> {
            CoResult::Yield(self.i, InfiniteCounter{i: self.i + 1})
        }
    }

    #[test]
    fn full_each() {
        let bart = Counter::<i64>{i: 3, lim: 10};
        let mut cnt = 3;
        let large_num = 1000;
        let message = each!(bart => i {
            assert_eq!(i, cnt);
            cnt += 1;
            if large_num < 5 { break; }
        } then with msg {
            String::from(msg) + " Yayy!"
        } else {
            String::from("I got broken!")
        });
        assert_eq!(cnt, 10);
        assert_eq!(message, String::from("I'm done! Yayy!"));
    }

    #[test]
    fn full_each_with_break() {
        let bart = Counter::<i64>{i: 3, lim: 10};
        let mut cnt = 3;
        let message = each!(bart => i {
            assert_eq!(i, cnt);
            cnt += 1;
            break;
        } then with msg {
            msg
        } else {
            "I got broken!"
        });
        assert_eq!(cnt, 4);
        assert_eq!(message, "I got broken!");
    }

    #[test]
    fn each_ignore_return() {
        let bart = Counter::<i64>{i: 3, lim: 10};
        let mut cnt = 3;
        let large_number = 1000;
        let message = each!(bart => i {
            assert_eq!(i, cnt);
            cnt += 1;
            if large_number < 5 { break; }
        } then {
            "At last!"
        } else {
            "I got broken!"
        });
        assert_eq!(cnt, 10);
        assert_eq!(message, "At last!");
    }

    #[test]
    fn each_break_no_then() {
        let bart = InfiniteCounter::<i64>{i: 3};
        let mut cnt = 3;
        let message = each!(bart => i {
            assert_eq!(i, cnt);
            cnt += 1;
            if cnt >= 20 { break; }
        } else {
            "I got broken!"
        });
        assert_eq!(cnt, 20);
        assert_eq!(message, "I got broken!");
    }

    #[test]
    fn each_no_else() {
        let bart = Counter::<i64>{i: 3, lim: 10};
        let mut cnt = 3;
        let message = each!(bart => i {
            assert_eq!(i, cnt);
            cnt += 1;
        } then {
            "At last!"
        });
        assert_eq!(cnt, 10);
        assert_eq!(message, "At last!");
    }

    #[test]
    fn each_no_then_else() {
        let bart = Counter::<i64>{i: 3, lim: 10};
        let mut cnt = 3;
        let message = each!(bart => i {
            assert_eq!(i, cnt);
            cnt += 1;
        });
        assert_eq!(cnt, 10);
        assert_eq!(message, "I'm done!");
    }

    #[test]
    fn each_no_then() {
        let bart = Counter::<i64>{i: 3, lim: 10};
        let mut cnt = 3;
        #[allow(unreachable_code)]
        let message = each!(bart => i {
            assert_eq!(i, cnt);
            cnt += 1;
        } else {
            "bogus"
        });
        assert_eq!(cnt, 10);
        assert_eq!(message, "I'm done!");
    }
}
<|endoftext|>


<commit_before>mod convert;

///# aHash
///
/// This hashing algorithm is intended to be a DOS resistant, hardware specific, Hash.
/// This can be seen as a DOS resistant alternative to FxHash, or a fast equivalent to SipHash.
/// It provides a high speed hash algorithm, and is a Keyed hash. This allows it to be used
/// in a HashMap without allowing for the possibility that an malicious user can induce a collision.
///
/// # How aHash works
///
/// aHash uses the hardware AES instruction on x86 processors to provide a keyed hash function.
/// It uses two rounds of AES per hash. So it should not be considered cryptographically secure.

use crate::convert::Convert;
use std::collections::{HashMap};
use std::default::Default;
use std::hash::{BuildHasherDefault, Hasher, BuildHasher};
use std::mem::transmute;

/// A `HashMap` using a `LocationBasedState` BuildHasher to hash the items.
pub type AHashMap<K, V> = HashMap<K, V, LocationBasedState>;

const DEFAULT_KEYS: [u64; 2] = [0x6c62_272e_07bb_0142, 0x517c_c1b7_2722_0a95];

/// Provides a `BuildHasher` is typically used (e.g. by [`HashMap`]) to create
/// [`AHasher`]s for each key such that they are hashed independently of one
/// another, since [`AHasher`]s contain state.
///
/// LocationBasedState uses it's in-memory location to see the AHasher. This
/// is more predictable than true random values, but does not require generating
/// them.
///
/// For each instance of `LocationBasedState`, the [`AHasher`]s created by
/// [`build_hasher`] should be identical. That is, if the same stream of bytes
/// is fed into each hasher, the same output will also be generated.
///
/// # Examples
///
/// ```
/// use ahash::LocationBasedState;
/// use std::hash::{BuildHasher, Hasher};
///
/// let s = LocationBasedState::new();
/// let mut hasher_1 = s.build_hasher();
/// let mut hasher_2 = s.build_hasher();
///
/// hasher_1.write_u32(8128);
/// hasher_2.write_u32(8128);
///
/// assert_eq!(hasher_1.finish(), hasher_2.finish());
/// ```
///
/// [`build_hasher`]: #tymethod.build_hasher
/// [`Hasher`]: trait.Hasher.html
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
pub struct LocationBasedState { }

impl LocationBasedState {
    pub fn new() -> LocationBasedState {
        LocationBasedState{}
    }
}
impl BuildHasher for LocationBasedState {
    type Hasher = AHasher;

    fn build_hasher(&self) -> AHasher {
        let location = self as *const Self as u64;
        AHasher {buffer:[location, location.rotate_left(8)]}
    }
}
impl Default for LocationBasedState {
    fn default() -> LocationBasedState {
        LocationBasedState{}
    }
}

/// A trait for hashing an arbitrary stream of bytes.
///
/// Instances of `AHasher` represent state that is updated while hashing data.
///
/// Each method updates the internal state based on the new data provided. Once
/// all of the data has been provided, the resulting hash can be obtained by calling
/// `finish()`
///
/// #Example
///
/// ```
/// use std::hash::Hasher;
/// use ahash::AHasher;
///
/// let mut hasher = AHasher::new_with_keys(123, 456);
///
/// hasher.write_u32(1989);
/// hasher.write_u8(11);
/// hasher.write_u8(9);
/// hasher.write(b"Huh?");
///
/// println!("Hash is {:x}!", hasher.finish());
/// ```
#[derive(Debug, Clone)]
pub struct AHasher {
    buffer: [u64; 2],
}
impl AHasher {
    pub fn new_with_keys(key0: u64, key1: u64) -> AHasher {
        AHasher { buffer:[key0, key1] }
    }
}
impl Default for AHasher {
    #[inline]
    fn default() -> AHasher {
        AHasher { buffer: [DEFAULT_KEYS[0], DEFAULT_KEYS[1]] }
    }
}

macro_rules! as_array {
    ($input:expr, $len:expr) => {{
        {
            #[inline]
            fn as_array<T>(slice: &[T]) -> &[T; $len] {
                assert_eq!(slice.len(), $len);
                unsafe {
                    &*(slice.as_ptr() as *const [_; $len])
                }
            }
            as_array($input)
        }
    }}
}

//Implementation note: each of the write_XX methods passes the arguments slightly differently to hash.
//This is done so that an u8 and a u64 that both contain the same value will produce different hashes.
impl Hasher for AHasher {
    #[inline]
    fn write_u8(&mut self, i: u8) {
        self.buffer = hash([self.buffer[1], self.buffer[0] ^ i as u64].convert(), self.buffer.convert()).convert();

    }

    #[inline]
    fn write_u16(&mut self, i: u16) {
        self.buffer = hash([self.buffer[1] ^ i as u64, self.buffer[0]].convert(), self.buffer.convert()).convert();

    }

    #[inline]
    fn write_u32(&mut self, i: u32) {
        self.buffer = hash([self.buffer[0], self.buffer[1]  ^ i as u64].convert(), self.buffer.convert()).convert();
    }

    #[inline]
    fn write_u128(&mut self, i: u128) {
        let buffer: u128 = self.buffer.convert();
        self.buffer = hash((buffer ^ i).convert(), self.buffer.convert()).convert();
    }

    #[inline]
    fn write_usize(&mut self, i: usize) {
        self.write_u64(i as u64);
    }

    #[inline]
    fn write_u64(&mut self, i: u64) {
        self.buffer = hash([self.buffer[0] ^ i, self.buffer[1]].convert(), self.buffer.convert()).convert();
    }
    #[inline]
    fn write(&mut self, input: &[u8]) {
        let mut data = input;
        let mut remainder_low: u64 = self.buffer[0];
        let mut remainder_hi: u64 = self.buffer[1];
        if data.len() >= 16 {
            while data.len() >= 16 {
                let (block, rest) = data.split_at(16);
                let block: &[u8; 16] = as_array!(block, 16);
                self.buffer = hash(self.buffer.convert(), *block).convert();
                data = rest;
            }
            self.buffer = hash(self.buffer.convert(), self.buffer.convert()).convert();
        }
        if data.len() >= 8 {
            let (block, rest) = data.split_at(8);
            let val: u64 = as_array!(block, 8).convert();
            remainder_hi ^= val;
            remainder_hi = remainder_hi.rotate_left(32);
            data = rest;
        }
        if data.len() >= 4 {
            let (block, rest) = data.split_at(4);
            let val: u32 = as_array!(block, 4).convert();
            remainder_low ^= val as u64;
            remainder_low = remainder_low.rotate_left(32);
            data = rest;
        }
        if data.len() >= 2 {
            let (block, rest) = data.split_at(2);
            let val: u16 = as_array!(block, 2).convert();
            remainder_low ^= val as u64;
            remainder_low = remainder_low.rotate_left(16);
            data = rest;
        }
        if data.len() >= 1 {
            remainder_low ^= data[0] as u64;
            remainder_low = remainder_low.rotate_left(8);
        }
        self.buffer = hash([remainder_low, remainder_hi].convert(), self.buffer.convert()).convert();
    }
    #[inline]
    fn finish(&self) -> u64 {
        let result: [u64; 2] = hash(self.buffer.convert(), self.buffer.convert()).convert();
        result[0]//.wrapping_add(result[1])
    }
}

#[inline(always)]
fn hash(value: [u8; 16], xor: [u8; 16]) -> [u8; 16] {
    #[cfg(target_arch = "x86")]
    use core::arch::x86::*;
    #[cfg(target_arch = "x86_64")]
    use std::arch::x86_64::*;
    unsafe {
        let value = transmute(value);
        transmute(_mm_aesenc_si128(value, transmute(xor)))
    }
}

#[cfg(all(
    any(target_arch = "x86", target_arch = "x86_64"),
    target_feature = "aes"
))]
#[cfg(test)]
mod tests {
    use crate::convert::Convert;
    use crate::*;

    #[test]
    fn test_builder() {
        let mut map = HashMap::<u32, u64, LocationBasedState>::default();
        map.insert(1, 3);
    }

    #[test]
    fn test_location_based_state() {
        let state = LocationBasedState::new();
        let hasher_a = state.build_hasher();
        assert_ne!(0, hasher_a.buffer[0]);
        assert_ne!(0, hasher_a.buffer[1]);
        assert_ne!(hasher_a.buffer[0], AHasher::default().buffer[0]);
        assert_ne!(hasher_a.buffer[1], AHasher::default().buffer[1]);
        let hasher_b = state.build_hasher();
        assert_eq!(hasher_a.buffer[0], hasher_b.buffer[0]);
        assert_eq!(hasher_a.buffer[1], hasher_b.buffer[1]);
    }

    #[test]
    fn test_hash() {
        let mut result: [u64; 2] = [0x6c62272e07bb0142, 0x62b821756295c58d];
        let value: [u64; 2] = [1 << 32, 0xFEDCBA9876543210];
        result = hash(value.convert(), result.convert()).convert();
        result = hash(result.convert(), result.convert()).convert();
        let mut result2: [u64; 2] = [0x6c62272e07bb0142, 0x62b821756295c58d];
        let value2: [u64; 2] = [1, 0xFEDCBA9876543210];
        result2 = hash(value2.convert(), result2.convert()).convert();
        result2 = hash(result2.convert(), result.convert()).convert();
        let result: [u8; 16] = result.convert();
        let result2: [u8; 16] = result2.convert();
        assert_ne!(hex::encode(result), hex::encode(result2));
    }
    #[test]
    fn test_conversion() {
        let input: &[u8] = "dddddddd".as_bytes();
        let bytes: u64 = as_array!(input, 8).convert();
        assert_eq!(bytes, 0x6464646464646464);
    }

}
<commit_msg>fix minor copy and paste error<commit_after>mod convert;

///# aHash
///
/// This hashing algorithm is intended to be a DOS resistant, hardware specific, Hash.
/// This can be seen as a DOS resistant alternative to FxHash, or a fast equivalent to SipHash.
/// It provides a high speed hash algorithm, and is a Keyed hash. This allows it to be used
/// in a HashMap without allowing for the possibility that an malicious user can induce a collision.
///
/// # How aHash works
///
/// aHash uses the hardware AES instruction on x86 processors to provide a keyed hash function.
/// It uses two rounds of AES per hash. So it should not be considered cryptographically secure.

use crate::convert::Convert;
use std::collections::{HashMap};
use std::default::Default;
use std::hash::{BuildHasherDefault, Hasher, BuildHasher};
use std::mem::transmute;

/// A `HashMap` using a `LocationBasedState` BuildHasher to hash the items.
pub type AHashMap<K, V> = HashMap<K, V, LocationBasedState>;

const DEFAULT_KEYS: [u64; 2] = [0x6c62_272e_07bb_0142, 0x517c_c1b7_2722_0a95];

/// Provides a `BuildHasher` is typically used (e.g. by [`HashMap`]) to create
/// [`AHasher`]s for each key such that they are hashed independently of one
/// another, since [`AHasher`]s contain state.
///
/// LocationBasedState uses it's in-memory location to see the AHasher. This
/// is more predictable than true random values, but does not require generating
/// them.
///
/// For each instance of `LocationBasedState`, the [`AHasher`]s created by
/// [`build_hasher`] should be identical. That is, if the same stream of bytes
/// is fed into each hasher, the same output will also be generated.
///
/// # Examples
///
/// ```
/// use ahash::LocationBasedState;
/// use std::hash::{BuildHasher, Hasher};
///
/// let s = LocationBasedState::new();
/// let mut hasher_1 = s.build_hasher();
/// let mut hasher_2 = s.build_hasher();
///
/// hasher_1.write_u32(8128);
/// hasher_2.write_u32(8128);
///
/// assert_eq!(hasher_1.finish(), hasher_2.finish());
/// ```
///
/// [`build_hasher`]: #tymethod.build_hasher
/// [`Hasher`]: trait.Hasher.html
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
pub struct LocationBasedState { }

impl LocationBasedState {
    pub fn new() -> LocationBasedState {
        LocationBasedState{}
    }
}
impl BuildHasher for LocationBasedState {
    type Hasher = AHasher;

    fn build_hasher(&self) -> AHasher {
        let location = self as *const Self as u64;
        AHasher {buffer:[location, location.rotate_left(8)]}
    }
}
impl Default for LocationBasedState {
    fn default() -> LocationBasedState {
        LocationBasedState{}
    }
}

/// A `Hasher` for hashing an arbitrary stream of bytes.
///
/// Instances of `AHasher` represent state that is updated while hashing data.
///
/// Each method updates the internal state based on the new data provided. Once
/// all of the data has been provided, the resulting hash can be obtained by calling
/// `finish()`
///
/// #Example
///
/// ```
/// use std::hash::Hasher;
/// use ahash::AHasher;
///
/// let mut hasher = AHasher::new_with_keys(123, 456);
///
/// hasher.write_u32(1989);
/// hasher.write_u8(11);
/// hasher.write_u8(9);
/// hasher.write(b"Huh?");
///
/// println!("Hash is {:x}!", hasher.finish());
/// ```
#[derive(Debug, Clone)]
pub struct AHasher {
    buffer: [u64; 2],
}
impl AHasher {
    pub fn new_with_keys(key0: u64, key1: u64) -> AHasher {
        AHasher { buffer:[key0, key1] }
    }
}
impl Default for AHasher {
    #[inline]
    fn default() -> AHasher {
        AHasher { buffer: [DEFAULT_KEYS[0], DEFAULT_KEYS[1]] }
    }
}

macro_rules! as_array {
    ($input:expr, $len:expr) => {{
        {
            #[inline]
            fn as_array<T>(slice: &[T]) -> &[T; $len] {
                assert_eq!(slice.len(), $len);
                unsafe {
                    &*(slice.as_ptr() as *const [_; $len])
                }
            }
            as_array($input)
        }
    }}
}

//Implementation note: each of the write_XX methods passes the arguments slightly differently to hash.
//This is done so that an u8 and a u64 that both contain the same value will produce different hashes.
impl Hasher for AHasher {
    #[inline]
    fn write_u8(&mut self, i: u8) {
        self.buffer = hash([self.buffer[1], self.buffer[0] ^ i as u64].convert(), self.buffer.convert()).convert();

    }

    #[inline]
    fn write_u16(&mut self, i: u16) {
        self.buffer = hash([self.buffer[1] ^ i as u64, self.buffer[0]].convert(), self.buffer.convert()).convert();

    }

    #[inline]
    fn write_u32(&mut self, i: u32) {
        self.buffer = hash([self.buffer[0], self.buffer[1]  ^ i as u64].convert(), self.buffer.convert()).convert();
    }

    #[inline]
    fn write_u128(&mut self, i: u128) {
        let buffer: u128 = self.buffer.convert();
        self.buffer = hash((buffer ^ i).convert(), self.buffer.convert()).convert();
    }

    #[inline]
    fn write_usize(&mut self, i: usize) {
        self.write_u64(i as u64);
    }

    #[inline]
    fn write_u64(&mut self, i: u64) {
        self.buffer = hash([self.buffer[0] ^ i, self.buffer[1]].convert(), self.buffer.convert()).convert();
    }
    #[inline]
    fn write(&mut self, input: &[u8]) {
        let mut data = input;
        let mut remainder_low: u64 = self.buffer[0];
        let mut remainder_hi: u64 = self.buffer[1];
        if data.len() >= 16 {
            while data.len() >= 16 {
                let (block, rest) = data.split_at(16);
                let block: &[u8; 16] = as_array!(block, 16);
                self.buffer = hash(self.buffer.convert(), *block).convert();
                data = rest;
            }
            self.buffer = hash(self.buffer.convert(), self.buffer.convert()).convert();
        }
        if data.len() >= 8 {
            let (block, rest) = data.split_at(8);
            let val: u64 = as_array!(block, 8).convert();
            remainder_hi ^= val;
            remainder_hi = remainder_hi.rotate_left(32);
            data = rest;
        }
        if data.len() >= 4 {
            let (block, rest) = data.split_at(4);
            let val: u32 = as_array!(block, 4).convert();
            remainder_low ^= val as u64;
            remainder_low = remainder_low.rotate_left(32);
            data = rest;
        }
        if data.len() >= 2 {
            let (block, rest) = data.split_at(2);
            let val: u16 = as_array!(block, 2).convert();
            remainder_low ^= val as u64;
            remainder_low = remainder_low.rotate_left(16);
            data = rest;
        }
        if data.len() >= 1 {
            remainder_low ^= data[0] as u64;
            remainder_low = remainder_low.rotate_left(8);
        }
        self.buffer = hash([remainder_low, remainder_hi].convert(), self.buffer.convert()).convert();
    }
    #[inline]
    fn finish(&self) -> u64 {
        let result: [u64; 2] = hash(self.buffer.convert(), self.buffer.convert()).convert();
        result[0]//.wrapping_add(result[1])
    }
}

#[inline(always)]
fn hash(value: [u8; 16], xor: [u8; 16]) -> [u8; 16] {
    #[cfg(target_arch = "x86")]
    use core::arch::x86::*;
    #[cfg(target_arch = "x86_64")]
    use std::arch::x86_64::*;
    unsafe {
        let value = transmute(value);
        transmute(_mm_aesenc_si128(value, transmute(xor)))
    }
}

#[cfg(all(
    any(target_arch = "x86", target_arch = "x86_64"),
    target_feature = "aes"
))]
#[cfg(test)]
mod tests {
    use crate::convert::Convert;
    use crate::*;

    #[test]
    fn test_builder() {
        let mut map = HashMap::<u32, u64, LocationBasedState>::default();
        map.insert(1, 3);
    }

    #[test]
    fn test_location_based_state() {
        let state = LocationBasedState::new();
        let hasher_a = state.build_hasher();
        assert_ne!(0, hasher_a.buffer[0]);
        assert_ne!(0, hasher_a.buffer[1]);
        assert_ne!(hasher_a.buffer[0], AHasher::default().buffer[0]);
        assert_ne!(hasher_a.buffer[1], AHasher::default().buffer[1]);
        let hasher_b = state.build_hasher();
        assert_eq!(hasher_a.buffer[0], hasher_b.buffer[0]);
        assert_eq!(hasher_a.buffer[1], hasher_b.buffer[1]);
    }

    #[test]
    fn test_hash() {
        let mut result: [u64; 2] = [0x6c62272e07bb0142, 0x62b821756295c58d];
        let value: [u64; 2] = [1 << 32, 0xFEDCBA9876543210];
        result = hash(value.convert(), result.convert()).convert();
        result = hash(result.convert(), result.convert()).convert();
        let mut result2: [u64; 2] = [0x6c62272e07bb0142, 0x62b821756295c58d];
        let value2: [u64; 2] = [1, 0xFEDCBA9876543210];
        result2 = hash(value2.convert(), result2.convert()).convert();
        result2 = hash(result2.convert(), result.convert()).convert();
        let result: [u8; 16] = result.convert();
        let result2: [u8; 16] = result2.convert();
        assert_ne!(hex::encode(result), hex::encode(result2));
    }
    #[test]
    fn test_conversion() {
        let input: &[u8] = "dddddddd".as_bytes();
        let bytes: u64 = as_array!(input, 8).convert();
        assert_eq!(bytes, 0x6464646464646464);
    }

}
<|endoftext|>


<commit_before>//! A [TOML]-parsing library
//!
//! This library implements a [TOML] v0.4.0 compatible parser,
//! primarily supporting the [`serde`] library for encoding/decoding
//! various types in Rust.
//!
//! TOML itself is a simple, ergonomic, and readable configuration format:
//!
//! ```toml
//! [package]
//! name = "toml"
//! version = "0.2.1"
//! authors = ["Alex Crichton <alex@alexcrichton.com>"]
//!
//! [dependencies]
//! serde = "0.9"
//! ```
//!
//! The TOML format tends to be relatively common throughout the Rust community
//! for configuration, notably being used by [Cargo], Rust's package manager.
//!
//! ## TOML values
//!
//! A value in TOML is represented with the `Value` enum in this crate:
//!
//! ```rust,ignore
//! pub enum Value {
//!     String(String),
//!     Integer(i64),
//!     Float(f64),
//!     Boolean(bool),
//!     Datetime(Datetime),
//!     Array(Array),
//!     Table(Table),
//! }
//! ```
//!
//! TOML is similar to JSON with the notable addition of a `Datetime`
//! type. In general, TOML and JSON are interchangeable in terms of
//! formats.
//!
//! ## Parsing TOML
//!
//! The easiest way to parse a TOML document is via the `Value` type:
//!
//! ```rust
//! use toml::Value;
//!
//! let value = "foo = 'bar'".parse::<Value>().unwrap();
//!
//! assert_eq!(value["foo"].as_str(), Some("bar"));
//! ```
//!
//! The `Value` type implements a number of convenience methods and
//! traits; the example above uses `FromStr` to parse a `str` into a
//! `Value`.
//!
//! ## Deserialization and Serialization
//!
//! This crate supports [`serde`] 0.9 with a number of
//! implementations of the `Deserialize`, `Serialize`, `Deserializer`, and
//! `Serializer` traits. Namely, you'll find:
//!
//! * `Deserialize for Value`
//! * `Serialize for Value`
//! * `Deserialize for Datetime`
//! * `Serialize for Datetime`
//! * `Deserializer for de::Deserializer`
//! * `Serializer for ser::Serializer`
//! * `Deserializer for Value`
//!
//! This means that you can use Serde to deserialize/serialize the
//! `Value` type as well as the `Datetime` type in this crate. You can also
//! use the `Deserializer`, `Serializer`, or `Value` type itself to act as
//! a deserializer/serializer for arbitrary types.
//!
//! An example of deserializing with TOML is:
//!
//! ```rust
//! #[macro_use]
//! extern crate serde_derive;
//! extern crate toml;
//!
//! #[derive(Deserialize)]
//! struct Config {
//!     ip: String,
//!     port: Option<u16>,
//!     keys: Keys,
//! }
//!
//! #[derive(Deserialize)]
//! struct Keys {
//!     github: String,
//!     travis: Option<String>,
//! }
//!
//! fn main() {
//!     let config: Config = toml::from_str(r#"
//!         ip = '127.0.0.1'
//!
//!         [keys]
//!         github = 'xxxxxxxxxxxxxxxxx'
//!         travis = 'yyyyyyyyyyyyyyyyy'
//!     "#).unwrap();
//!
//!     assert_eq!(config.ip, "127.0.0.1");
//!     assert_eq!(config.port, None);
//!     assert_eq!(config.keys.github, "xxxxxxxxxxxxxxxxx");
//!     assert_eq!(config.keys.travis.as_ref().unwrap(), "yyyyyyyyyyyyyyyyy");
//! }
//! ```
//!
//! You can serialize types in a similar fashion:
//!
//! ```rust
//! #[macro_use]
//! extern crate serde_derive;
//! extern crate toml;
//!
//! #[derive(Serialize)]
//! struct Config {
//!     ip: String,
//!     port: Option<u16>,
//!     keys: Keys,
//! }
//!
//! #[derive(Serialize)]
//! struct Keys {
//!     github: String,
//!     travis: Option<String>,
//! }
//!
//! fn main() {
//!     let config = Config {
//!         ip: "127.0.0.1".to_string(),
//!         port: None,
//!         keys: Keys {
//!             github: "xxxxxxxxxxxxxxxxx".to_string(),
//!             travis: Some("yyyyyyyyyyyyyyyyy".to_string()),
//!         },
//!     };
//!
//!     let toml = toml::to_string(&config).unwrap();
//! }
//! ```
//!
//! [TOML]: https://github.com/toml-lang/toml
//! [Cargo]: https://crates.io/
//! [`serde`]: https://serde.rs/

#![doc(html_root_url = "https://docs.rs/toml/0.3")]
#![deny(missing_docs)]

#[macro_use]
extern crate serde;

pub mod value;
#[doc(no_inline)]
pub use value::Value;
mod datetime;

pub mod ser;
#[doc(no_inline)]
pub use ser::{to_string, to_vec, Serializer};
pub mod de;
#[doc(no_inline)]
pub use de::{from_slice, from_str, Deserializer};
mod tokens;
<commit_msg>Fixed the serde dependency in the documentation<commit_after>//! A [TOML]-parsing library
//!
//! This library implements a [TOML] v0.4.0 compatible parser,
//! primarily supporting the [`serde`] library for encoding/decoding
//! various types in Rust.
//!
//! TOML itself is a simple, ergonomic, and readable configuration format:
//!
//! ```toml
//! [package]
//! name = "toml"
//! version = "0.2.1"
//! authors = ["Alex Crichton <alex@alexcrichton.com>"]
//!
//! [dependencies]
//! serde = "1.0"
//! ```
//!
//! The TOML format tends to be relatively common throughout the Rust community
//! for configuration, notably being used by [Cargo], Rust's package manager.
//!
//! ## TOML values
//!
//! A value in TOML is represented with the `Value` enum in this crate:
//!
//! ```rust,ignore
//! pub enum Value {
//!     String(String),
//!     Integer(i64),
//!     Float(f64),
//!     Boolean(bool),
//!     Datetime(Datetime),
//!     Array(Array),
//!     Table(Table),
//! }
//! ```
//!
//! TOML is similar to JSON with the notable addition of a `Datetime`
//! type. In general, TOML and JSON are interchangeable in terms of
//! formats.
//!
//! ## Parsing TOML
//!
//! The easiest way to parse a TOML document is via the `Value` type:
//!
//! ```rust
//! use toml::Value;
//!
//! let value = "foo = 'bar'".parse::<Value>().unwrap();
//!
//! assert_eq!(value["foo"].as_str(), Some("bar"));
//! ```
//!
//! The `Value` type implements a number of convenience methods and
//! traits; the example above uses `FromStr` to parse a `str` into a
//! `Value`.
//!
//! ## Deserialization and Serialization
//!
//! This crate supports [`serde`] 0.9 with a number of
//! implementations of the `Deserialize`, `Serialize`, `Deserializer`, and
//! `Serializer` traits. Namely, you'll find:
//!
//! * `Deserialize for Value`
//! * `Serialize for Value`
//! * `Deserialize for Datetime`
//! * `Serialize for Datetime`
//! * `Deserializer for de::Deserializer`
//! * `Serializer for ser::Serializer`
//! * `Deserializer for Value`
//!
//! This means that you can use Serde to deserialize/serialize the
//! `Value` type as well as the `Datetime` type in this crate. You can also
//! use the `Deserializer`, `Serializer`, or `Value` type itself to act as
//! a deserializer/serializer for arbitrary types.
//!
//! An example of deserializing with TOML is:
//!
//! ```rust
//! #[macro_use]
//! extern crate serde_derive;
//! extern crate toml;
//!
//! #[derive(Deserialize)]
//! struct Config {
//!     ip: String,
//!     port: Option<u16>,
//!     keys: Keys,
//! }
//!
//! #[derive(Deserialize)]
//! struct Keys {
//!     github: String,
//!     travis: Option<String>,
//! }
//!
//! fn main() {
//!     let config: Config = toml::from_str(r#"
//!         ip = '127.0.0.1'
//!
//!         [keys]
//!         github = 'xxxxxxxxxxxxxxxxx'
//!         travis = 'yyyyyyyyyyyyyyyyy'
//!     "#).unwrap();
//!
//!     assert_eq!(config.ip, "127.0.0.1");
//!     assert_eq!(config.port, None);
//!     assert_eq!(config.keys.github, "xxxxxxxxxxxxxxxxx");
//!     assert_eq!(config.keys.travis.as_ref().unwrap(), "yyyyyyyyyyyyyyyyy");
//! }
//! ```
//!
//! You can serialize types in a similar fashion:
//!
//! ```rust
//! #[macro_use]
//! extern crate serde_derive;
//! extern crate toml;
//!
//! #[derive(Serialize)]
//! struct Config {
//!     ip: String,
//!     port: Option<u16>,
//!     keys: Keys,
//! }
//!
//! #[derive(Serialize)]
//! struct Keys {
//!     github: String,
//!     travis: Option<String>,
//! }
//!
//! fn main() {
//!     let config = Config {
//!         ip: "127.0.0.1".to_string(),
//!         port: None,
//!         keys: Keys {
//!             github: "xxxxxxxxxxxxxxxxx".to_string(),
//!             travis: Some("yyyyyyyyyyyyyyyyy".to_string()),
//!         },
//!     };
//!
//!     let toml = toml::to_string(&config).unwrap();
//! }
//! ```
//!
//! [TOML]: https://github.com/toml-lang/toml
//! [Cargo]: https://crates.io/
//! [`serde`]: https://serde.rs/

#![doc(html_root_url = "https://docs.rs/toml/0.3")]
#![deny(missing_docs)]

#[macro_use]
extern crate serde;

pub mod value;
#[doc(no_inline)]
pub use value::Value;
mod datetime;

pub mod ser;
#[doc(no_inline)]
pub use ser::{to_string, to_vec, Serializer};
pub mod de;
#[doc(no_inline)]
pub use de::{from_slice, from_str, Deserializer};
mod tokens;
<|endoftext|>


<commit_before>use std::ops::{BitOrAssign, Shl, ShlAssign, ShrAssign, BitAnd};

pub mod read;
pub mod write;

pub use read::BitRead;
pub use read::BitReaderBE;
pub use read::BitReaderLE;

pub use write::BitWrite;
pub use write::BitWriterBE;
pub use write::BitWriterLE;

pub trait Numeric: Sized + Copy + Default +
    ShlAssign<Self> + ShrAssign<Self> + Shl<u32,Output=Self> +
    BitOrAssign<Self> + BitAnd<Self,Output=Self> {
    fn one() -> Self;
    fn from_bit(bit: bool) -> Self;
    fn to_bit(self) -> bool;
}

impl Numeric for u8 {
    #[inline]
    fn one() -> Self {1}
    #[inline]
    fn from_bit(bit: bool) -> Self {if bit {1} else {0}}
    #[inline]
    fn to_bit(self) -> bool {self != 0}
}

impl Numeric for u16 {
    #[inline]
    fn one() -> Self {1}
    #[inline]
    fn from_bit(bit: bool) -> Self {if bit {1} else {0}}
    #[inline]
    fn to_bit(self) -> bool {self != 0}
}

impl Numeric for u32 {
    #[inline]
    fn one() -> Self {1}
    #[inline]
    fn from_bit(bit: bool) -> Self {if bit {1} else {0}}
    #[inline]
    fn to_bit(self) -> bool {self != 0}
}

impl Numeric for u64 {
    #[inline]
    fn one() -> Self {1}
    #[inline]
    fn from_bit(bit: bool) -> Self {if bit {1} else {0}}
    #[inline]
    fn to_bit(self) -> bool {self != 0}
}
<commit_msg>Add stronger inline suggestion to some trivial methods<commit_after>use std::ops::{BitOrAssign, Shl, ShlAssign, ShrAssign, BitAnd};

pub mod read;
pub mod write;

pub use read::BitRead;
pub use read::BitReaderBE;
pub use read::BitReaderLE;

pub use write::BitWrite;
pub use write::BitWriterBE;
pub use write::BitWriterLE;

pub trait Numeric: Sized + Copy + Default +
    ShlAssign<Self> + ShrAssign<Self> + Shl<u32,Output=Self> +
    BitOrAssign<Self> + BitAnd<Self,Output=Self> {
    fn one() -> Self;
    fn from_bit(bit: bool) -> Self;
    fn to_bit(self) -> bool;
}

impl Numeric for u8 {
    #[inline(always)]
    fn one() -> Self {1}
    #[inline(always)]
    fn from_bit(bit: bool) -> Self {if bit {1} else {0}}
    #[inline(always)]
    fn to_bit(self) -> bool {self != 0}
}

impl Numeric for u16 {
    #[inline(always)]
    fn one() -> Self {1}
    #[inline(always)]
    fn from_bit(bit: bool) -> Self {if bit {1} else {0}}
    #[inline(always)]
    fn to_bit(self) -> bool {self != 0}
}

impl Numeric for u32 {
    #[inline(always)]
    fn one() -> Self {1}
    #[inline(always)]
    fn from_bit(bit: bool) -> Self {if bit {1} else {0}}
    #[inline(always)]
    fn to_bit(self) -> bool {self != 0}
}

impl Numeric for u64 {
    #[inline(always)]
    fn one() -> Self {1}
    #[inline(always)]
    fn from_bit(bit: bool) -> Self {if bit {1} else {0}}
    #[inline(always)]
    fn to_bit(self) -> bool {self != 0}
}
<|endoftext|>


<commit_before>#![allow(unstable)]

use std::default::Default;
use std::cmp::Ordering;
use std::cell::Cell;
use std::hash::{self, Hash};
use std::collections::hash_map::Hasher;
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::RingBuf;
use std::collections::BitvSet;
use std::collections::BinaryHeap;
use std::collections::hash_map::Entry::{
    Occupied,
    Vacant,
};
use std::fmt;
use std::ops::{Add, Deref};

pub use scored::MinScored;
pub use digraph::DiGraph;
pub use graph::Graph;
pub use ograph::OGraph;
use ograph::{
    EdgeType,
};

pub use self::EdgeDirection::{Outgoing, Incoming};
pub use visit::{
    Dfs,
    DfsIter,
    BreadthFirst,
};
use visit::VisitMap;

mod scored;
pub mod digraph;
pub mod graph;
pub mod ograph;
pub mod visit;

pub mod unionfind;

// Index into the NodeIndex and EdgeIndex arrays
/// Edge direction
#[derive(Copy, Clone, Show, PartialEq)]
pub enum EdgeDirection {
    /// A **Outgoing** edge is an outward edge *from* the current node.
    Outgoing = 0,
    /// An **Incoming** edge is an inbound edge *to* the current node.
    Incoming = 1
}

/// A reference that is hashed and compared by its pointer value.
pub struct Ptr<'b, T: 'b>(pub &'b T);

impl<'b, T> Copy for Ptr<'b, T> {}
impl<'b, T> Clone for Ptr<'b, T>
{
    fn clone(&self) -> Self { *self }
}

fn ptreq<T>(a: &T, b: &T) -> bool {
    a as *const _ == b as *const _
}

impl<'b, T> PartialEq for Ptr<'b, T>
{
    /// Ptr compares by pointer equality, i.e if they point to the same value
    fn eq(&self, other: &Ptr<'b, T>) -> bool {
        ptreq(self.0, other.0)
    }
}

impl<'b, T> PartialOrd for Ptr<'b, T>
{
    fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'b, T> Ord for Ptr<'b, T>
{
    /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order.
    fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
        let a = self.0 as *const _;
        let b = other.0 as *const _;
        a.cmp(&b)
    }
}

impl<'b, T> Deref for Ptr<'b, T> {
    type Target = T;
    fn deref<'a>(&'a self) -> &'a T {
        self.0
    }
}

impl<'b, T> Eq for Ptr<'b, T> {}

impl<'b, T, H: hash::Writer + hash::Hasher> Hash<H> for Ptr<'b, T>
{
    fn hash(&self, st: &mut H)
    {
        let ptr = (self.0) as *const _;
        ptr.hash(st)
    }
}

impl<'b, T: fmt::Show> fmt::Show for Ptr<'b, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// Dijkstra's shortest path algorithm.
pub fn dijkstra<'a, G, N, K, F, Edges>(graph: &'a G,
                                           start: N,
                                           goal: Option<N>,
                                           mut edges: F) -> HashMap<N, K> where
    G: visit::Visitable<NodeId=N>,
    N: Copy + Clone + Eq + Hash<Hasher> + fmt::Show,
    K: Default + Add<Output=K> + Copy + PartialOrd + fmt::Show,
    F: FnMut(&'a G, N) -> Edges,
    Edges: Iterator<Item=(N, K)>,
    <G as visit::Visitable>::Map: VisitMap<N>,
{
    let mut visited = graph.visit_map();
    let mut scores = HashMap::new();
    let mut predecessor = HashMap::new();
    let mut visit_next = BinaryHeap::new();
    let zero_score: K = Default::default();
    scores.insert(start, zero_score);
    visit_next.push(MinScored(zero_score, start));
    while let Some(MinScored(node_score, node)) = visit_next.pop() {
        if visited.contains(&node) {
            continue
        }
        for (next, edge) in edges(graph, node) {
            if visited.contains(&next) {
                continue
            }
            let mut next_score = node_score + edge;
            match scores.entry(next) {
                Occupied(ent) => if next_score < *ent.get() {
                    *ent.into_mut() = next_score;
                    predecessor.insert(next, node);
                } else {
                    next_score = *ent.get();
                },
                Vacant(ent) => {
                    ent.insert(next_score);
                    predecessor.insert(next, node);
                }
            }
            visit_next.push(MinScored(next_score, next));
        }
        if goal.as_ref() == Some(&node) {
            break
        }
        visited.visit(node);
    }
    scores
}

#[derive(Show)]
pub struct Node<T>(pub T);

pub struct NodeCell<T: Copy>(pub Cell<T>);

impl<T: Copy> Deref for NodeCell<T> {
    type Target = Cell<T>;
    #[inline]
    fn deref(&self) -> &Cell<T> {
        &self.0
    }
}

impl<T: Copy + fmt::Show> fmt::Show for NodeCell<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Node({:?})", self.0.get())
    }
}
<commit_msg>Cleanup dijkstra<commit_after>#![allow(unstable)]

use std::default::Default;
use std::cmp::Ordering;
use std::cell::Cell;
use std::hash::{self, Hash};
use std::collections::hash_map::Hasher;
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::RingBuf;
use std::collections::BitvSet;
use std::collections::BinaryHeap;
use std::collections::hash_map::Entry::{
    Occupied,
    Vacant,
};
use std::fmt;
use std::ops::{Add, Deref};

pub use scored::MinScored;
pub use digraph::DiGraph;
pub use graph::Graph;
pub use ograph::OGraph;
use ograph::{
    EdgeType,
};

pub use self::EdgeDirection::{Outgoing, Incoming};
pub use visit::{
    Dfs,
    DfsIter,
    BreadthFirst,
};
use visit::VisitMap;

mod scored;
pub mod digraph;
pub mod graph;
pub mod ograph;
pub mod visit;

pub mod unionfind;

// Index into the NodeIndex and EdgeIndex arrays
/// Edge direction
#[derive(Copy, Clone, Show, PartialEq)]
pub enum EdgeDirection {
    /// A **Outgoing** edge is an outward edge *from* the current node.
    Outgoing = 0,
    /// An **Incoming** edge is an inbound edge *to* the current node.
    Incoming = 1
}

/// A reference that is hashed and compared by its pointer value.
pub struct Ptr<'b, T: 'b>(pub &'b T);

impl<'b, T> Copy for Ptr<'b, T> {}
impl<'b, T> Clone for Ptr<'b, T>
{
    fn clone(&self) -> Self { *self }
}

fn ptreq<T>(a: &T, b: &T) -> bool {
    a as *const _ == b as *const _
}

impl<'b, T> PartialEq for Ptr<'b, T>
{
    /// Ptr compares by pointer equality, i.e if they point to the same value
    fn eq(&self, other: &Ptr<'b, T>) -> bool {
        ptreq(self.0, other.0)
    }
}

impl<'b, T> PartialOrd for Ptr<'b, T>
{
    fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'b, T> Ord for Ptr<'b, T>
{
    /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order.
    fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
        let a = self.0 as *const _;
        let b = other.0 as *const _;
        a.cmp(&b)
    }
}

impl<'b, T> Deref for Ptr<'b, T> {
    type Target = T;
    fn deref<'a>(&'a self) -> &'a T {
        self.0
    }
}

impl<'b, T> Eq for Ptr<'b, T> {}

impl<'b, T, H: hash::Writer + hash::Hasher> Hash<H> for Ptr<'b, T>
{
    fn hash(&self, st: &mut H)
    {
        let ptr = (self.0) as *const _;
        ptr.hash(st)
    }
}

impl<'b, T: fmt::Show> fmt::Show for Ptr<'b, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// Dijkstra's shortest path algorithm.
pub fn dijkstra<'a, G, N, K, F, Edges>(graph: &'a G,
                                       start: N,
                                       goal: Option<N>,
                                       mut edges: F) -> HashMap<N, K> where
    G: visit::Visitable<NodeId=N>,
    N: Clone + Eq + Hash<Hasher>,
    K: Default + Add<Output=K> + Copy + PartialOrd,
    F: FnMut(&'a G, N) -> Edges,
    Edges: Iterator<Item=(N, K)>,
    <G as visit::Visitable>::Map: VisitMap<N>,
{
    let mut visited = graph.visit_map();
    let mut scores = HashMap::new();
    let mut predecessor = HashMap::new();
    let mut visit_next = BinaryHeap::new();
    let zero_score: K = Default::default();
    scores.insert(start.clone(), zero_score);
    visit_next.push(MinScored(zero_score, start));
    while let Some(MinScored(node_score, node)) = visit_next.pop() {
        if visited.contains(&node) {
            continue
        }
        for (next, edge) in edges(graph, node.clone()) {
            if visited.contains(&next) {
                continue
            }
            let mut next_score = node_score + edge;
            match scores.entry(next.clone()) {
                Occupied(ent) => if next_score < *ent.get() {
                    *ent.into_mut() = next_score;
                    predecessor.insert(next.clone(), node.clone());
                } else {
                    next_score = *ent.get();
                },
                Vacant(ent) => {
                    ent.insert(next_score);
                    predecessor.insert(next.clone(), node.clone());
                }
            }
            visit_next.push(MinScored(next_score, next));
        }
        if goal.as_ref() == Some(&node) {
            break
        }
        visited.visit(node);
    }
    scores
}

#[derive(Show)]
pub struct Node<T>(pub T);

pub struct NodeCell<T: Copy>(pub Cell<T>);

impl<T: Copy> Deref for NodeCell<T> {
    type Target = Cell<T>;
    #[inline]
    fn deref(&self) -> &Cell<T> {
        &self.0
    }
}

impl<T: Copy + fmt::Show> fmt::Show for NodeCell<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Node({:?})", self.0.get())
    }
}
<|endoftext|>


<commit_before>#![crate_name = "rustful"]

#![crate_type = "rlib"]

#![doc(html_root_url = "http://ogeon.github.io/rustful/doc/")]

#![feature(fs_time, path_ext, std_misc, core)]
#![cfg_attr(test, feature(test))]

#[cfg(test)] extern crate test;
#[cfg(test)] extern crate tempdir;

extern crate url;
extern crate time;
extern crate hyper;
extern crate anymap;

pub use hyper::mime;
pub use hyper::method::Method;
pub use hyper::status::StatusCode;
pub use hyper::header;
pub use hyper::HttpResult;
pub use hyper::HttpError;
pub use hyper::version::HttpVersion;

pub use self::server::Server;
pub use self::context::Context;
pub use self::response::Response;
pub use self::response::Error;
pub use self::handler::Handler;
pub use self::router::Router;
pub use self::log::Log;
pub use self::router::TreeRouter;

mod utils;
#[macro_use] mod macros;

pub mod server;
pub mod router;
pub mod handler;
pub mod cache;
pub mod context;
pub mod response;
pub mod plugin;
pub mod log;

use std::path::Path;

///HTTP or HTTPS
pub enum Scheme<'a> {
    ///Standard HTTP.
    Http,

    ///HTTP with SSL encryption.
    Https {
        ///Path to SSL certificate.
        cert: &'a Path,

        ///Path to key file.
        key: &'a Path
    }
}<commit_msg>Don't use core feature<commit_after>#![crate_name = "rustful"]

#![crate_type = "rlib"]

#![doc(html_root_url = "http://ogeon.github.io/rustful/doc/")]

#![feature(fs_time, path_ext, std_misc)]
#![cfg_attr(test, feature(test))]

#[cfg(test)] extern crate test;
#[cfg(test)] extern crate tempdir;

extern crate url;
extern crate time;
extern crate hyper;
extern crate anymap;

pub use hyper::mime;
pub use hyper::method::Method;
pub use hyper::status::StatusCode;
pub use hyper::header;
pub use hyper::HttpResult;
pub use hyper::HttpError;
pub use hyper::version::HttpVersion;

pub use self::server::Server;
pub use self::context::Context;
pub use self::response::Response;
pub use self::response::Error;
pub use self::handler::Handler;
pub use self::router::Router;
pub use self::log::Log;
pub use self::router::TreeRouter;

mod utils;
#[macro_use] mod macros;

pub mod server;
pub mod router;
pub mod handler;
pub mod cache;
pub mod context;
pub mod response;
pub mod plugin;
pub mod log;

use std::path::Path;

///HTTP or HTTPS
pub enum Scheme<'a> {
    ///Standard HTTP.
    Http,

    ///HTTP with SSL encryption.
    Https {
        ///Path to SSL certificate.
        cert: &'a Path,

        ///Path to key file.
        key: &'a Path
    }
}<|endoftext|>


<commit_before>
use std::fs;
use std::io;
use std::path::Path;

extern crate byteorder;

pub mod types;

#[macro_use]
pub mod utils;

pub struct File {
    pub ehdr: types::FileHeader,
    pub phdrs: Vec<types::ProgramHeader>,
    pub sections: Vec<Section>,
}

pub trait ReadExact {
    fn read_exact(&mut self, len: usize) -> io::Result<Vec<u8>>;
}
impl<T> ReadExact for T
    where T: io::Read
{
    fn read_exact(&mut self, len: usize) -> io::Result<Vec<u8>> {
        use std::io::{Error, ErrorKind};
        let mut buf = Vec::with_capacity(len);
        loop {
            if buf.len() >= len { break; }

            let current_len = buf.len();

            let read = try!(self.read(&mut buf[current_len..]));
            if read == 0 {
                return Err(Error::new(ErrorKind::Other,
                                      "EOF"));
            }
        }

        return Ok(buf);
    }
}

impl std::fmt::Debug for File {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{:?} {:?} {:?}", self.ehdr, self.phdrs, self.sections)
    }
}

impl std::fmt::Display for File {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        try!(write!(f, "{{ {} }}", self.ehdr));
        try!(write!(f, "{{ "));
        for phdr in self.phdrs.iter() {
            try!(write!(f, "{}", phdr));
        }
        try!(write!(f, " }} {{ "));
        for shdr in self.sections.iter() {
            try!(write!(f, "{}", shdr));
        }
        write!(f, " }}")
    }
}

#[derive(Debug)]
pub enum ParseError {
    IoError(io::Error),
    InvalidMagic,
    InvalidFormat(Option<std::string::FromUtf8Error>),
    NotImplemented,
}

impl std::convert::From<std::io::Error> for ParseError {
    fn from(e: std::io::Error) -> Self {
        ParseError::IoError(e)
    }
}

impl std::convert::From<std::string::FromUtf8Error> for ParseError {
    fn from(e: std::string::FromUtf8Error) -> Self {
        ParseError::InvalidFormat(Some(e))
    }
}
impl std::convert::From<byteorder::Error> for ParseError {
    fn from(e: byteorder::Error) -> Self {
        match e {
            byteorder::Error::UnexpectedEOF => {
                ParseError::InvalidFormat(None)
            },
            byteorder::Error::Io(e) => {
                From::from(e)
            },
        }
    }
}

impl File {
    pub fn open_path<T: AsRef<Path>>(path: T) -> Result<File, ParseError> {
        // Open the file for reading
        let mut io_file = try!(fs::File::open(path));

        File::open_stream(&mut io_file)
    }

    pub fn open_stream<T: io::Read + io::Seek>(io_file: &mut T) -> Result<File, ParseError> {
        // Read the platform-independent ident bytes
        let mut ident = [0u8; types::EI_NIDENT];
        let nread = try!(io_file.read(ident.as_mut()));

        if nread != types::EI_NIDENT {
            return Err(ParseError::InvalidFormat(None));
        }

        // Verify the magic number
        if ident[0] != types::ELFMAG0 || ident[1] != types::ELFMAG1
                || ident[2] != types::ELFMAG2 || ident[3] != types::ELFMAG3 {
            return Err(ParseError::InvalidMagic);
        }

        // Fill in file header values from ident bytes
        let mut elf_f = File::new();
        elf_f.ehdr.class = types::Class(ident[types::EI_CLASS]);
        elf_f.ehdr.data = types::Data(ident[types::EI_DATA]);
        elf_f.ehdr.osabi = types::OSABI(ident[types::EI_OSABI]);
        elf_f.ehdr.abiversion = ident[types::EI_ABIVERSION];
        elf_f.ehdr.elftype = types::Type(try!(read_u16!(elf_f, io_file)));
        elf_f.ehdr.machine = types::Machine(try!(read_u16!(elf_f, io_file)));
        elf_f.ehdr.version = types::Version(try!(read_u32!(elf_f, io_file)));

        let mut phoff: u64;
        let mut shoff: u64;

        // Parse the platform-dependent file fields
        if elf_f.ehdr.class == types::ELFCLASS32 {
            elf_f.ehdr.entry = try!(read_u32!(elf_f, io_file)) as u64;
            phoff = try!(read_u32!(elf_f, io_file)) as u64;
            shoff = try!(read_u32!(elf_f, io_file)) as u64;
        } else {
            elf_f.ehdr.entry = try!(read_u64!(elf_f, io_file));
            phoff = try!(read_u64!(elf_f, io_file));
            shoff = try!(read_u64!(elf_f, io_file));
        }

        let flags = try!(read_u32!(elf_f, io_file));
        let ehsize = try!(read_u16!(elf_f, io_file));
        let phentsize = try!(read_u16!(elf_f, io_file));
        let phnum = try!(read_u16!(elf_f, io_file));
        let shentsize = try!(read_u16!(elf_f, io_file));
        let shnum = try!(read_u16!(elf_f, io_file));
        let shstrndx = try!(read_u16!(elf_f, io_file));

        // Parse the program headers
        try!(io_file.seek(io::SeekFrom::Start(phoff)));
        for _ in 0..phnum {
            let mut progtype: types::ProgType;
            let mut offset: u64;
            let mut vaddr: u64;
            let mut paddr: u64;
            let mut filesz: u64;
            let mut memsz: u64;
            let mut flags: types::ProgFlag;
            let mut align: u64;

            progtype = types::ProgType(try!(read_u32!(elf_f, io_file)));
            if elf_f.ehdr.class == types::ELFCLASS32 {
                offset = try!(read_u32!(elf_f, io_file)) as u64;
                vaddr = try!(read_u32!(elf_f, io_file)) as u64;
                paddr = try!(read_u32!(elf_f, io_file)) as u64;
                filesz = try!(read_u32!(elf_f, io_file)) as u64;
                memsz = try!(read_u32!(elf_f, io_file)) as u64;
                flags = types::ProgFlag(try!(read_u32!(elf_f, io_file)));
                align = try!(read_u32!(elf_f, io_file)) as u64;
            } else {
                flags = types::ProgFlag(try!(read_u32!(elf_f, io_file)));
                offset = try!(read_u64!(elf_f, io_file));
                vaddr = try!(read_u64!(elf_f, io_file));
                paddr = try!(read_u64!(elf_f, io_file));
                filesz = try!(read_u64!(elf_f, io_file));
                memsz = try!(read_u64!(elf_f, io_file));
                align = try!(read_u64!(elf_f, io_file));
            }

            elf_f.phdrs.push(types::ProgramHeader {
                    progtype: progtype,
                    offset:   offset,
                    vaddr:    vaddr,
                    paddr:    paddr,
                    filesz:   filesz,
                    memsz:    memsz,
                    flags:    flags,
                    align:    align,
                });
        }

        // Parse the section headers
        let mut name_idxs: Vec<u32> = Vec::new();
        try!(io_file.seek(io::SeekFrom::Start(phoff)));
        for _ in 0..shnum {
            let name: String = String::new();
            let mut shtype: types::SectionType;
            let mut flags: types::SectionFlag;
            let mut addr: u64;
            let mut offset: u64;
            let mut size: u64;
            let mut link: u32;
            let mut info: u32;
            let mut addralign: u64;
            let mut entsize: u64;

            name_idxs.push(try!(read_u32!(elf_f, io_file)));
            shtype = types::SectionType(try!(read_u32!(elf_f, io_file)));
            if elf_f.ehdr.class == types::ELFCLASS32 {
                flags = types::SectionFlag(try!(read_u32!(elf_f, io_file)) as u64);
                addr = try!(read_u32!(elf_f, io_file)) as u64;
                offset = try!(read_u32!(elf_f, io_file)) as u64;
                size = try!(read_u32!(elf_f, io_file)) as u64;
                link = try!(read_u32!(elf_f, io_file));
                info = try!(read_u32!(elf_f, io_file));
                addralign = try!(read_u32!(elf_f, io_file)) as u64;
                entsize = try!(read_u32!(elf_f, io_file)) as u64;
            } else {
                flags = types::SectionFlag(try!(read_u64!(elf_f, io_file)));
                addr = try!(read_u64!(elf_f, io_file));
                offset = try!(read_u64!(elf_f, io_file));
                size = try!(read_u64!(elf_f, io_file));
                link = try!(read_u32!(elf_f, io_file));
                info = try!(read_u32!(elf_f, io_file));
                addralign = try!(read_u64!(elf_f, io_file));
                entsize = try!(read_u64!(elf_f, io_file));
            }

            elf_f.sections.push(Section {
                    shdr: types::SectionHeader {
                        name:      name,
                        shtype:    shtype,
                        flags:     flags,
                        addr:      addr,
                        offset:    offset,
                        size:      size,
                        link:      link,
                        info:      info,
                        addralign: addralign,
                        entsize:   entsize,
                    },
                    data: Vec::new(),
                });
        }

        // Read the section data
        let mut s_i: usize = 0;
        loop {
            if s_i == shnum as usize { break; }

            let off = elf_f.sections[s_i].shdr.offset;
            let size = elf_f.sections[s_i].shdr.size;
            try!(io_file.seek(io::SeekFrom::Start(off)));
            elf_f.sections[s_i].data = try!(io_file.read_exact(size as usize));

            s_i += 1;
        }

        // Parse the section names from the string header string table
        s_i = 0;
        loop {
            if s_i == shnum as usize { break; }

            elf_f.sections[s_i].shdr.name = try!(utils::get_string(
                &elf_f.sections[shstrndx as usize].data,
                name_idxs[s_i] as usize));

            s_i += 1;
        }

        Ok(elf_f)
    }

    pub fn get_section<T: AsRef<str>>(&self, name: T) -> Option<&Section> {
        self.sections
            .iter()
            .find(|section| section.shdr.name == name.as_ref() )
    }

    pub fn new() -> File {
        File {
            ehdr: types::FileHeader::new(),
            phdrs: Vec::new(),
            sections: Vec::new(),
        }
    }
}

#[derive(Debug)]
pub struct Section {
    pub shdr: types::SectionHeader,
    pub data: Vec<u8>,
}

impl std::fmt::Display for Section {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.shdr)
    }
}
<commit_msg>Read section contents using Take and read_to_end<commit_after>
use std::fs;
use std::io;
use std::path::Path;
use std::io::Read;

extern crate byteorder;

pub mod types;

#[macro_use]
pub mod utils;

pub struct File {
    pub ehdr: types::FileHeader,
    pub phdrs: Vec<types::ProgramHeader>,
    pub sections: Vec<Section>,
}

pub trait ReadExact {
    fn read_exact(&mut self, len: u64) -> io::Result<Vec<u8>>;
}
impl<T> ReadExact for T
    where T: io::Read
{
    fn read_exact(&mut self, len: u64) -> io::Result<Vec<u8>> {
        use std::io::{Error, ErrorKind};
        let mut buf = Vec::with_capacity(len as usize);
        let mut chunk = self.take(len);
        try!(chunk.read_to_end(&mut buf));
        return Ok(buf);
    }
}

impl std::fmt::Debug for File {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{:?} {:?} {:?}", self.ehdr, self.phdrs, self.sections)
    }
}

impl std::fmt::Display for File {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        try!(write!(f, "{{ {} }}", self.ehdr));
        try!(write!(f, "{{ "));
        for phdr in self.phdrs.iter() {
            try!(write!(f, "{}", phdr));
        }
        try!(write!(f, " }} {{ "));
        for shdr in self.sections.iter() {
            try!(write!(f, "{}", shdr));
        }
        write!(f, " }}")
    }
}

#[derive(Debug)]
pub enum ParseError {
    IoError(io::Error),
    InvalidMagic,
    InvalidFormat(Option<std::string::FromUtf8Error>),
    NotImplemented,
}

impl std::convert::From<std::io::Error> for ParseError {
    fn from(e: std::io::Error) -> Self {
        ParseError::IoError(e)
    }
}

impl std::convert::From<std::string::FromUtf8Error> for ParseError {
    fn from(e: std::string::FromUtf8Error) -> Self {
        ParseError::InvalidFormat(Some(e))
    }
}
impl std::convert::From<byteorder::Error> for ParseError {
    fn from(e: byteorder::Error) -> Self {
        match e {
            byteorder::Error::UnexpectedEOF => {
                ParseError::InvalidFormat(None)
            },
            byteorder::Error::Io(e) => {
                From::from(e)
            },
        }
    }
}

impl File {
    pub fn open_path<T: AsRef<Path>>(path: T) -> Result<File, ParseError> {
        // Open the file for reading
        let mut io_file = try!(fs::File::open(path));

        File::open_stream(&mut io_file)
    }

    pub fn open_stream<T: io::Read + io::Seek>(io_file: &mut T) -> Result<File, ParseError> {
        // Read the platform-independent ident bytes
        let mut ident = [0u8; types::EI_NIDENT];
        let nread = try!(io_file.read(ident.as_mut()));

        if nread != types::EI_NIDENT {
            return Err(ParseError::InvalidFormat(None));
        }

        // Verify the magic number
        if ident[0] != types::ELFMAG0 || ident[1] != types::ELFMAG1
                || ident[2] != types::ELFMAG2 || ident[3] != types::ELFMAG3 {
            return Err(ParseError::InvalidMagic);
        }

        // Fill in file header values from ident bytes
        let mut elf_f = File::new();
        elf_f.ehdr.class = types::Class(ident[types::EI_CLASS]);
        elf_f.ehdr.data = types::Data(ident[types::EI_DATA]);
        elf_f.ehdr.osabi = types::OSABI(ident[types::EI_OSABI]);
        elf_f.ehdr.abiversion = ident[types::EI_ABIVERSION];
        elf_f.ehdr.elftype = types::Type(try!(read_u16!(elf_f, io_file)));
        elf_f.ehdr.machine = types::Machine(try!(read_u16!(elf_f, io_file)));
        elf_f.ehdr.version = types::Version(try!(read_u32!(elf_f, io_file)));

        let mut phoff: u64;
        let mut shoff: u64;

        // Parse the platform-dependent file fields
        if elf_f.ehdr.class == types::ELFCLASS32 {
            elf_f.ehdr.entry = try!(read_u32!(elf_f, io_file)) as u64;
            phoff = try!(read_u32!(elf_f, io_file)) as u64;
            shoff = try!(read_u32!(elf_f, io_file)) as u64;
        } else {
            elf_f.ehdr.entry = try!(read_u64!(elf_f, io_file));
            phoff = try!(read_u64!(elf_f, io_file));
            shoff = try!(read_u64!(elf_f, io_file));
        }

        let flags = try!(read_u32!(elf_f, io_file));
        let ehsize = try!(read_u16!(elf_f, io_file));
        let phentsize = try!(read_u16!(elf_f, io_file));
        let phnum = try!(read_u16!(elf_f, io_file));
        let shentsize = try!(read_u16!(elf_f, io_file));
        let shnum = try!(read_u16!(elf_f, io_file));
        let shstrndx = try!(read_u16!(elf_f, io_file));

        // Parse the program headers
        try!(io_file.seek(io::SeekFrom::Start(phoff)));
        for _ in 0..phnum {
            let mut progtype: types::ProgType;
            let mut offset: u64;
            let mut vaddr: u64;
            let mut paddr: u64;
            let mut filesz: u64;
            let mut memsz: u64;
            let mut flags: types::ProgFlag;
            let mut align: u64;

            progtype = types::ProgType(try!(read_u32!(elf_f, io_file)));
            if elf_f.ehdr.class == types::ELFCLASS32 {
                offset = try!(read_u32!(elf_f, io_file)) as u64;
                vaddr = try!(read_u32!(elf_f, io_file)) as u64;
                paddr = try!(read_u32!(elf_f, io_file)) as u64;
                filesz = try!(read_u32!(elf_f, io_file)) as u64;
                memsz = try!(read_u32!(elf_f, io_file)) as u64;
                flags = types::ProgFlag(try!(read_u32!(elf_f, io_file)));
                align = try!(read_u32!(elf_f, io_file)) as u64;
            } else {
                flags = types::ProgFlag(try!(read_u32!(elf_f, io_file)));
                offset = try!(read_u64!(elf_f, io_file));
                vaddr = try!(read_u64!(elf_f, io_file));
                paddr = try!(read_u64!(elf_f, io_file));
                filesz = try!(read_u64!(elf_f, io_file));
                memsz = try!(read_u64!(elf_f, io_file));
                align = try!(read_u64!(elf_f, io_file));
            }

            elf_f.phdrs.push(types::ProgramHeader {
                    progtype: progtype,
                    offset:   offset,
                    vaddr:    vaddr,
                    paddr:    paddr,
                    filesz:   filesz,
                    memsz:    memsz,
                    flags:    flags,
                    align:    align,
                });
        }

        // Parse the section headers
        let mut name_idxs: Vec<u32> = Vec::new();
        try!(io_file.seek(io::SeekFrom::Start(phoff)));
        for _ in 0..shnum {
            let name: String = String::new();
            let mut shtype: types::SectionType;
            let mut flags: types::SectionFlag;
            let mut addr: u64;
            let mut offset: u64;
            let mut size: u64;
            let mut link: u32;
            let mut info: u32;
            let mut addralign: u64;
            let mut entsize: u64;

            name_idxs.push(try!(read_u32!(elf_f, io_file)));
            shtype = types::SectionType(try!(read_u32!(elf_f, io_file)));
            if elf_f.ehdr.class == types::ELFCLASS32 {
                flags = types::SectionFlag(try!(read_u32!(elf_f, io_file)) as u64);
                addr = try!(read_u32!(elf_f, io_file)) as u64;
                offset = try!(read_u32!(elf_f, io_file)) as u64;
                size = try!(read_u32!(elf_f, io_file)) as u64;
                link = try!(read_u32!(elf_f, io_file));
                info = try!(read_u32!(elf_f, io_file));
                addralign = try!(read_u32!(elf_f, io_file)) as u64;
                entsize = try!(read_u32!(elf_f, io_file)) as u64;
            } else {
                flags = types::SectionFlag(try!(read_u64!(elf_f, io_file)));
                addr = try!(read_u64!(elf_f, io_file));
                offset = try!(read_u64!(elf_f, io_file));
                size = try!(read_u64!(elf_f, io_file));
                link = try!(read_u32!(elf_f, io_file));
                info = try!(read_u32!(elf_f, io_file));
                addralign = try!(read_u64!(elf_f, io_file));
                entsize = try!(read_u64!(elf_f, io_file));
            }

            elf_f.sections.push(Section {
                    shdr: types::SectionHeader {
                        name:      name,
                        shtype:    shtype,
                        flags:     flags,
                        addr:      addr,
                        offset:    offset,
                        size:      size,
                        link:      link,
                        info:      info,
                        addralign: addralign,
                        entsize:   entsize,
                    },
                    data: Vec::new(),
                });
        }

        // Read the section data
        let mut s_i: usize = 0;
        loop {
            if s_i == shnum as usize { break; }

            let off = elf_f.sections[s_i].shdr.offset;
            let size = elf_f.sections[s_i].shdr.size;
            try!(io_file.seek(io::SeekFrom::Start(off)));
            elf_f.sections[s_i].data = try!(io_file.read_exact(size));

            s_i += 1;
        }

        // Parse the section names from the string header string table
        s_i = 0;
        loop {
            if s_i == shnum as usize { break; }

            elf_f.sections[s_i].shdr.name = try!(utils::get_string(
                &elf_f.sections[shstrndx as usize].data,
                name_idxs[s_i] as usize));

            s_i += 1;
        }

        Ok(elf_f)
    }

    pub fn get_section<T: AsRef<str>>(&self, name: T) -> Option<&Section> {
        self.sections
            .iter()
            .find(|section| section.shdr.name == name.as_ref() )
    }

    pub fn new() -> File {
        File {
            ehdr: types::FileHeader::new(),
            phdrs: Vec::new(),
            sections: Vec::new(),
        }
    }
}

#[derive(Debug)]
pub struct Section {
    pub shdr: types::SectionHeader,
    pub data: Vec<u8>,
}

impl std::fmt::Display for Section {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.shdr)
    }
}
<|endoftext|>


<commit_before>//! Struct and methods for union-find operation.

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

use std::{iter, mem};

#[derive(Clone)]
enum UFNode {
    Key(uint),
    Size(uint)
}

/// Struct for union-find operation.
pub struct UnionFind {
    data: Vec<UFNode>
}

impl UnionFind {
    /// Creates empty `UnionFind` struct.
    #[inline]
    pub fn new(len: uint) -> UnionFind {
        UnionFind { data: iter::repeat(UFNode::Size(1)).take(len).collect() }
    }

    /// Join two sets that contains given keys (Union operation).
    ///
    /// Returns `true` if these keys are belonged to different sets.
    pub fn union(&mut self, key1: uint, key2: uint) -> bool {
        let (key1, size1) = self.get_key_size(key1);
        let (key2, size2) = self.get_key_size(key2);
        if key1 == key2 { return false; }

        let mut key1 = key1; let mut size1 = size1;
        let mut key2 = key2; let mut size2 = size2;

        if size1 < size2 {
            mem::swap(&mut key1, &mut key2);
            mem::swap(&mut size1, &mut size2);
        }

        self.data[key1] = UFNode::Size(size1 + size2);
        self.data[key2] = UFNode::Key(key1);

        return true;
    }

    /// Returns `true` if two keys contained by the same set (find operation).
    #[inline]
    pub fn find(&mut self, key1: uint, key2: uint) -> bool {
        return self.get_key(key1) == self.get_key(key2);
    }

    /// Returns the number of the elements that belongs to the same set with key.
    #[inline]
    pub fn get_size(&mut self, key: uint) -> uint {
        self.get_key_size(key).1
    }

    fn get_key(&mut self, key: uint) -> uint {
        self.get_key_size(key).0
    }

    fn get_key_size(&mut self, key: uint) -> (uint, uint) {
        let (root_key, size) = match self.data[key] {
            UFNode::Size(size) => { return (key, size); }
            UFNode::Key(key) => self.get_key_size(key)
        };
        self.data[key] = UFNode::Key(root_key);
        return (root_key, size);
    }
}

#[test]
fn test_union_find() {
    let mut uf = UnionFind::new(100);
    assert_eq!(uf.get_size(0), 1);
    assert_eq!(uf.get_size(1), 1);
    assert!(!uf.find(0, 1));
    assert!(!uf.find(1, 2));
    assert!(uf.union(0, 1));
    assert!(uf.find(0, 1));
    assert_eq!(uf.get_size(0), 2);
    assert_eq!(uf.get_size(1), 2);
    assert_eq!(uf.get_size(2), 1);
    assert!(!uf.union(0, 1));
    assert_eq!(uf.get_size(0), 2);
    assert_eq!(uf.get_size(1), 2);
    assert_eq!(uf.get_size(2), 1);
    assert!(uf.union(1, 2));
    assert_eq!(uf.get_size(0), 3);
    assert_eq!(uf.get_size(1), 3);
    assert_eq!(uf.get_size(2), 3);
    assert!(uf.find(0, 1));
    assert!(uf.find(2, 1));
}
<commit_msg>deriving Show, Clone<commit_after>//! Struct and methods for union-find operation.

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

use std::{iter, mem};

#[derive(Clone, Show)]
enum UFNode {
    Key(uint),
    Size(uint)
}

/// Struct for union-find operation.
#[derive(Clone, Show)]
pub struct UnionFind {
    data: Vec<UFNode>
}

impl UnionFind {
    /// Creates empty `UnionFind` struct.
    #[inline]
    pub fn new(len: uint) -> UnionFind {
        UnionFind { data: iter::repeat(UFNode::Size(1)).take(len).collect() }
    }

    /// Join two sets that contains given keys (Union operation).
    ///
    /// Returns `true` if these keys are belonged to different sets.
    pub fn union(&mut self, key1: uint, key2: uint) -> bool {
        let (key1, size1) = self.get_key_size(key1);
        let (key2, size2) = self.get_key_size(key2);
        if key1 == key2 { return false; }

        let mut key1 = key1; let mut size1 = size1;
        let mut key2 = key2; let mut size2 = size2;

        if size1 < size2 {
            mem::swap(&mut key1, &mut key2);
            mem::swap(&mut size1, &mut size2);
        }

        self.data[key1] = UFNode::Size(size1 + size2);
        self.data[key2] = UFNode::Key(key1);

        return true;
    }

    /// Returns `true` if two keys contained by the same set (find operation).
    #[inline]
    pub fn find(&mut self, key1: uint, key2: uint) -> bool {
        return self.get_key(key1) == self.get_key(key2);
    }

    /// Returns the number of the elements that belongs to the same set with key.
    #[inline]
    pub fn get_size(&mut self, key: uint) -> uint {
        self.get_key_size(key).1
    }

    fn get_key(&mut self, key: uint) -> uint {
        self.get_key_size(key).0
    }

    fn get_key_size(&mut self, key: uint) -> (uint, uint) {
        let (root_key, size) = match self.data[key] {
            UFNode::Size(size) => { return (key, size); }
            UFNode::Key(key) => self.get_key_size(key)
        };
        self.data[key] = UFNode::Key(root_key);
        return (root_key, size);
    }
}

#[test]
fn test_union_find() {
    let mut uf = UnionFind::new(100);
    assert_eq!(uf.get_size(0), 1);
    assert_eq!(uf.get_size(1), 1);
    assert!(!uf.find(0, 1));
    assert!(!uf.find(1, 2));
    assert!(uf.union(0, 1));
    assert!(uf.find(0, 1));
    assert_eq!(uf.get_size(0), 2);
    assert_eq!(uf.get_size(1), 2);
    assert_eq!(uf.get_size(2), 1);
    assert!(!uf.union(0, 1));
    assert_eq!(uf.get_size(0), 2);
    assert_eq!(uf.get_size(1), 2);
    assert_eq!(uf.get_size(2), 1);
    assert!(uf.union(1, 2));
    assert_eq!(uf.get_size(0), 3);
    assert_eq!(uf.get_size(1), 3);
    assert_eq!(uf.get_size(2), 3);
    assert!(uf.find(0, 1));
    assert!(uf.find(2, 1));
}
<|endoftext|>


<commit_before>//! # TLS Parser
//!
//! A TLS parser, implemented with the [nom](https://github.com/Geal/nom)
//! parser combinator framework.
//!
//! The goal of this parser is to implement TLS messages analysis, for example
//! to use rules from a network IDS, for ex during the TLS handshake.
//!
//! It implements structures and parsing functions for records and messages, but
//! need additional code to handle fragmentation, or to fully inspect messages.
//! Parsing some TLS messages requires to know the previously selected parameters.
//! See [the rusticata TLS parser](https://github.com/rusticata/rusticata/blob/master/src/tls.rs)
//! for a full example.
//!
//! The code is available on [Github](https://github.com/rusticata/tls-parser)
//! and is part of the [Rusticata](https://github.com/rusticata) project.
//!
//! # Implementation notes
//!
//! When parsing messages, if a field is an integer corresponding to an enum of known values,
//! it is not parsed as an enum type, but as an integer. While this complicates accesses,
//! it allows to read invalid values and continue parsing (for an IDS, it's better to read
//! values than to get a generic parse error).

#![deny(/*missing_docs,*/unsafe_code,
        unstable_features,
        unused_import_braces, unused_qualifications)]

#[macro_use]
extern crate enum_primitive;

#[macro_use]
extern crate nom;

extern crate phf;

#[macro_use]
extern crate rusticata_macros;

#[macro_use]
extern crate cookie_factory;

pub use tls_alert::*;
/// TLS alerts
#[macro_use]
pub mod tls_alert;
pub use tls_ciphers::*;
/// TLS ciphersuites definitions and parameters
pub mod tls_ciphers;
pub use tls_dh::*;
/// Diffie-Hellman parameters
pub mod tls_dh;
pub use tls_ec::*;
/// Elliptic curves
pub mod tls_ec;
pub use tls_extensions::*;
/// TLS extensions
#[macro_use]
pub mod tls_extensions;
pub use tls_sign_hash::*;
/// TLS signature schemes
pub mod tls_sign_hash;
pub use tls_states::*;
/// TLS state machine
pub mod tls_states;
pub use tls::*;
/// TLS parser structures and functions
pub mod tls;

mod tls_debug;

pub mod tls_serialize;
pub use tls_serialize::*;
<commit_msg>Fix warning when not using the serialize feature<commit_after>//! # TLS Parser
//!
//! A TLS parser, implemented with the [nom](https://github.com/Geal/nom)
//! parser combinator framework.
//!
//! The goal of this parser is to implement TLS messages analysis, for example
//! to use rules from a network IDS, for ex during the TLS handshake.
//!
//! It implements structures and parsing functions for records and messages, but
//! need additional code to handle fragmentation, or to fully inspect messages.
//! Parsing some TLS messages requires to know the previously selected parameters.
//! See [the rusticata TLS parser](https://github.com/rusticata/rusticata/blob/master/src/tls.rs)
//! for a full example.
//!
//! The code is available on [Github](https://github.com/rusticata/tls-parser)
//! and is part of the [Rusticata](https://github.com/rusticata) project.
//!
//! # Implementation notes
//!
//! When parsing messages, if a field is an integer corresponding to an enum of known values,
//! it is not parsed as an enum type, but as an integer. While this complicates accesses,
//! it allows to read invalid values and continue parsing (for an IDS, it's better to read
//! values than to get a generic parse error).

#![deny(/*missing_docs,*/unsafe_code,
        unstable_features,
        unused_import_braces, unused_qualifications)]

#[macro_use]
extern crate enum_primitive;

#[macro_use]
extern crate nom;

extern crate phf;

#[macro_use]
extern crate rusticata_macros;

#[cfg(feature = "serialize")]
#[macro_use]
extern crate cookie_factory;

pub use tls_alert::*;
/// TLS alerts
#[macro_use]
pub mod tls_alert;
pub use tls_ciphers::*;
/// TLS ciphersuites definitions and parameters
pub mod tls_ciphers;
pub use tls_dh::*;
/// Diffie-Hellman parameters
pub mod tls_dh;
pub use tls_ec::*;
/// Elliptic curves
pub mod tls_ec;
pub use tls_extensions::*;
/// TLS extensions
#[macro_use]
pub mod tls_extensions;
pub use tls_sign_hash::*;
/// TLS signature schemes
pub mod tls_sign_hash;
pub use tls_states::*;
/// TLS state machine
pub mod tls_states;
pub use tls::*;
/// TLS parser structures and functions
pub mod tls;

mod tls_debug;

pub mod tls_serialize;
pub use tls_serialize::*;
<|endoftext|>


<commit_before>mod hidden;

use std::hash::Hash;

use self::hidden::base::*;
use self::hidden::nav::make_node;
use self::hidden::mutators::make_mut_node;

pub use self::hidden::nav::{ChildList, Edge, Node, ParentList};
pub use self::hidden::mutators::{EdgeExpander, MutChildList, MutEdge, MutNode, MutParentList};

/// A search graph.
///
/// Supports incremental rollout of game state topology, vertex de-duplication
/// with transposition tables, and cycle detection. Does not support deletion.
///
/// - `T`: The type of game states. It is required to derive `Hash` and `Eq` to
///   so that it may be stored in a hashtable, where game states are looked up to
///   support de-duplication of game states. It is required to derive `Clone` to
///   accommodate a limitation of the `HashMap` interface.
/// - `S`: The type of graph vertex data.
/// - `A`: The type of graph edge data.
///
/// Vertices are addressed by content. To examine graph contents, obtain a node
/// handle with `get_node`. To modify graph contents, add new root vertices with
/// `add_root` and retrieve extant vertices with `get_node_mut`.
pub struct Graph<T, S, A> where T: Hash + Eq + Clone {
    /// Lookup table that maps from game states to `StateId`.
    state_ids: StateNamespace<T>,
    vertices: Vec<Vertex<S>>,  // Indexed by StateId.
    arcs: Vec<Arc<A>>,  // Indexed by ArcId.
}

impl<T, S, A> Graph<T, S, A> where T: Hash + Eq + Clone {
    /// Creates an empty `Graph` with no vertices or edges.
    pub fn new() -> Self {
        Graph {
            state_ids: StateNamespace::new(),
            vertices: Vec::new(),
            arcs: Vec::new(),
        }
    }

    /// Returns the vertex for the given `StateId`.
    fn get_vertex(&self, state: StateId) -> &Vertex<S> {
        &self.vertices[state.as_usize()]
    }

    /// Returns the vertex for the given `StateId`.
    fn get_vertex_mut(&mut self, state: StateId) -> &mut Vertex<S> {
        &mut self.vertices[state.as_usize()]
    }

    /// Returns the edge for the given `ArcId`.
    fn get_arc(&self, arc: ArcId) -> &Arc<A> {
        &self.arcs[arc.as_usize()]
    }

    /// Returns the edge for the given `ArcId`.
    fn get_arc_mut(&mut self, arc: ArcId) -> &mut Arc<A> {
        &mut self.arcs[arc.as_usize()]
    }

    /// Adds a new vertex with the given data, returning a mutable reference to it.
    ///
    /// This method does not add incoming or outgoing edges (expanded or
    /// not). That must be done by calling `add_arc` with the new vertex
    /// `StateId`.
    fn add_vertex(&mut self, data: S) -> &mut Vertex<S> {
        self.vertices.push(Vertex { data: data, parents: Vec::new(), children: Vec::new(), });
        self.vertices.last_mut().unwrap()
    }

    /// Adds a new edge with the given data, source, and target. A corresponding
    /// edge in the opposite direction is not automatically added.
    fn add_arc(&mut self, data: A, source: StateId, target: Target<StateId, ()>) {
        let arc_id = ArcId(self.arcs.len());
        self.get_vertex_mut(source).children.push(arc_id);
        self.arcs.push(Arc { data: data, source: source, target: target, });
    }

    /// Gets a node handle for the given game state.
    ///
    /// If `state` does not correspond to a known game state, returns `None`.
    pub fn get_node<'s>(&'s self, state: &T) -> Option<Node<'s, T, S, A>> {
        match self.state_ids.get(&state) {
            Some(id) => Some(make_node(self, id)),
            None => None,
        }
    }

    /// Gets a mutable node handle for the given game state.
    ///
    /// If `state` does not correspond to a known game state, returns `None`.
    pub fn get_node_mut<'s>(&'s mut self, state: &T) -> Option<MutNode<'s, T, S, A>> {
        match self.state_ids.get(state) {
            Some(id) => Some(make_mut_node(self, id)),
            None => None,
        }
    }

    /// Adds a root vertex (one with no parents) for the given game state and
    /// data and returns a mutable handle for it.
    ///
    /// If `state` is already known, returns a mutable handle to that state,
    /// ignoring the `data` parameter. As a result, this method is guaranteed to
    /// return a handle for a root vertex only when `state` is a novel game
    /// state.
    pub fn add_root<'s>(&'s mut self, state: T, data: S) -> MutNode<'s, T, S, A> {
        let node_id = match self.state_ids.get_or_insert(state) {
            NamespaceInsertion::Present(id) => id,
            NamespaceInsertion::New(id) => {
                self.add_vertex(data);
                id
            },
        };
        make_mut_node(self, node_id)
    }
}

/// The target of an outgoing graph edge.
///
/// A search graph is built up incrementally. Any vertices are typically added
/// with all of their edges in the unexpanded state. Graph-modifying operations
/// which are executed while exploring the game state topology will expand these
/// edges. Cycle detection is done at edge expansion time.
#[derive(Clone, Copy, Debug)]
pub enum Target<T, R> {
    /// Edge has not yet been expanded.
    Unexpanded(R),
    /// Edge has been expanded and was the expanded edge that lead to the game
    /// state which it points to. The target of this edge will have a
    /// backpointer to this edge's source in its parent list.
    Expanded(T),
}
<commit_msg>Export edge list iter types.<commit_after>mod hidden;

use std::hash::Hash;

use self::hidden::base::*;
use self::hidden::nav::make_node;
use self::hidden::mutators::make_mut_node;

pub use self::hidden::nav::{ChildList, ChildListIter, Edge, Node, ParentList, ParentListIter};
pub use self::hidden::mutators::{EdgeExpander, MutChildList, MutEdge, MutNode, MutParentList};

/// A search graph.
///
/// Supports incremental rollout of game state topology, vertex de-duplication
/// with transposition tables, and cycle detection. Does not support deletion.
///
/// - `T`: The type of game states. It is required to derive `Hash` and `Eq` to
///   so that it may be stored in a hashtable, where game states are looked up to
///   support de-duplication of game states. It is required to derive `Clone` to
///   accommodate a limitation of the `HashMap` interface.
/// - `S`: The type of graph vertex data.
/// - `A`: The type of graph edge data.
///
/// Vertices are addressed by content. To examine graph contents, obtain a node
/// handle with `get_node`. To modify graph contents, add new root vertices with
/// `add_root` and retrieve extant vertices with `get_node_mut`.
pub struct Graph<T, S, A> where T: Hash + Eq + Clone {
    /// Lookup table that maps from game states to `StateId`.
    state_ids: StateNamespace<T>,
    vertices: Vec<Vertex<S>>,  // Indexed by StateId.
    arcs: Vec<Arc<A>>,  // Indexed by ArcId.
}

impl<T, S, A> Graph<T, S, A> where T: Hash + Eq + Clone {
    /// Creates an empty `Graph` with no vertices or edges.
    pub fn new() -> Self {
        Graph {
            state_ids: StateNamespace::new(),
            vertices: Vec::new(),
            arcs: Vec::new(),
        }
    }

    /// Returns the vertex for the given `StateId`.
    fn get_vertex(&self, state: StateId) -> &Vertex<S> {
        &self.vertices[state.as_usize()]
    }

    /// Returns the vertex for the given `StateId`.
    fn get_vertex_mut(&mut self, state: StateId) -> &mut Vertex<S> {
        &mut self.vertices[state.as_usize()]
    }

    /// Returns the edge for the given `ArcId`.
    fn get_arc(&self, arc: ArcId) -> &Arc<A> {
        &self.arcs[arc.as_usize()]
    }

    /// Returns the edge for the given `ArcId`.
    fn get_arc_mut(&mut self, arc: ArcId) -> &mut Arc<A> {
        &mut self.arcs[arc.as_usize()]
    }

    /// Adds a new vertex with the given data, returning a mutable reference to it.
    ///
    /// This method does not add incoming or outgoing edges (expanded or
    /// not). That must be done by calling `add_arc` with the new vertex
    /// `StateId`.
    fn add_vertex(&mut self, data: S) -> &mut Vertex<S> {
        self.vertices.push(Vertex { data: data, parents: Vec::new(), children: Vec::new(), });
        self.vertices.last_mut().unwrap()
    }

    /// Adds a new edge with the given data, source, and target. A corresponding
    /// edge in the opposite direction is not automatically added.
    fn add_arc(&mut self, data: A, source: StateId, target: Target<StateId, ()>) {
        let arc_id = ArcId(self.arcs.len());
        self.get_vertex_mut(source).children.push(arc_id);
        self.arcs.push(Arc { data: data, source: source, target: target, });
    }

    /// Gets a node handle for the given game state.
    ///
    /// If `state` does not correspond to a known game state, returns `None`.
    pub fn get_node<'s>(&'s self, state: &T) -> Option<Node<'s, T, S, A>> {
        match self.state_ids.get(&state) {
            Some(id) => Some(make_node(self, id)),
            None => None,
        }
    }

    /// Gets a mutable node handle for the given game state.
    ///
    /// If `state` does not correspond to a known game state, returns `None`.
    pub fn get_node_mut<'s>(&'s mut self, state: &T) -> Option<MutNode<'s, T, S, A>> {
        match self.state_ids.get(state) {
            Some(id) => Some(make_mut_node(self, id)),
            None => None,
        }
    }

    /// Adds a root vertex (one with no parents) for the given game state and
    /// data and returns a mutable handle for it.
    ///
    /// If `state` is already known, returns a mutable handle to that state,
    /// ignoring the `data` parameter. As a result, this method is guaranteed to
    /// return a handle for a root vertex only when `state` is a novel game
    /// state.
    pub fn add_root<'s>(&'s mut self, state: T, data: S) -> MutNode<'s, T, S, A> {
        let node_id = match self.state_ids.get_or_insert(state) {
            NamespaceInsertion::Present(id) => id,
            NamespaceInsertion::New(id) => {
                self.add_vertex(data);
                id
            },
        };
        make_mut_node(self, node_id)
    }
}

/// The target of an outgoing graph edge.
///
/// A search graph is built up incrementally. Any vertices are typically added
/// with all of their edges in the unexpanded state. Graph-modifying operations
/// which are executed while exploring the game state topology will expand these
/// edges. Cycle detection is done at edge expansion time.
#[derive(Clone, Copy, Debug)]
pub enum Target<T, R> {
    /// Edge has not yet been expanded.
    Unexpanded(R),
    /// Edge has been expanded and was the expanded edge that lead to the game
    /// state which it points to. The target of this edge will have a
    /// backpointer to this edge's source in its parent list.
    Expanded(T),
}
<|endoftext|>