<commit_before>use crate::convert::*;
use crate::operations::*;
#[cfg(feature = "specialize")]
use crate::HasherExt;
use core::hash::Hasher;

///This constant come from Kunth's prng (Empirically it works better than those from splitmix32).
const MULTIPLE: u64 = crate::random_state::MULTIPLE;
const ROT: u32 = 23; //17

/// 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()`
///
/// [Clone] is also provided in case you wish to calculate hashes for two different items that
/// start with the same data.
///
#[derive(Debug, Clone)]
pub struct AHasher {
    buffer: u64,
    pad: u64,
    extra_keys: [u64; 2],
}

impl AHasher {
    /// Creates a new hasher keyed to the provided key.
    #[inline]
    #[allow(dead_code)] // Is not called if non-fallback hash is used.
    pub fn new_with_keys(key1: u128, key2: u128) -> AHasher {
        AHasher {
            buffer: key1 as u64,
            pad: key2 as u64,
            extra_keys: key2.convert(),
        }
    }

    #[cfg(test)]
    #[allow(dead_code)] // Is not called if non-fallback hash is used.
    pub(crate) fn test_with_keys(key1: u64, key2: u64) -> AHasher {
        use crate::random_state::scramble_keys;
        let (k1, k2, k3, k4) = scramble_keys(key1, key2);
        AHasher {
            buffer: k1,
            pad: k2,
            extra_keys: [k3, k4],
        }
    }

    /// This update function has the goal of updating the buffer with a single multiply
    /// FxHash does this but is vulnerable to attack. To avoid this input needs to be masked to with an
    /// unpredictable value. Other hashes such as murmurhash have taken this approach but were found vulnerable
    /// to attack. The attack was based on the idea of reversing the pre-mixing (Which is necessarily
    /// reversible otherwise bits would be lost) then placing a difference in the highest bit before the
    /// multiply used to mix the data. Because a multiply can never affect the bits to the right of it, a
    /// subsequent update that also differed in this bit could result in a predictable collision.
    ///
    /// This version avoids this vulnerability while still only using a single multiply. It takes advantage
    /// of the fact that when a 64 bit multiply is performed the upper 64 bits are usually computed and thrown
    /// away. Instead it creates two 128 bit values where the upper 64 bits are zeros and multiplies them.
    /// (The compiler is smart enough to turn this into a 64 bit multiplication in the assembly)
    /// Then the upper bits are xored with the lower bits to produce a single 64 bit result.
    ///
    /// To understand why this is a good scrambling function it helps to understand multiply-with-carry PRNGs:
    /// https://en.wikipedia.org/wiki/Multiply-with-carry_pseudorandom_number_generator
    /// If the multiple is chosen well, this creates a long period, decent quality PRNG.
    /// Notice that this function is equivalent to this except the `buffer`/`state` is being xored with each
    /// new block of data. In the event that data is all zeros, it is exactly equivalent to a MWC PRNG.
    ///
    /// This is impervious to attack because every bit buffer at the end is dependent on every bit in
    /// `new_data ^ buffer`. For example suppose two inputs differed in only the 5th bit. Then when the
    /// multiplication is performed the `result` will differ in bits 5-69. More specifically it will differ by
    /// 2^5 * MULTIPLE. However in the next step bits 65-128 are turned into a separate 64 bit value. So the
    /// differing bits will be in the lower 6 bits of this value. The two intermediate values that differ in
    /// bits 5-63 and in bits 0-5 respectively get added together. Producing an output that differs in every
    /// bit. The addition carries in the multiplication and at the end additionally mean that the even if an
    /// attacker somehow knew part of (but not all) the contents of the buffer before hand,
    /// they would not be able to predict any of the bits in the buffer at the end.
    #[inline(always)]
    fn update(&mut self, new_data: u64) {
        self.buffer = (new_data ^ self.buffer).folded_multiply(MULTIPLE);
    }

    /// Similar to the above this function performs an update using a "folded multiply".
    /// However it takes in 128 bits of data instead of 64. Both halves must be masked.
    ///
    /// This makes it impossible for an attacker to place a single bit difference between
    /// two blocks so as to cancel each other.
    ///
    /// However this is not sufficient. to prevent (a,b) from hashing the same as (b,a) the buffer itself must
    /// be updated between calls in a way that does not commute. To achieve this XOR and Rotate are used.
    /// Add followed by xor is not the same as xor followed by add, and rotate ensures that the same out bits
    /// can't be changed by the same set of input bits. To cancel this sequence with subsequent input would require
    /// knowing the keys.
    #[inline(always)]
    fn large_update(&mut self, new_data: u128) {
        let block: [u64; 2] = new_data.convert();
        let combined = (block[0] ^ self.extra_keys[0]).folded_multiply(block[1] ^ self.extra_keys[1]);
        self.buffer = (combined.wrapping_add(self.buffer) ^ self.pad).rotate_left(ROT);
    }
}

#[cfg(feature = "specialize")]
impl HasherExt for AHasher {
    #[inline]
    fn hash_u64(self, value: u64) -> u64 {
        let rot = (self.pad & 64) as u32;
        (value ^ self.buffer).folded_multiply(MULTIPLE).rotate_left(rot)
    }

    #[inline]
    fn short_finish(&self) -> u64 {
        self.buffer.wrapping_add(self.pad)
    }
}

/// Provides methods to hash all of the primitive types.
impl Hasher for AHasher {
    #[inline]
    fn write_u8(&mut self, i: u8) {
        self.update(i as u64);
    }

    #[inline]
    fn write_u16(&mut self, i: u16) {
        self.update(i as u64);
    }

    #[inline]
    fn write_u32(&mut self, i: u32) {
        self.update(i as u64);
    }

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

    #[inline]
    fn write_u128(&mut self, i: u128) {
        let data: [u64; 2] = i.convert();
        self.update(data[0]);
        self.update(data[1]);
    }

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

    #[inline]
    #[allow(clippy::collapsible_if)]
    fn write(&mut self, input: &[u8]) {
        let mut data = input;
        let length = data.len() as u64;
        //Needs to be an add rather than an xor because otherwise it could be canceled with carefully formed input.
        self.buffer = self.buffer.wrapping_add(length).wrapping_mul(MULTIPLE);
        //A 'binary search' on sizes reduces the number of comparisons.
        if data.len() > 8 {
            if data.len() > 32 {
                let tail = data.read_last_u128();
                self.large_update(tail);
                while data.len() > 16 {
                    let (block, rest) = data.read_u128();
                    self.large_update(block);
                    data = rest;
                }
            } else {
                if data.len() > 16 {
                    self.large_update(data.read_u128().0);
                    self.large_update(data.read_last_u128());
                } else {
                    self.update(data.read_u64().0);
                    self.update(data.read_last_u64());
                }
            }
        } else {
            if data.len() >= 2 {
                if data.len() >= 4 {
                    let block: [u32; 2] = [data.read_u32().0, data.read_last_u32()];
                    self.update(block.convert());
                } else {
                    let value = [data.read_u16().0 as u32, data[data.len() - 1] as u32];
                    self.update(value.convert());
                }
            } else {
                let value = if data.len() > 0 {
                    data[0] //len 1
                } else {
                    0
                };
                self.update(value as u64);
            }
        }
    }
    #[inline]
    fn finish(&self) -> u64 {
        let rot = (self.buffer & 63) as u32;
        (self.buffer).folded_multiply(self.pad).rotate_left(rot)
    }
}

#[cfg(test)]
mod tests {
    use crate::convert::Convert;
    use crate::fallback_hash::*;

    #[test]
    fn test_hash() {
        let mut hasher = AHasher::new_with_keys(0, 0);
        let value: u64 = 1 << 32;
        hasher.update(value);
        let result = hasher.buffer;
        let mut hasher = AHasher::new_with_keys(0, 0);
        let value2: u64 = 1;
        hasher.update(value2);
        let result2 = hasher.buffer;
        let result: [u8; 8] = result.convert();
        let result2: [u8; 8] = 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>Simplify some of the paths of the fallback. This helps with alignment and makes it easier to LLVM to optimize.<commit_after>use crate::convert::*;
use crate::operations::*;
#[cfg(feature = "specialize")]
use crate::HasherExt;
use core::hash::Hasher;

///This constant come from Kunth's prng (Empirically it works better than those from splitmix32).
const MULTIPLE: u64 = crate::random_state::MULTIPLE;
const ROT: u32 = 23; //17

/// 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()`
///
/// [Clone] is also provided in case you wish to calculate hashes for two different items that
/// start with the same data.
///
#[derive(Debug, Clone)]
pub struct AHasher {
    buffer: u64,
    pad: u64,
    extra_keys: [u64; 2],
}

impl AHasher {
    /// Creates a new hasher keyed to the provided key.
    #[inline]
    #[allow(dead_code)] // Is not called if non-fallback hash is used.
    pub fn new_with_keys(key1: u128, key2: u128) -> AHasher {
        AHasher {
            buffer: key1 as u64,
            pad: key2 as u64,
            extra_keys: (key1 ^ key2).convert(),
        }
    }

    #[cfg(test)]
    #[allow(dead_code)] // Is not called if non-fallback hash is used.
    pub(crate) fn test_with_keys(key1: u64, key2: u64) -> AHasher {
        use crate::random_state::scramble_keys;
        let (k1, k2, k3, k4) = scramble_keys(key1, key2);
        AHasher {
            buffer: k1,
            pad: k2,
            extra_keys: [k3, k4],
        }
    }

    /// This update function has the goal of updating the buffer with a single multiply
    /// FxHash does this but is vulnerable to attack. To avoid this input needs to be masked to with an
    /// unpredictable value. Other hashes such as murmurhash have taken this approach but were found vulnerable
    /// to attack. The attack was based on the idea of reversing the pre-mixing (Which is necessarily
    /// reversible otherwise bits would be lost) then placing a difference in the highest bit before the
    /// multiply used to mix the data. Because a multiply can never affect the bits to the right of it, a
    /// subsequent update that also differed in this bit could result in a predictable collision.
    ///
    /// This version avoids this vulnerability while still only using a single multiply. It takes advantage
    /// of the fact that when a 64 bit multiply is performed the upper 64 bits are usually computed and thrown
    /// away. Instead it creates two 128 bit values where the upper 64 bits are zeros and multiplies them.
    /// (The compiler is smart enough to turn this into a 64 bit multiplication in the assembly)
    /// Then the upper bits are xored with the lower bits to produce a single 64 bit result.
    ///
    /// To understand why this is a good scrambling function it helps to understand multiply-with-carry PRNGs:
    /// https://en.wikipedia.org/wiki/Multiply-with-carry_pseudorandom_number_generator
    /// If the multiple is chosen well, this creates a long period, decent quality PRNG.
    /// Notice that this function is equivalent to this except the `buffer`/`state` is being xored with each
    /// new block of data. In the event that data is all zeros, it is exactly equivalent to a MWC PRNG.
    ///
    /// This is impervious to attack because every bit buffer at the end is dependent on every bit in
    /// `new_data ^ buffer`. For example suppose two inputs differed in only the 5th bit. Then when the
    /// multiplication is performed the `result` will differ in bits 5-69. More specifically it will differ by
    /// 2^5 * MULTIPLE. However in the next step bits 65-128 are turned into a separate 64 bit value. So the
    /// differing bits will be in the lower 6 bits of this value. The two intermediate values that differ in
    /// bits 5-63 and in bits 0-5 respectively get added together. Producing an output that differs in every
    /// bit. The addition carries in the multiplication and at the end additionally mean that the even if an
    /// attacker somehow knew part of (but not all) the contents of the buffer before hand,
    /// they would not be able to predict any of the bits in the buffer at the end.
    #[inline(always)]
    fn update(&mut self, new_data: u64) {
        self.buffer = (new_data ^ self.buffer).folded_multiply(MULTIPLE);
    }

    /// Similar to the above this function performs an update using a "folded multiply".
    /// However it takes in 128 bits of data instead of 64. Both halves must be masked.
    ///
    /// This makes it impossible for an attacker to place a single bit difference between
    /// two blocks so as to cancel each other.
    ///
    /// However this is not sufficient. to prevent (a,b) from hashing the same as (b,a) the buffer itself must
    /// be updated between calls in a way that does not commute. To achieve this XOR and Rotate are used.
    /// Add followed by xor is not the same as xor followed by add, and rotate ensures that the same out bits
    /// can't be changed by the same set of input bits. To cancel this sequence with subsequent input would require
    /// knowing the keys.
    #[inline(always)]
    fn large_update(&mut self, new_data: u128) {
        let block: [u64; 2] = new_data.convert();
        let combined = (block[0] ^ self.extra_keys[0]).folded_multiply(block[1] ^ self.extra_keys[1]);
        self.buffer = (self.pad.wrapping_add(combined) ^ self.buffer).rotate_left(ROT);
    }
}

#[cfg(feature = "specialize")]
impl HasherExt for AHasher {
    #[inline]
    fn hash_u64(self, value: u64) -> u64 {
        let rot = (self.pad & 64) as u32;
        (value ^ self.buffer).folded_multiply(MULTIPLE).rotate_left(rot)
    }

    #[inline]
    fn short_finish(&self) -> u64 {
        self.buffer.wrapping_add(self.pad)
    }
}

/// Provides methods to hash all of the primitive types.
impl Hasher for AHasher {
    #[inline]
    fn write_u8(&mut self, i: u8) {
        self.update(i as u64);
    }

    #[inline]
    fn write_u16(&mut self, i: u16) {
        self.update(i as u64);
    }

    #[inline]
    fn write_u32(&mut self, i: u32) {
        self.update(i as u64);
    }

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

    #[inline]
    fn write_u128(&mut self, i: u128) {
        let data: [u64; 2] = i.convert();
        self.update(data[0]);
        self.update(data[1]);
    }

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

    #[inline]
    #[allow(clippy::collapsible_if)]
    fn write(&mut self, input: &[u8]) {
        let mut data = input;
        let length = data.len() as u64;
        //Needs to be an add rather than an xor because otherwise it could be canceled with carefully formed input.
        self.buffer = self.buffer.wrapping_add(length).wrapping_mul(MULTIPLE);
        //A 'binary search' on sizes reduces the number of comparisons.
        if data.len() > 8 {
            if data.len() > 16 {
                let tail = data.read_last_u128();
                self.large_update(tail);
                while data.len() > 16 {
                    let (block, rest) = data.read_u128();
                    self.large_update(block);
                    data = rest;
                }
            } else {
                self.large_update([data.read_u64().0, data.read_last_u64()].convert());
            }
        } else {
            if data.len() >= 2 {
                if data.len() >= 4 {
                    let block = [data.read_u32().0 as u64, data.read_last_u32() as u64];
                    self.large_update(block.convert());
                } else {
                    let value = [data.read_u16().0 as u32, data[data.len() - 1] as u32];
                    self.update(value.convert());
                }
            } else {
                if data.len() > 0 {
                    self.update(data[0] as u64);
                }
            }
        }
    }
    #[inline]
    fn finish(&self) -> u64 {
        let rot = (self.buffer & 63) as u32;
        (self.buffer).folded_multiply(self.pad).rotate_left(rot)
    }
}

#[cfg(test)]
mod tests {
    use crate::convert::Convert;
    use crate::fallback_hash::*;

    #[test]
    fn test_hash() {
        let mut hasher = AHasher::new_with_keys(0, 0);
        let value: u64 = 1 << 32;
        hasher.update(value);
        let result = hasher.buffer;
        let mut hasher = AHasher::new_with_keys(0, 0);
        let value2: u64 = 1;
        hasher.update(value2);
        let result2 = hasher.buffer;
        let result: [u8; 8] = result.convert();
        let result2: [u8; 8] = 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>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Simple compression

*/

#[allow(missing_doc)];

use std::libc::{c_void, size_t, c_int};
use std::libc;
use std::vec;

pub mod rustrt {
    use std::libc::{c_int, c_void, size_t};

    #[link_name = "rustrt"]
    extern {
        pub fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
                                          src_buf_len: size_t,
                                          pout_len: *mut size_t,
                                          flags: c_int)
                                          -> *c_void;

        pub fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
                                            src_buf_len: size_t,
                                            pout_len: *mut size_t,
                                            flags: c_int)
                                            -> *c_void;
    }
}

static LZ_NONE : c_int = 0x0;   // Huffman-coding only.
static LZ_FAST : c_int = 0x1;   // LZ with only one probe
static LZ_NORM : c_int = 0x80;  // LZ with 128 probes, "normal"
static LZ_BEST : c_int = 0xfff; // LZ with 4095 probes, "best"
static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum

pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] {
    do bytes.as_imm_buf |b, len| {
        unsafe {
            let mut outsz : size_t = 0;
            let res =
                rustrt::tdefl_compress_mem_to_heap(b as *c_void,
                                                   len as size_t,
                                                   &mut outsz,
                                                   LZ_NORM);
            assert!(res as int != 0);
            let out = vec::raw::from_buf_raw(res as *u8,
                                             outsz as uint);
            libc::free(res);
            out
        }
    }
}

fn inflate_bytes_(bytes: &[u8], flags: c_int) -> ~[u8] {
    do bytes.as_imm_buf |b, len| {
        unsafe {
            let mut outsz : size_t = 0;
            let res =
                rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
                                                     len as size_t,
                                                     &mut outsz,
                                                     flags);
            assert!(res as int != 0);
            let out = vec::raw::from_buf_raw(res as *u8,
                                            outsz as uint);
            libc::free(res);
            out
        }
    }
}

pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] {
    inflate_bytes_(bytes, 0)
}

pub fn inflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
    inflate_bytes_(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
}

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

    #[test]
    fn test_flate_round_trip() {
        let mut r = rand::rng();
        let mut words = ~[];
        do 20.times {
            let range = r.gen_uint_range(1, 10);
            words.push(r.gen_bytes(range));
        }
        do 20.times {
            let mut input = ~[];
            do 2000.times {
                input.push_all(r.choose(words));
            }
            debug!("de/inflate of %u bytes of random word-sequences",
                   input.len());
            let cmp = deflate_bytes(input);
            let out = inflate_bytes(cmp);
            debug!("%u bytes deflated to %u (%.1f%% size)",
                   input.len(), cmp.len(),
                   100.0 * ((cmp.len() as float) / (input.len() as float)));
            assert_eq!(input, out);
        }
    }
}
<commit_msg>add extra::flate::deflate_bytes_zlib and a test<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Simple compression

*/

#[allow(missing_doc)];

use std::libc::{c_void, size_t, c_int};
use std::libc;
use std::vec;

pub mod rustrt {
    use std::libc::{c_int, c_void, size_t};

    #[link_name = "rustrt"]
    extern {
        pub fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
                                          src_buf_len: size_t,
                                          pout_len: *mut size_t,
                                          flags: c_int)
                                          -> *c_void;

        pub fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
                                            src_buf_len: size_t,
                                            pout_len: *mut size_t,
                                            flags: c_int)
                                            -> *c_void;
    }
}

static LZ_NONE : c_int = 0x0;   // Huffman-coding only.
static LZ_FAST : c_int = 0x1;   // LZ with only one probe
static LZ_NORM : c_int = 0x80;  // LZ with 128 probes, "normal"
static LZ_BEST : c_int = 0xfff; // LZ with 4095 probes, "best"
static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum

fn deflate_bytes_(bytes: &[u8], flags: c_int) -> ~[u8] {
    do bytes.as_imm_buf |b, len| {
        unsafe {
            let mut outsz : size_t = 0;
            let res =
                rustrt::tdefl_compress_mem_to_heap(b as *c_void,
                                                   len as size_t,
                                                   &mut outsz,
                                                   flags);
            assert!(res as int != 0);
            let out = vec::raw::from_buf_raw(res as *u8,
                                             outsz as uint);
            libc::free(res);
            out
        }
    }
}

pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] {
    deflate_bytes_(bytes, LZ_NORM)
}

pub fn deflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
    deflate_bytes_(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
}

fn inflate_bytes_(bytes: &[u8], flags: c_int) -> ~[u8] {
    do bytes.as_imm_buf |b, len| {
        unsafe {
            let mut outsz : size_t = 0;
            let res =
                rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
                                                     len as size_t,
                                                     &mut outsz,
                                                     flags);
            assert!(res as int != 0);
            let out = vec::raw::from_buf_raw(res as *u8,
                                            outsz as uint);
            libc::free(res);
            out
        }
    }
}

pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] {
    inflate_bytes_(bytes, 0)
}

pub fn inflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
    inflate_bytes_(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
}

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

    #[test]
    fn test_flate_round_trip() {
        let mut r = rand::rng();
        let mut words = ~[];
        do 20.times {
            let range = r.gen_uint_range(1, 10);
            words.push(r.gen_bytes(range));
        }
        do 20.times {
            let mut input = ~[];
            do 2000.times {
                input.push_all(r.choose(words));
            }
            debug!("de/inflate of %u bytes of random word-sequences",
                   input.len());
            let cmp = deflate_bytes(input);
            let out = inflate_bytes(cmp);
            debug!("%u bytes deflated to %u (%.1f%% size)",
                   input.len(), cmp.len(),
                   100.0 * ((cmp.len() as float) / (input.len() as float)));
            assert_eq!(input, out);
        }
    }

    #[test]
    fn test_zlib_flate() {
        let bytes = ~[1, 2, 3, 4, 5];
        let deflated = deflate_bytes(bytes);
        let inflated = inflate_bytes(deflated);
        assert_eq!(inflated, bytes);
    }
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]
#![feature(globs)]

extern crate router = "route-recognizer";
extern crate conduit;

use std::collections::HashMap;
use std::any::{Any, AnyRefExt};
use std::fmt::Show;

use router::{Router, Match};
use conduit::{Method, Handler, Request, Response};

pub struct RouteBuilder {
    routers: HashMap<Method, Router<Box<Handler + Send + Share>>>
}

impl RouteBuilder {
    pub fn new() -> RouteBuilder {
        RouteBuilder { routers: HashMap::new() }
    }

    pub fn recognize<'a>(&'a self, method: &Method, path: &str)
                         -> Result<Match<&'a Box<Handler + Send + Share>>, String>
    {
        match self.routers.find(method) {
            None => Err(format!("No router found for {}", method)),
            Some(router) => router.recognize(path)
        }
    }

    pub fn map<'a, H: Handler>(&'a mut self, method: Method, pattern: &str,
                               handler: H) -> &'a mut RouteBuilder {
        {
            let router = self.routers.find_or_insert_with(method, |_| Router::new());
            router.add(pattern, box handler as Box<Handler + Send + Share>);
        }
        self
    }

    pub fn get<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                               -> &'a mut RouteBuilder {
        self.map(conduit::Get, pattern, handler)
    }

    pub fn post<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                                -> &'a mut RouteBuilder {
        self.map(conduit::Post, pattern, handler)
    }

    pub fn put<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                               -> &'a mut RouteBuilder {
        self.map(conduit::Put, pattern, handler)
    }

    pub fn delete<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                                  -> &'a mut RouteBuilder {
        self.map(conduit::Delete, pattern, handler)
    }

    pub fn head<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                                -> &'a mut RouteBuilder {
        self.map(conduit::Head, pattern, handler)
    }
}

impl conduit::Handler for RouteBuilder {
    fn call(&self, request: &mut Request) -> Result<Response, Box<Show>> {
        let m = {
            let method = request.method();
            let path = request.path();

            match self.recognize(&method, path) {
                Ok(m) => m,
                Err(e) => return Err(box e as Box<Show>)
            }
        };

        {
            let extensions = request.mut_extensions();
            extensions.insert("router.params", box m.params.clone() as Box<Any>);
        }

        (*m.handler).call(request)
    }
}

pub trait RequestParams<'a> {
    fn params(self) -> &'a router::Params;
}

pub fn params<'a>(req: &'a mut Request) -> &'a router::Params {
    req.extensions().find(&"router.params")
        .and_then(|a| a.as_ref::<router::Params>())
        .expect("Missing params")
}

impl<'a> RequestParams<'a> for &'a mut Request {
    fn params(self) -> &'a router::Params {
        params(self)
    }
}

#[cfg(test)]
mod tests {
    extern crate semver;
    use std::io::net::ip::IpAddr;
    use std::collections::HashMap;
    use std::io::MemReader;
    use super::*;

    use conduit;
    use conduit::{Handler, Method, Scheme, Host, Headers, Extensions};

    struct RequestSentinel {
        method: Method,
        path: String,
        extensions: conduit::Extensions
    }

    impl RequestSentinel {
        fn new(method: Method, path: &'static str) -> RequestSentinel {
            RequestSentinel {
                path: path.to_string(),
                extensions: HashMap::new(),
                method: method
            }
        }
    }

    impl conduit::Request for RequestSentinel {
        fn http_version(&self) -> semver::Version { unimplemented!() }
        fn conduit_version(&self) -> semver::Version { unimplemented!() }
        fn method(&self) -> Method { self.method }
        fn scheme(&self) -> Scheme { unimplemented!() }
        fn host<'a>(&'a self) -> Host<'a> { unimplemented!() }
        fn virtual_root<'a>(&'a self) -> Option<&'a str> { unimplemented!() }
        fn path<'a>(&'a self) -> &'a str {
            self.path.as_slice()
        }
        fn query_string<'a>(&'a self) -> Option<&'a str> { unimplemented!() }
        fn remote_ip(&self) -> IpAddr { unimplemented!() }
        fn content_length(&self) -> Option<uint> { unimplemented!() }
        fn headers<'a>(&'a self) -> &'a Headers { unimplemented!() }
        fn body<'a>(&'a mut self) -> &'a mut Reader { unimplemented!() }
        fn extensions<'a>(&'a self) -> &'a Extensions {
            &self.extensions
        }
        fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions {
            &mut self.extensions
        }
    }

    #[test]
    fn basic_get() {
        let router = test_router();
        let mut req = RequestSentinel::new(conduit::Get, "/posts/1");
        let mut res = router.call(&mut req).ok().expect("No response");

        assert_eq!(res.status, (200, "OK"));
        assert_eq!(res.body.read_to_string().unwrap(), "1, Get".to_string());
    }

    #[test]
    fn basic_post() {
        let router = test_router();
        let mut req = RequestSentinel::new(conduit::Post, "/posts/10");
        let mut res = router.call(&mut req).ok().expect("No response");

        assert_eq!(res.status, (200, "OK"));
        assert_eq!(res.body.read_to_string().unwrap(), "10, Post".to_string());
    }

    #[test]
    fn nonexistent_route() {
        let router = test_router();
        let mut req = RequestSentinel::new(conduit::Post, "/nonexistent");
        router.call(&mut req).err().expect("No response");
    }

    fn test_router() -> RouteBuilder {
        let mut router = RouteBuilder::new();
        router.post("/posts/:id", test_handler);
        router.get("/posts/:id", test_handler);
        router
    }

    fn test_handler(req: &mut conduit::Request) -> Result<conduit::Response, ()> {
        let mut res = vec!();
        res.push(req.params()["id"]);
        res.push(format!("{}", req.method()));

        Ok(conduit::Response {
            status: (200, "OK"),
            headers: HashMap::new(),
            body: box MemReader::new(res.connect(", ").into_bytes())
        })
    }
}
<commit_msg>Don't require a mut request<commit_after>#![feature(macro_rules)]
#![feature(globs)]

extern crate router = "route-recognizer";
extern crate conduit;

use std::collections::HashMap;
use std::any::{Any, AnyRefExt};
use std::fmt::Show;

use router::{Router, Match};
use conduit::{Method, Handler, Request, Response};

pub struct RouteBuilder {
    routers: HashMap<Method, Router<Box<Handler + Send + Share>>>
}

impl RouteBuilder {
    pub fn new() -> RouteBuilder {
        RouteBuilder { routers: HashMap::new() }
    }

    pub fn recognize<'a>(&'a self, method: &Method, path: &str)
                         -> Result<Match<&'a Box<Handler + Send + Share>>, String>
    {
        match self.routers.find(method) {
            None => Err(format!("No router found for {}", method)),
            Some(router) => router.recognize(path)
        }
    }

    pub fn map<'a, H: Handler>(&'a mut self, method: Method, pattern: &str,
                               handler: H) -> &'a mut RouteBuilder {
        {
            let router = self.routers.find_or_insert_with(method, |_| Router::new());
            router.add(pattern, box handler as Box<Handler + Send + Share>);
        }
        self
    }

    pub fn get<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                               -> &'a mut RouteBuilder {
        self.map(conduit::Get, pattern, handler)
    }

    pub fn post<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                                -> &'a mut RouteBuilder {
        self.map(conduit::Post, pattern, handler)
    }

    pub fn put<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                               -> &'a mut RouteBuilder {
        self.map(conduit::Put, pattern, handler)
    }

    pub fn delete<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                                  -> &'a mut RouteBuilder {
        self.map(conduit::Delete, pattern, handler)
    }

    pub fn head<'a, H: Handler>(&'a mut self, pattern: &str, handler: H)
                                -> &'a mut RouteBuilder {
        self.map(conduit::Head, pattern, handler)
    }
}

impl conduit::Handler for RouteBuilder {
    fn call(&self, request: &mut Request) -> Result<Response, Box<Show>> {
        let m = {
            let method = request.method();
            let path = request.path();

            match self.recognize(&method, path) {
                Ok(m) => m,
                Err(e) => return Err(box e as Box<Show>)
            }
        };

        {
            let extensions = request.mut_extensions();
            extensions.insert("router.params", box m.params.clone() as Box<Any>);
        }

        (*m.handler).call(request)
    }
}

pub trait RequestParams<'a> {
    fn params(self) -> &'a router::Params;
}

pub fn params<'a>(req: &'a Request) -> &'a router::Params {
    req.extensions().find(&"router.params")
        .and_then(|a| a.as_ref::<router::Params>())
        .expect("Missing params")
}

impl<'a> RequestParams<'a> for &'a Request {
    fn params(self) -> &'a router::Params {
        params(self)
    }
}

#[cfg(test)]
mod tests {
    extern crate semver;
    use std::io::net::ip::IpAddr;
    use std::collections::HashMap;
    use std::io::MemReader;
    use super::*;

    use conduit;
    use conduit::{Handler, Method, Scheme, Host, Headers, Extensions};

    struct RequestSentinel {
        method: Method,
        path: String,
        extensions: conduit::Extensions
    }

    impl RequestSentinel {
        fn new(method: Method, path: &'static str) -> RequestSentinel {
            RequestSentinel {
                path: path.to_string(),
                extensions: HashMap::new(),
                method: method
            }
        }
    }

    impl conduit::Request for RequestSentinel {
        fn http_version(&self) -> semver::Version { unimplemented!() }
        fn conduit_version(&self) -> semver::Version { unimplemented!() }
        fn method(&self) -> Method { self.method }
        fn scheme(&self) -> Scheme { unimplemented!() }
        fn host<'a>(&'a self) -> Host<'a> { unimplemented!() }
        fn virtual_root<'a>(&'a self) -> Option<&'a str> { unimplemented!() }
        fn path<'a>(&'a self) -> &'a str {
            self.path.as_slice()
        }
        fn query_string<'a>(&'a self) -> Option<&'a str> { unimplemented!() }
        fn remote_ip(&self) -> IpAddr { unimplemented!() }
        fn content_length(&self) -> Option<uint> { unimplemented!() }
        fn headers<'a>(&'a self) -> &'a Headers { unimplemented!() }
        fn body<'a>(&'a mut self) -> &'a mut Reader { unimplemented!() }
        fn extensions<'a>(&'a self) -> &'a Extensions {
            &self.extensions
        }
        fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions {
            &mut self.extensions
        }
    }

    #[test]
    fn basic_get() {
        let router = test_router();
        let mut req = RequestSentinel::new(conduit::Get, "/posts/1");
        let mut res = router.call(&mut req).ok().expect("No response");

        assert_eq!(res.status, (200, "OK"));
        assert_eq!(res.body.read_to_string().unwrap(), "1, Get".to_string());
    }

    #[test]
    fn basic_post() {
        let router = test_router();
        let mut req = RequestSentinel::new(conduit::Post, "/posts/10");
        let mut res = router.call(&mut req).ok().expect("No response");

        assert_eq!(res.status, (200, "OK"));
        assert_eq!(res.body.read_to_string().unwrap(), "10, Post".to_string());
    }

    #[test]
    fn nonexistent_route() {
        let router = test_router();
        let mut req = RequestSentinel::new(conduit::Post, "/nonexistent");
        router.call(&mut req).err().expect("No response");
    }

    fn test_router() -> RouteBuilder {
        let mut router = RouteBuilder::new();
        router.post("/posts/:id", test_handler);
        router.get("/posts/:id", test_handler);
        router
    }

    fn test_handler(req: &mut conduit::Request) -> Result<conduit::Response, ()> {
        let mut res = vec!();
        res.push(req.params()["id"]);
        res.push(format!("{}", req.method()));

        Ok(conduit::Response {
            status: (200, "OK"),
            headers: HashMap::new(),
            body: box MemReader::new(res.connect(", ").into_bytes())
        })
    }
}
<|endoftext|>


<commit_before>mod memory;
mod stack;
mod pc;
mod storage;
mod params;
mod eval;
mod commit;
pub mod errors;

pub use self::memory::{Memory, SeqMemory};
pub use self::stack::Stack;
pub use self::pc::{PC, Instruction};
pub use self::storage::{Storage, HashMapStorage};
pub use self::params::{Context, BlockHeader, Log, Patch};
pub use self::eval::{State, Machine, MachineStatus};
pub use self::commit::{AccountCommitment, Account};

use std::collections::hash_map;
use utils::bigint::M256;
use utils::gas::Gas;
use utils::address::Address;
use self::errors::{RequireError, CommitError, VMError};

pub type SeqVM = VM<SeqMemory, HashMapStorage>;

pub struct VM<M, S>(Vec<Machine<M, S>>, Vec<Context>);

#[derive(Debug, Clone)]
pub enum VMStatus {
    Running,
    ExitedOk,
    ExitedErr(VMError),
}

impl<M: Memory + Default, S: Storage + Default + Clone> VM<M, S> {
    pub fn new(context: Context, block: BlockHeader, patch: Patch) -> VM<M, S> {
        let mut machines = Vec::new();
        machines.push(Machine::new(context, block, patch, 0));
        VM(machines, Vec::new())
    }

    pub fn commit_account(&mut self, commitment: AccountCommitment<S>) -> Result<(), CommitError> {
        for machine in &mut self.0 {
            machine.commit_account(commitment.clone())?;
        }
        Ok(())
    }

    pub fn commit_blockhash(&mut self, number: M256, hash: M256) -> Result<(), CommitError> {
        for machine in &mut self.0 {
            machine.commit_blockhash(number, hash)?;
        }
        Ok(())
    }

    pub fn status(&self) -> VMStatus {
        match self.0[0].status() {
            MachineStatus::Running | MachineStatus::InvokeCreate(_) | MachineStatus::InvokeCall(_, _) => VMStatus::Running,
            MachineStatus::ExitedOk => VMStatus::ExitedOk,
            MachineStatus::ExitedErr(err) => VMStatus::ExitedErr(err.into()),
        }
    }

    pub fn step(&mut self) -> Result<(), RequireError> {
        if self.0.len() >= 1024 {
            panic!();
        }
        match self.0.last().unwrap().status().clone() {
            MachineStatus::Running => {
                self.0.last_mut().unwrap().step()
            },
            MachineStatus::ExitedOk | MachineStatus::ExitedErr(_) => {
                if self.0.len() <= 1 {
                    Ok(())
                } else {
                    let finished = self.0.pop().unwrap();
                    self.0.last_mut().unwrap().apply_sub(finished);
                    Ok(())
                }
            },
            MachineStatus::InvokeCall(context, _) | MachineStatus::InvokeCreate(context) => {
                self.1.push(context.clone());
                let sub = self.0.last().unwrap().derive(context);
                self.0.push(sub);
                Ok(())
            },
        }
    }

    pub fn fire(&mut self) -> Result<(), RequireError> {
        loop {
            match self.status() {
                VMStatus::Running => self.step()?,
                VMStatus::ExitedOk | VMStatus::ExitedErr(_) => return Ok(()),
            }
        }
    }

    pub fn accounts(&self) -> hash_map::Values<Address, Account<S>> {
        self.0[0].state().account_state.accounts()
    }

    pub fn out(&self) -> &[u8] {
        self.0[0].state().out.as_slice()
    }

    pub fn available_gas(&self) -> Gas {
        self.0[0].state().available_gas()
    }

    pub fn refunded_gas(&self) -> Gas {
        self.0[0].state().refunded_gas
    }

    pub fn logs(&self) -> &[Log] {
        self.0[0].state().logs.as_slice()
    }

    pub fn history(&self) -> &[Context] {
        self.1.as_slice()
    }
}
<commit_msg>Problem: initial depth is incorrect Solution: fix it<commit_after>mod memory;
mod stack;
mod pc;
mod storage;
mod params;
mod eval;
mod commit;
pub mod errors;

pub use self::memory::{Memory, SeqMemory};
pub use self::stack::Stack;
pub use self::pc::{PC, Instruction};
pub use self::storage::{Storage, HashMapStorage};
pub use self::params::{Context, BlockHeader, Log, Patch};
pub use self::eval::{State, Machine, MachineStatus};
pub use self::commit::{AccountCommitment, Account};

use std::collections::hash_map;
use utils::bigint::M256;
use utils::gas::Gas;
use utils::address::Address;
use self::errors::{RequireError, CommitError, VMError};

pub type SeqVM = VM<SeqMemory, HashMapStorage>;

pub struct VM<M, S>(Vec<Machine<M, S>>, Vec<Context>);

#[derive(Debug, Clone)]
pub enum VMStatus {
    Running,
    ExitedOk,
    ExitedErr(VMError),
}

impl<M: Memory + Default, S: Storage + Default + Clone> VM<M, S> {
    pub fn new(context: Context, block: BlockHeader, patch: Patch) -> VM<M, S> {
        let mut machines = Vec::new();
        machines.push(Machine::new(context, block, patch, 1));
        VM(machines, Vec::new())
    }

    pub fn commit_account(&mut self, commitment: AccountCommitment<S>) -> Result<(), CommitError> {
        for machine in &mut self.0 {
            machine.commit_account(commitment.clone())?;
        }
        Ok(())
    }

    pub fn commit_blockhash(&mut self, number: M256, hash: M256) -> Result<(), CommitError> {
        for machine in &mut self.0 {
            machine.commit_blockhash(number, hash)?;
        }
        Ok(())
    }

    pub fn status(&self) -> VMStatus {
        match self.0[0].status() {
            MachineStatus::Running | MachineStatus::InvokeCreate(_) | MachineStatus::InvokeCall(_, _) => VMStatus::Running,
            MachineStatus::ExitedOk => VMStatus::ExitedOk,
            MachineStatus::ExitedErr(err) => VMStatus::ExitedErr(err.into()),
        }
    }

    pub fn step(&mut self) -> Result<(), RequireError> {
        if self.0.len() > 1024 {
            panic!();
        }
        match self.0.last().unwrap().status().clone() {
            MachineStatus::Running => {
                self.0.last_mut().unwrap().step()
            },
            MachineStatus::ExitedOk | MachineStatus::ExitedErr(_) => {
                if self.0.len() <= 1 {
                    Ok(())
                } else {
                    let finished = self.0.pop().unwrap();
                    self.0.last_mut().unwrap().apply_sub(finished);
                    Ok(())
                }
            },
            MachineStatus::InvokeCall(context, _) | MachineStatus::InvokeCreate(context) => {
                self.1.push(context.clone());
                let sub = self.0.last().unwrap().derive(context);
                self.0.push(sub);
                Ok(())
            },
        }
    }

    pub fn fire(&mut self) -> Result<(), RequireError> {
        loop {
            match self.status() {
                VMStatus::Running => self.step()?,
                VMStatus::ExitedOk | VMStatus::ExitedErr(_) => return Ok(()),
            }
        }
    }

    pub fn accounts(&self) -> hash_map::Values<Address, Account<S>> {
        self.0[0].state().account_state.accounts()
    }

    pub fn out(&self) -> &[u8] {
        self.0[0].state().out.as_slice()
    }

    pub fn available_gas(&self) -> Gas {
        self.0[0].state().available_gas()
    }

    pub fn refunded_gas(&self) -> Gas {
        self.0[0].state().refunded_gas
    }

    pub fn logs(&self) -> &[Log] {
        self.0[0].state().logs.as_slice()
    }

    pub fn history(&self) -> &[Context] {
        self.1.as_slice()
    }
}
<|endoftext|>


<commit_before>extern crate rustorm;
extern crate uuid;
extern crate chrono;
extern crate rustc_serialize;

use rustorm::platform::postgres::Postgres;
use rustorm::pool::ManagedPool;

use rustorm::table::IsTable;
use rustorm::dao::{IsDao,Value};
use rustorm::query::Query;
use rustorm::query::{Filter,Equality,Operand};
use rustorm::dao::Dao;
use gen::bazaar::Product;
use gen::bazaar::product;
use gen::bazaar::ProductAvailability;
use gen::bazaar::product_availability;
use gen::bazaar::ProductCategory;
use gen::bazaar::product_category;
use gen::bazaar::Category;
use gen::bazaar::category;
use gen::bazaar::ProductPhoto;
use gen::bazaar::product_photo;
use gen::bazaar::Photo;
use gen::bazaar::photo;

use rustorm::query::Function;
use rustorm::query::function::COUNT;
use rustorm::query::QueryBuilder;
use gen::bazaar;
use rustorm::query::ToTableName;
use rustorm::query::HasEquality;
use rustorm::query::order::HasDirection;
use rustorm::query::join::ToJoin;
use rustorm::query::builder::SELECT;

mod gen;

#[test]
fn test_complex(){
    let pg = Postgres::new();
    let frag = SELECT().ALL()
        .FROM(&bazaar::product)
        .LEFT_JOIN(bazaar::product_category
           .ON(product_category::product_id.EQ(&product::product_id)))
        .LEFT_JOIN(bazaar::category
            .ON(category::category_id.EQ(&product_category::category_id)))
        .LEFT_JOIN(bazaar::product_photo
            .ON(product::product_id.EQ(&product_photo::product_id)))
        .LEFT_JOIN(bazaar::photo
            .ON(product_photo::photo_id.EQ(&photo::photo_id)))
        .WHERE(
				product::name.EQ_VALUE(&"GTX660 Ti videocard")
			.AND(category::name.EQ_VALUE(&"Electronic"))
		)
        .ORDER_BY(&[product::name.ASC(), product::created.DESC()])
        .GROUP_BY(&[category::name])
        .HAVING(COUNT(&"*").GT(&1))
    	.build(&pg);

    let expected = "
SELECT *
     FROM bazaar.product
          LEFT JOIN bazaar.product_category
          ON product_id = product.product_id
          LEFT JOIN bazaar.category
          ON category_id = product_category.category_id
          LEFT JOIN bazaar.product_photo
          ON product_id = product_photo.product_id
          LEFT JOIN bazaar.photo
          ON photo_id = photo.photo_id
    WHERE ( product.name = $1  AND category.name = $2   )
 GROUP BY (category.name)
   HAVING  COUNT(*) > $3
 ORDER BY product.name ASC, product.created DESC
 ".to_string();
    println!("actual:   {{{}}} [{}]", frag.sql, frag.sql.len());
    println!("expected: {{{}}} [{}]", expected, expected.len());
    assert_eq!(frag.sql.trim() , expected.trim());
}

<commit_msg>tests corrections<commit_after>extern crate rustorm;
extern crate uuid;
extern crate chrono;
extern crate rustc_serialize;

use rustorm::platform::postgres::Postgres;
use rustorm::pool::ManagedPool;

use rustorm::table::IsTable;
use rustorm::dao::{IsDao,Value};
use rustorm::query::Query;
use rustorm::query::{Filter,Equality,Operand};
use rustorm::dao::Dao;
use gen::bazaar::Product;
use gen::bazaar::product;
use gen::bazaar::ProductAvailability;
use gen::bazaar::product_availability;
use gen::bazaar::ProductCategory;
use gen::bazaar::product_category;
use gen::bazaar::Category;
use gen::bazaar::category;
use gen::bazaar::ProductPhoto;
use gen::bazaar::product_photo;
use gen::bazaar::Photo;
use gen::bazaar::photo;

use rustorm::query::Function;
use rustorm::query::function::COUNT;
use rustorm::query::QueryBuilder;
use gen::bazaar;
use rustorm::query::ToTableName;
use rustorm::query::HasEquality;
use rustorm::query::order::HasDirection;
use rustorm::query::join::ToJoin;
use rustorm::query::builder::SELECT;

mod gen;

#[test]
fn test_complex(){
    let pg = Postgres::new();
    let frag = SELECT().ALL()
        .FROM(&bazaar::product)
        .LEFT_JOIN(bazaar::product_category
           .ON(product_category::product_id.EQ(&product::product_id)))
        .LEFT_JOIN(bazaar::category
            .ON(category::category_id.EQ(&product_category::category_id)))
        .LEFT_JOIN(bazaar::product_photo
            .ON(product::product_id.EQ(&product_photo::product_id)))
        .LEFT_JOIN(bazaar::photo
            .ON(product_photo::photo_id.EQ(&photo::photo_id)))
        .WHERE(
				product::name.EQ_VALUE(&"GTX660 Ti videocard")
			.AND(category::name.EQ_VALUE(&"Electronic"))
		)
        .ORDER_BY(&[product::name.ASC(), product::created.DESC()])
        .GROUP_BY(&[category::name])
        .HAVING(COUNT(&"*").GT(&1))
    	.build(&pg);

    let expected = "
SELECT *
     FROM bazaar.product
          LEFT JOIN bazaar.product_category
          ON product_id = product.product_id
          LEFT JOIN bazaar.category
          ON category_id = product_category.category_id
          LEFT JOIN bazaar.product_photo
          ON product_id = product_photo.product_id
          LEFT JOIN bazaar.photo
          ON photo_id = photo.photo_id
    WHERE ( product.name = $1  AND category.name = $2   )
 GROUP BY category.name
   HAVING  COUNT(*) > $3
 ORDER BY product.name ASC, product.created DESC
 ".to_string();
    println!("actual:   {{{}}} [{}]", frag.sql, frag.sql.len());
    println!("expected: {{{}}} [{}]", expected, expected.len());
    assert_eq!(frag.sql.trim() , expected.trim());
}

<|endoftext|>


<commit_before>use super::Graph;
use super::dominators::{Dominators, dominators_given_rpo};
use super::iterate::reverse_post_order;
use super::node_vec::NodeVec;
use super::reachable::{Reachability, reachable_given_rpo};

use std::u32;

#[cfg(test)]
mod test;

pub fn loop_tree<G: Graph>(graph: &G) -> LoopTree<G> {
    let reverse_post_order = reverse_post_order(graph, graph.start_node());
    let reachable = reachable_given_rpo(graph, &reverse_post_order);
    let dominators = dominators_given_rpo(graph, &reverse_post_order);
    loop_tree_given(graph, &reverse_post_order, &reachable, &dominators)
}

pub fn loop_tree_given<G: Graph>(graph: &G,
                                 rpo: &[G::Node],
                                 reachable: &Reachability<G>,
                                 dominators: &Dominators<G>)
                                 -> LoopTree<G>
{
    let mut loop_ids: NodeVec<G, Option<LoopId>> = NodeVec::from_default(graph);
    let mut loop_nodes: Vec<LoopNode<G>> = vec![];

    for &node in rpo {
        // Find innermost loop that `node` is a member of (excluding
        // any loop where `node` is the head), if any.
        let innermost_loop_id =
            dominators.dominators(node)
                      .filter(|&dom| dom != node)
                      .filter(|&dom| reachable.can_reach(node, dom))
                      .next()
                      .map(|n| loop_ids[n].unwrap());

        // `node` itself is a loop head if it dominates any of its
        // predecessors.
        let node_is_loop_head =
            graph.predecessors(node)
                 .any(|pred| dominators.is_dominated_by(pred, node));

        if node_is_loop_head {
            loop_nodes.push(LoopNode {
                parent: innermost_loop_id,
                head: node
            });
            loop_ids[node] = Some(LoopId::from(loop_nodes.len() - 1));
        } else {
            loop_ids[node] = innermost_loop_id;
        }
    }

    LoopTree {
        loop_ids: loop_ids,
        loop_nodes: loop_nodes,
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct LoopId {
    index: u32
}

impl From<usize> for LoopId {
    fn from(value: usize) -> LoopId {
        assert!(value < (u32::MAX as usize));
        LoopId { index: value as u32 }
    }
}

impl From<LoopId> for usize {
    fn from(id: LoopId) -> usize {
        id.index as usize
    }
}

#[derive(Debug)]
pub struct LoopNode<G: Graph> {
    parent: Option<LoopId>,
    head: G::Node,
}

impl<G: Graph> Copy for LoopNode<G> { }

impl<G: Graph> Clone for LoopNode<G> { fn clone(&self) -> Self { *self } }

pub struct LoopTree<G: Graph> {
    loop_ids: NodeVec<G, Option<LoopId>>,
    loop_nodes: Vec<LoopNode<G>>,
}

impl<G: Graph> LoopTree<G> {
    pub fn loop_id(&self, node: G::Node) -> Option<LoopId> {
        self.loop_ids[node]
    }

    pub fn loop_head(&self, node: G::Node) -> Option<G::Node> {
        self.loop_ids[node].map(|l| self.loop_node(l).head)
    }

    pub fn loop_node(&self, id: LoopId) -> LoopNode<G> {
        self.loop_nodes[usize::from(id)]
    }
}
<commit_msg>s/opaque filter/skip/<commit_after>use super::Graph;
use super::dominators::{Dominators, dominators_given_rpo};
use super::iterate::reverse_post_order;
use super::node_vec::NodeVec;
use super::reachable::{Reachability, reachable_given_rpo};

use std::u32;

#[cfg(test)]
mod test;

pub fn loop_tree<G: Graph>(graph: &G) -> LoopTree<G> {
    let reverse_post_order = reverse_post_order(graph, graph.start_node());
    let reachable = reachable_given_rpo(graph, &reverse_post_order);
    let dominators = dominators_given_rpo(graph, &reverse_post_order);
    loop_tree_given(graph, &reverse_post_order, &reachable, &dominators)
}

pub fn loop_tree_given<G: Graph>(graph: &G,
                                 rpo: &[G::Node],
                                 reachable: &Reachability<G>,
                                 dominators: &Dominators<G>)
                                 -> LoopTree<G>
{
    let mut loop_ids: NodeVec<G, Option<LoopId>> = NodeVec::from_default(graph);
    let mut loop_nodes: Vec<LoopNode<G>> = vec![];

    for &node in rpo {
        // Find innermost loop that `node` is a member of (excluding
        // any loop where `node` is the head), if any.
        let innermost_loop_id =
            dominators.dominators(node)
                      .skip(1)
                      .filter(|&dom| reachable.can_reach(node, dom))
                      .next()
                      .map(|n| loop_ids[n].unwrap());

        // `node` itself is a loop head if it dominates any of its
        // predecessors.
        let node_is_loop_head =
            graph.predecessors(node)
                 .any(|pred| dominators.is_dominated_by(pred, node));

        if node_is_loop_head {
            loop_nodes.push(LoopNode {
                parent: innermost_loop_id,
                head: node
            });
            loop_ids[node] = Some(LoopId::from(loop_nodes.len() - 1));
        } else {
            loop_ids[node] = innermost_loop_id;
        }
    }

    LoopTree {
        loop_ids: loop_ids,
        loop_nodes: loop_nodes,
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct LoopId {
    index: u32
}

impl From<usize> for LoopId {
    fn from(value: usize) -> LoopId {
        assert!(value < (u32::MAX as usize));
        LoopId { index: value as u32 }
    }
}

impl From<LoopId> for usize {
    fn from(id: LoopId) -> usize {
        id.index as usize
    }
}

#[derive(Debug)]
pub struct LoopNode<G: Graph> {
    parent: Option<LoopId>,
    head: G::Node,
}

impl<G: Graph> Copy for LoopNode<G> { }

impl<G: Graph> Clone for LoopNode<G> { fn clone(&self) -> Self { *self } }

pub struct LoopTree<G: Graph> {
    loop_ids: NodeVec<G, Option<LoopId>>,
    loop_nodes: Vec<LoopNode<G>>,
}

impl<G: Graph> LoopTree<G> {
    pub fn loop_id(&self, node: G::Node) -> Option<LoopId> {
        self.loop_ids[node]
    }

    pub fn loop_head(&self, node: G::Node) -> Option<G::Node> {
        self.loop_ids[node].map(|l| self.loop_node(l).head)
    }

    pub fn loop_node(&self, id: LoopId) -> LoopNode<G> {
        self.loop_nodes[usize::from(id)]
    }
}
<|endoftext|>


<commit_before>extern crate simd;
use simd::u8x16;
use simd::ssse3::*;

use std::{env, process};

struct State {
    s: [u8; 16],
    flip_masks: [u8x16; 16],
    rotate_masks: [u8x16; 16],

    maxflips: i32,
    odd: u16,
    checksum: i32,
}
impl State {
    fn new() -> State {
        State {
            s: [0; 16],
            flip_masks: [u8x16::splat(0); 16],
            rotate_masks: [u8x16::splat(0); 16],

            maxflips: 0,
            odd: 0,
            checksum: 0,
        }
    }
    #[inline(never)]
    fn rotate_sisd(&mut self, n: usize) {
        let c = self.s[0];
        for i in 1..(n + 1) {
            self.s[i - 1] = self.s[i];
        }
        self.s[n] = c;
    }
    #[inline(never)]
    fn popmasks(&mut self) {
        let mut mask = [0_u8; 16];
        for i in 0..16 {
            for j in 0..16 { mask[j] = j as u8; }

            for x in 0..(i+1)/2 {
                mask.swap(x, i - x);
            }

            self.flip_masks[i] = u8x16::load(&mask, 0);

            for j in 0..16 { self.s[j] = j as u8; }
            self.rotate_sisd(i);
            self.rotate_masks[i] = self.load_s();
        }
    }
    fn rotate(&mut self, n: usize) {
        self.load_s().shuf(self.rotate_masks[n]).store(&mut self.s, 0)
    }

    fn load_s(&self) -> u8x16 {
        u8x16::load(&self.s, 0)
    }

    #[inline(never)]
    fn tk(&mut self, n: usize) {
        #[derive(Copy, Clone, Debug)]
        struct Perm {
            perm: u8x16,
            start: u8,
            odd: u16
        }

        let mut perms = [Perm { perm: u8x16::splat(0), start: 0 , odd: 0 }; 60];

        let mut i = 0;
        let mut c = [0_u8; 16];
        let mut perm_max = 0;

        while i < n {
            while i < n && perm_max < 60 {
                self.rotate(i);
                if c[i] as usize >= i {
                    c[i] = 0;
                    i += 1;
                    continue
                }

                c[i] += 1;
                i = 1;
                self.odd = !self.odd;
                if self.s[0] != 0 {
                    if self.s[self.s[0] as usize] != 0 {
                        perms[perm_max].perm = self.load_s();
                        perms[perm_max].start = self.s[0];
                        perms[perm_max].odd = self.odd;
                        perm_max += 1;
                    } else {
                        if self.maxflips == 0 { self.maxflips = 1 }
                        self.checksum += if self.odd != 0 { -1 } else { 1 };
                    }
                }
            }

            let mut k = 0;
            while k < std::cmp::max(1, perm_max) - 1 {
                let pk = &perms[k];
                let pk1 = &perms[k + 1];
                //println!("perm1 {:?}\nperm2 {:?}", pk.perm, pk1.perm);
                let mut perm1 = pk.perm;
                let mut perm2 = pk1.perm;

                let mut f1 = 0;
                let mut f2 = 0;
                let mut toterm1 = pk.start;
                let mut toterm2 = pk1.start;

                while toterm1 != 0 && toterm2 != 0 {
                    perm1 = perm1.shuf(self.flip_masks[toterm1 as usize]);
                    perm2 = perm2.shuf(self.flip_masks[toterm2 as usize]);
                    toterm1 = perm1.extract(0);
                    toterm2 = perm2.extract(0);

                    f1 += 1; f2 += 1;
                }
                while toterm1 != 0 {
                    perm1 = perm1.shuf(self.flip_masks[toterm1 as usize]);
                    toterm1 = perm1.extract(0);
                    f1 += 1;
                }
                while toterm2 != 0 {
                    perm2 = perm2.shuf(self.flip_masks[toterm2 as usize]);
                    toterm2 = perm2.extract(0);
                    f2 += 1;
                }

                if f1 > self.maxflips { self.maxflips = f1 }
                if f2 > self.maxflips { self.maxflips = f2 }
                self.checksum += if pk.odd != 0 { -f1 } else { f1 };
                self.checksum += if pk1.odd != 0 { -f2 } else { f2 };

                k += 2;
            }
            while k < perm_max {
                let pk = &perms[k];
                let mut perm = pk.perm;
                let mut f = 0;
                let mut toterm = pk.start;
                while toterm != 0 {
                    perm = perm.shuf(self.flip_masks[toterm as usize]);
                    toterm = perm.extract(0);
                    f += 1;
                }
                if f > self.maxflips { self.maxflips = f }
                self.checksum += if pk.odd != 0 { -f } else { f };
                k += 1
            }
            perm_max = 0;
        }
    }
}

fn main() {
    let mut state = State::new();
    state.popmasks();

    let args = env::args().collect::<Vec<_>>();
    if args.len() < 2 {
        println!("usage: {} number", args[0]);
        process::exit(1)
    }
    let max_n = args[1].parse().unwrap();
    if max_n < 3 || max_n > 15 {
        println!("range: must be 3 <= n <= 14");
        process::exit(1);
    }
    for i in 0..max_n { state.s[i] = i as u8 }
    state.tk(max_n);

    println!("{}\nPfannkuchen({}) = {}", state.checksum, max_n, state.maxflips);
}
<commit_msg>Make fannkuch-redux work on ARM too.<commit_after>extern crate simd;
use simd::u8x16;

use std::{env, process};

#[cfg(target_arch = "arm")]
#[inline(always)]
fn shuffle(x: u8x16, y: u8x16) -> u8x16 {
    use simd::neon::*;
    #[inline(always)]
    fn split(x: u8x16) -> (u8x8, u8x8) {
        unsafe {std::mem::transmute(x)}
    }
    fn join(x: u8x8, y: u8x8) -> u8x16 {
        unsafe {std::mem::transmute((x, y))}
    }

    let (t0, t1) = split(x);
    let (i0, i1) = split(y);
    join(i0.table_lookup_2(t0, t1),
         i1.table_lookup_2(t0, t1))
}

#[cfg(any(target_arch = "x86",
          target_arch = "x86_64"))]
#[inline(always)]
fn shuffle(x: u8x16, y: u8x16) -> u8x16 {
    use simd::ssse3::*;
    x.shuf(y)
}

struct State {
    s: [u8; 16],
    flip_masks: [u8x16; 16],
    rotate_masks: [u8x16; 16],

    maxflips: i32,
    odd: u16,
    checksum: i32,
}
impl State {
    fn new() -> State {
        State {
            s: [0; 16],
            flip_masks: [u8x16::splat(0); 16],
            rotate_masks: [u8x16::splat(0); 16],

            maxflips: 0,
            odd: 0,
            checksum: 0,
        }
    }
    #[inline(never)]
    fn rotate_sisd(&mut self, n: usize) {
        let c = self.s[0];
        for i in 1..(n + 1) {
            self.s[i - 1] = self.s[i];
        }
        self.s[n] = c;
    }
    #[inline(never)]
    fn popmasks(&mut self) {
        let mut mask = [0_u8; 16];
        for i in 0..16 {
            for j in 0..16 { mask[j] = j as u8; }

            for x in 0..(i+1)/2 {
                mask.swap(x, i - x);
            }

            self.flip_masks[i] = u8x16::load(&mask, 0);

            for j in 0..16 { self.s[j] = j as u8; }
            self.rotate_sisd(i);
            self.rotate_masks[i] = self.load_s();
        }
    }
    fn rotate(&mut self, n: usize) {
        shuffle(self.load_s(), self.rotate_masks[n]).store(&mut self.s, 0)
    }

    fn load_s(&self) -> u8x16 {
        u8x16::load(&self.s, 0)
    }

    #[inline(never)]
    fn tk(&mut self, n: usize) {
        #[derive(Copy, Clone, Debug)]
        struct Perm {
            perm: u8x16,
            start: u8,
            odd: u16
        }

        let mut perms = [Perm { perm: u8x16::splat(0), start: 0 , odd: 0 }; 60];

        let mut i = 0;
        let mut c = [0_u8; 16];
        let mut perm_max = 0;

        while i < n {
            while i < n && perm_max < 60 {
                self.rotate(i);
                if c[i] as usize >= i {
                    c[i] = 0;
                    i += 1;
                    continue
                }

                c[i] += 1;
                i = 1;
                self.odd = !self.odd;
                if self.s[0] != 0 {
                    if self.s[self.s[0] as usize] != 0 {
                        perms[perm_max].perm = self.load_s();
                        perms[perm_max].start = self.s[0];
                        perms[perm_max].odd = self.odd;
                        perm_max += 1;
                    } else {
                        if self.maxflips == 0 { self.maxflips = 1 }
                        self.checksum += if self.odd != 0 { -1 } else { 1 };
                    }
                }
            }

            let mut k = 0;
            while k < std::cmp::max(1, perm_max) - 1 {
                let pk = &perms[k];
                let pk1 = &perms[k + 1];
                //println!("perm1 {:?}\nperm2 {:?}", pk.perm, pk1.perm);
                let mut perm1 = pk.perm;
                let mut perm2 = pk1.perm;

                let mut f1 = 0;
                let mut f2 = 0;
                let mut toterm1 = pk.start;
                let mut toterm2 = pk1.start;

                while toterm1 != 0 && toterm2 != 0 {
                    perm1 = shuffle(perm1, self.flip_masks[toterm1 as usize]);
                    perm2 = shuffle(perm2, self.flip_masks[toterm2 as usize]);
                    toterm1 = perm1.extract(0);
                    toterm2 = perm2.extract(0);

                    f1 += 1; f2 += 1;
                }
                while toterm1 != 0 {
                    perm1 = shuffle(perm1, self.flip_masks[toterm1 as usize]);
                    toterm1 = perm1.extract(0);
                    f1 += 1;
                }
                while toterm2 != 0 {
                    perm2 = shuffle(perm2, self.flip_masks[toterm2 as usize]);
                    toterm2 = perm2.extract(0);
                    f2 += 1;
                }

                if f1 > self.maxflips { self.maxflips = f1 }
                if f2 > self.maxflips { self.maxflips = f2 }
                self.checksum += if pk.odd != 0 { -f1 } else { f1 };
                self.checksum += if pk1.odd != 0 { -f2 } else { f2 };

                k += 2;
            }
            while k < perm_max {
                let pk = &perms[k];
                let mut perm = pk.perm;
                let mut f = 0;
                let mut toterm = pk.start;
                while toterm != 0 {
                    perm = shuffle(perm, self.flip_masks[toterm as usize]);
                    toterm = perm.extract(0);
                    f += 1;
                }
                if f > self.maxflips { self.maxflips = f }
                self.checksum += if pk.odd != 0 { -f } else { f };
                k += 1
            }
            perm_max = 0;
        }
    }
}

fn main() {
    let mut state = State::new();
    state.popmasks();

    let args = env::args().collect::<Vec<_>>();
    if args.len() < 2 {
        println!("usage: {} number", args[0]);
        process::exit(1)
    }
    let max_n = args[1].parse().unwrap();
    if max_n < 3 || max_n > 15 {
        println!("range: must be 3 <= n <= 14");
        process::exit(1);
    }
    for i in 0..max_n { state.s[i] = i as u8 }
    state.tk(max_n);

    println!("{}\nPfannkuchen({}) = {}", state.checksum, max_n, state.maxflips);
}
<|endoftext|>


<commit_before>use rusqlite::Connection;
use log;

#[derive(Debug)]
pub struct Provider {
    id: i32,
    name: String,
}

pub fn table_create_provider(conn: &Connection) -> &Connection {
    conn.execute(
        "CREATE TABLE PROVIDER (
                  id              INTEGER PRIMARY KEY ASC,
                  name            TEXT NOT NULL UNIQUE
                  )",
        &[],
    ).unwrap();
    return conn;
}

pub fn insert_provider(conn: &Connection, name: &String) -> Result<i32, &'static str> {
    let bill = name.clone();
    let me = Provider { id: 0, name: bill };
    let provider_instance = conn.execute(
        "INSERT INTO PROVIDER (name)
                  VALUES (?1)",
        &[&me.name],
    );
    if provider_instance.is_err() {
        return Err("Insert failed");
    }
    provider_instance.unwrap();
    return Ok(0);
}

pub fn list_provider(conn: &Connection) -> Vec<Provider> {
    let mut stmt = conn.prepare("SELECT id, name  FROM PROVIDER").unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        Provider {
            id: row.get(0),
            name: row.get(1),
        }
    });
    let mut items = Vec::<Provider>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn provider_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, name FROM PROVIDER").unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        Provider {
            id: row.get(0),
            name: row.get(1),
        }
    }).unwrap();

    for person in person_iter {
        info!("Found provider {:?}", person.unwrap());
    }
}

pub fn pk_provider_by_name(
    conn: &Connection,
    name: &String,
    pk: &mut i32,
) -> Result<i32, &'static str> {
    let bill = name.clone();
    let mut stmt = conn.prepare("SELECT id, name  FROM PROVIDER WHERE name = ?1")
        .unwrap();
    let provider_iter = stmt.query_map(&[&bill], |row| {
        Provider {
            id: row.get(0),
            name: row.get(1),
        }
    }).unwrap();
    let mut found = 0;
    for person in provider_iter {
        let bill = person.unwrap();
        *pk = bill.id;
        found = bill.id;
    }
    if found != 0 {
        return Ok(found);
    }
    return Err("None found");
}
<commit_msg>Remoive unused 'use'<commit_after>use rusqlite::Connection;

#[derive(Debug)]
pub struct Provider {
    id: i32,
    name: String,
}

pub fn table_create_provider(conn: &Connection) -> &Connection {
    conn.execute(
        "CREATE TABLE PROVIDER (
                  id              INTEGER PRIMARY KEY ASC,
                  name            TEXT NOT NULL UNIQUE
                  )",
        &[],
    ).unwrap();
    return conn;
}

pub fn insert_provider(conn: &Connection, name: &String) -> Result<i32, &'static str> {
    let bill = name.clone();
    let me = Provider { id: 0, name: bill };
    let provider_instance = conn.execute(
        "INSERT INTO PROVIDER (name)
                  VALUES (?1)",
        &[&me.name],
    );
    if provider_instance.is_err() {
        return Err("Insert failed");
    }
    provider_instance.unwrap();
    return Ok(0);
}

pub fn list_provider(conn: &Connection) -> Vec<Provider> {
    let mut stmt = conn.prepare("SELECT id, name  FROM PROVIDER").unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        Provider {
            id: row.get(0),
            name: row.get(1),
        }
    });
    let mut items = Vec::<Provider>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn provider_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, name FROM PROVIDER").unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        Provider {
            id: row.get(0),
            name: row.get(1),
        }
    }).unwrap();

    for person in person_iter {
        info!("Found provider {:?}", person.unwrap());
    }
}

pub fn pk_provider_by_name(
    conn: &Connection,
    name: &String,
    pk: &mut i32,
) -> Result<i32, &'static str> {
    let bill = name.clone();
    let mut stmt = conn.prepare("SELECT id, name  FROM PROVIDER WHERE name = ?1")
        .unwrap();
    let provider_iter = stmt.query_map(&[&bill], |row| {
        Provider {
            id: row.get(0),
            name: row.get(1),
        }
    }).unwrap();
    let mut found = 0;
    for person in provider_iter {
        let bill = person.unwrap();
        *pk = bill.id;
        found = bill.id;
    }
    if found != 0 {
        return Ok(found);
    }
    return Err("None found");
}
<|endoftext|>


<commit_before>use frame::ChannelAssignment;

pub fn decode_left_side(buffer: &mut [i32]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    let left = buffer[i];
    let side = buffer[i + block_size];

    // right channel
    buffer[i + block_size] = left - side;
  }
}

pub fn decode_right_side(buffer: &mut [i32]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    let side  = buffer[i];
    let right = buffer[i + block_size];

    // left channel
    buffer[i] = side + right;
  }
}

pub fn decode_middle_side(buffer: &mut [i32]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    let mut middle = buffer[i];
    let side       = buffer[i + block_size];

    middle = (middle << 1) | (side & 1);

    // left and right channel
    buffer[i]              = (middle + side) >> 1;
    buffer[i + block_size] = (middle - side) >> 1;
  }
}

pub fn decode(channel_assignment: ChannelAssignment, buffer: &mut [i32]) {
  match channel_assignment {
    ChannelAssignment::Independent => return,
    ChannelAssignment::LeftSide    => decode_left_side(buffer),
    ChannelAssignment::RightSide   => decode_right_side(buffer),
    ChannelAssignment::MiddleSide  => decode_middle_side(buffer),
  }
}

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

  #[test]
  fn test_decode_left_side() {
    let mut channels = [ 2, 5, 83, 113, 127, -63, -45, -15
                       , 7, 38, 142, 238, 0, -152, -52, -18
                       ];
    let result       = [-5, -33, -59, -125, 127, 89, 7, 3];

    decode_left_side(&mut channels);

    assert_eq!(&channels[8..16], &result);
  }

  #[test]
  fn test_decode_right_side() {
    let mut channels = [ 7, 38, 142, 238, 0, -152, -52, -18
                       , -5, -33, -59, -125, 127, 89, 7, 3
                       ];
    let result       = [2, 5, 83, 113, 127, -63, -45, -15];

    decode_right_side(&mut channels);

    assert_eq!(&channels[0..8], &result);
  }

  #[test]
  fn test_decode_middle_side() {
    let mut channels = [ -2, -14, 12, -6, 127, 13, -19, -6
                       , 7, 38, 142, 238, 0, -152, -52, -18
                       ];
    let results      = [ 2, 5, 83, 113, 127, -63, -45, -15
                       , -5, -33, -59, -125, 127, 89, 7, 3
                       ];

    decode_middle_side(&mut channels);

    assert_eq!(&channels, &results);
  }

  #[test]
  fn test_decode() {
    let mut channels = [ 2, 5, 83, 113, 127, -63, -45, -15
                       , 7, 38, 142, 238, 0, -152, -52, -18
                       ];

    let results = [ [ 2, 5, 83, 113, 127, -63, -45, -15
                    , 7, 38, 142, 238, 0, -152, -52, -18
                    ],
                    [ 2, 5, 83, 113, 127, -63, -45, -15
                    ,-5, -33, -59, -125, 127, 89, 7, 3
                    ]
                  ];

    decode(ChannelAssignment::Independent, &mut channels);
    assert_eq!(&channels, &results[0]);

    channels = [ 2, 5, 83, 113, 127, -63, -45, -15
               , 7, 38, 142, 238, 0, -152, -52, -18
               ];

    decode(ChannelAssignment::LeftSide, &mut channels);
    assert_eq!(&channels, &results[1]);
  }
}
<commit_msg>Add `RightSide` test for frame decode<commit_after>use frame::ChannelAssignment;

pub fn decode_left_side(buffer: &mut [i32]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    let left = buffer[i];
    let side = buffer[i + block_size];

    // right channel
    buffer[i + block_size] = left - side;
  }
}

pub fn decode_right_side(buffer: &mut [i32]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    let side  = buffer[i];
    let right = buffer[i + block_size];

    // left channel
    buffer[i] = side + right;
  }
}

pub fn decode_middle_side(buffer: &mut [i32]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    let mut middle = buffer[i];
    let side       = buffer[i + block_size];

    middle = (middle << 1) | (side & 1);

    // left and right channel
    buffer[i]              = (middle + side) >> 1;
    buffer[i + block_size] = (middle - side) >> 1;
  }
}

pub fn decode(channel_assignment: ChannelAssignment, buffer: &mut [i32]) {
  match channel_assignment {
    ChannelAssignment::Independent => return,
    ChannelAssignment::LeftSide    => decode_left_side(buffer),
    ChannelAssignment::RightSide   => decode_right_side(buffer),
    ChannelAssignment::MiddleSide  => decode_middle_side(buffer),
  }
}

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

  #[test]
  fn test_decode_left_side() {
    let mut channels = [ 2, 5, 83, 113, 127, -63, -45, -15
                       , 7, 38, 142, 238, 0, -152, -52, -18
                       ];
    let result       = [-5, -33, -59, -125, 127, 89, 7, 3];

    decode_left_side(&mut channels);

    assert_eq!(&channels[8..16], &result);
  }

  #[test]
  fn test_decode_right_side() {
    let mut channels = [ 7, 38, 142, 238, 0, -152, -52, -18
                       , -5, -33, -59, -125, 127, 89, 7, 3
                       ];
    let result       = [2, 5, 83, 113, 127, -63, -45, -15];

    decode_right_side(&mut channels);

    assert_eq!(&channels[0..8], &result);
  }

  #[test]
  fn test_decode_middle_side() {
    let mut channels = [ -2, -14, 12, -6, 127, 13, -19, -6
                       , 7, 38, 142, 238, 0, -152, -52, -18
                       ];
    let results      = [ 2, 5, 83, 113, 127, -63, -45, -15
                       , -5, -33, -59, -125, 127, 89, 7, 3
                       ];

    decode_middle_side(&mut channels);

    assert_eq!(&channels, &results);
  }

  #[test]
  fn test_decode() {
    let mut channels = [ 2, 5, 83, 113, 127, -63, -45, -15
                       , 7, 38, 142, 238, 0, -152, -52, -18
                       ];

    let results = [ [ 2, 5, 83, 113, 127, -63, -45, -15
                    , 7, 38, 142, 238, 0, -152, -52, -18
                    ],
                    [ 2, 5, 83, 113, 127, -63, -45, -15
                    ,-5, -33, -59, -125, 127, 89, 7, 3
                    ]
                  ];

    decode(ChannelAssignment::Independent, &mut channels);
    assert_eq!(&channels, &results[0]);

    channels = [ 2, 5, 83, 113, 127, -63, -45, -15
               , 7, 38, 142, 238, 0, -152, -52, -18
               ];

    decode(ChannelAssignment::LeftSide, &mut channels);
    assert_eq!(&channels, &results[1]);

    channels = [ 7, 38, 142, 238, 0, -152, -52, -18
               , -5, -33, -59, -125, 127, 89, 7, 3
               ];

    decode(ChannelAssignment::RightSide, &mut channels);
    assert_eq!(&channels, &results[1]);
  }
}
<|endoftext|>


<commit_before>use frame::ChannelAssignment;

fn decode_left_side(buffer: &mut [i32]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    let left = buffer[i];
    let side = buffer[i + block_size];

    // right channel
    buffer[i + block_size] = left - side;
  }
}

fn decode_right_side(buffer: &mut [i32]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    let side  = buffer[i];
    let right = buffer[i + block_size];

    // left channel
    buffer[i] = side + right;
  }
}

pub fn decode(channel_assignment: ChannelAssignment, buffer: &mut [i32]) {
  match channel_assignment {
    ChannelAssignment::Independent => return,
    ChannelAssignment::LeftSide    => decode_left_side(buffer),
    ChannelAssignment::RightSide   => unimplemented!(),
    ChannelAssignment::MiddleSide  => unimplemented!(),
  }
}
<commit_msg>Add decode_right_side to `frame::decode`<commit_after>use frame::ChannelAssignment;

fn decode_left_side(buffer: &mut [i32]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    let left = buffer[i];
    let side = buffer[i + block_size];

    // right channel
    buffer[i + block_size] = left - side;
  }
}

fn decode_right_side(buffer: &mut [i32]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    let side  = buffer[i];
    let right = buffer[i + block_size];

    // left channel
    buffer[i] = side + right;
  }
}

pub fn decode(channel_assignment: ChannelAssignment, buffer: &mut [i32]) {
  match channel_assignment {
    ChannelAssignment::Independent => return,
    ChannelAssignment::LeftSide    => decode_left_side(buffer),
    ChannelAssignment::RightSide   => decode_right_side(buffer),
    ChannelAssignment::MiddleSide  => unimplemented!(),
  }
}
<|endoftext|>


<commit_before>extern crate x11 as libx11;
extern crate libc;

use self::libx11::xlib;
use std::ptr::{null, null_mut};
use std::mem::zeroed;

pub struct X11Window<'a> {
    pub width: u32,
    pub height: u32,
    display: &'a mut xlib::Display,
    screen: i32,
    window: xlib::Window,
    visual: &'a mut xlib::Visual,
    gc: xlib::GC,
}

impl<'a> X11Window<'a> {
    pub fn new(width: u32, height: u32) -> Result<X11Window<'a>, String> {
        unsafe {
            let disp = xlib::XOpenDisplay(null());
            if disp == null_mut() {
                return Err(String::from("Can't open display"))
            }
            let scr = xlib::XDefaultScreen(disp);
            let vis = xlib::XDefaultVisual(disp, scr);
            let root_win = xlib::XRootWindow(disp,scr);
            let black = xlib::XBlackPixel(disp, scr);
            let white = xlib::XWhitePixel(disp, scr);
            let win = xlib::XCreateSimpleWindow(
                disp, root_win,
                0, 0, width, height,
                0, black, white
            );

            xlib::XMapWindow(disp, win);

            let event_mask = xlib::StructureNotifyMask;
            xlib::XSelectInput(disp, win, event_mask);
            let mut e: xlib::XEvent = zeroed();

            loop {
                xlib::XNextEvent(disp, &mut e);
                match e.get_type() {
                    xlib::MapNotify => {break;},
                    _ => {},
                }
            }
            let mut gcval: xlib::XGCValues = zeroed();
            let gc = xlib::XCreateGC(disp, win, 0, &mut gcval);

            Ok(X11Window {
                width: width,
                height: height,
                display: &mut *disp,
                screen: scr,
                visual: &mut *vis,
                window: win,
                gc: gc,
            })
        }
    }

    pub fn update(&mut self) {
        unsafe {
            let mut buffer = Image::new(self.display, self.visual, 640, 480);

            for x in 0..640 {
                for y in 0..480 {
                    let pad = 00;
                    let red = (x % 256);
                    let green = (y % 256);
                    let blue = 256 - (x % 256);
                    let color = (pad << 24) + (red << 16) + (green << 8) + blue;
                    xlib::XPutPixel(buffer.ximage, x, y, color as u64);
                };
            };

            self.blit(&mut buffer);

            let mouse_events = xlib::ButtonPressMask | xlib::ButtonReleaseMask;
            xlib::XSelectInput(self.display, self.window, mouse_events);
            let mut e: xlib::XEvent = zeroed();
            loop {
                xlib::XNextEvent(self.display, &mut e);
                match e.get_type() {
                    xlib::ButtonRelease => {break;},
                    _ => {},
                }
            }
        }
    }

    pub fn blit(&mut self, img: &mut Image) {
        unsafe {
            xlib::XPutImage(self.display,
                            self.window,
                            self.gc,
                            img.ximage,
                            0,0,
                            0,0,
                            img.width,
                            img.height,)
        };
    }

    pub fn close(&mut self) {
        unsafe {
            xlib::XDestroyWindow(self.display, self.window);
            xlib::XCloseDisplay(self.display);
        }
    }
}

pub struct Image<'a> {
    ximage: &'a mut xlib::XImage,
    data: Vec<i8>,
    width: u32,
    height: u32,
}

impl<'a> Image<'a> {
    pub fn new(disp: &mut xlib::Display, vis: &mut xlib::Visual, width: u32, height: u32) -> Image<'a> {
        let bitmap_pad: i32 = 32;
        let bytes_per_line: i32 = (width as i32)*bitmap_pad/4;
        let mut data: Vec<i8> = vec![0; (width*height*4) as usize];
        let mut ximg_ref = unsafe {
            let ximg_ptr = xlib::XCreateImage(disp, vis, 24, xlib::ZPixmap, 0,
                                              data.as_mut_ptr(), width, height, bitmap_pad, bytes_per_line);
            xlib::XInitImage(ximg_ptr);
            &mut *ximg_ptr
        };

        Image {
            ximage: ximg_ref,
            data: data,
            width: width,
            height: height,
        }
    }
}
<commit_msg>Removed unnecessary parentheses<commit_after>extern crate x11 as libx11;
extern crate libc;

use self::libx11::xlib;
use std::ptr::{null, null_mut};
use std::mem::zeroed;

pub struct X11Window<'a> {
    pub width: u32,
    pub height: u32,
    display: &'a mut xlib::Display,
    screen: i32,
    window: xlib::Window,
    visual: &'a mut xlib::Visual,
    gc: xlib::GC,
}

impl<'a> X11Window<'a> {
    pub fn new(width: u32, height: u32) -> Result<X11Window<'a>, String> {
        unsafe {
            let disp = xlib::XOpenDisplay(null());
            if disp == null_mut() {
                return Err(String::from("Can't open display"))
            }
            let scr = xlib::XDefaultScreen(disp);
            let vis = xlib::XDefaultVisual(disp, scr);
            let root_win = xlib::XRootWindow(disp,scr);
            let black = xlib::XBlackPixel(disp, scr);
            let white = xlib::XWhitePixel(disp, scr);
            let win = xlib::XCreateSimpleWindow(
                disp, root_win,
                0, 0, width, height,
                0, black, white
            );

            xlib::XMapWindow(disp, win);

            let event_mask = xlib::StructureNotifyMask;
            xlib::XSelectInput(disp, win, event_mask);
            let mut e: xlib::XEvent = zeroed();

            loop {
                xlib::XNextEvent(disp, &mut e);
                match e.get_type() {
                    xlib::MapNotify => {break;},
                    _ => {},
                }
            }
            let mut gcval: xlib::XGCValues = zeroed();
            let gc = xlib::XCreateGC(disp, win, 0, &mut gcval);

            Ok(X11Window {
                width: width,
                height: height,
                display: &mut *disp,
                screen: scr,
                visual: &mut *vis,
                window: win,
                gc: gc,
            })
        }
    }

    pub fn update(&mut self) {
        unsafe {
            let mut buffer = Image::new(self.display, self.visual, 640, 480);

            for x in 0..640 {
                for y in 0..480 {
                    let pad = 00;
                    let red = x % 256;
                    let green = y % 256;
                    let blue = 256 - (x % 256);
                    let color = (pad << 24) + (red << 16) + (green << 8) + blue;
                    xlib::XPutPixel(buffer.ximage, x, y, color as u64);
                };
            };

            self.blit(&mut buffer);

            let mouse_events = xlib::ButtonPressMask | xlib::ButtonReleaseMask;
            xlib::XSelectInput(self.display, self.window, mouse_events);
            let mut e: xlib::XEvent = zeroed();
            loop {
                xlib::XNextEvent(self.display, &mut e);
                match e.get_type() {
                    xlib::ButtonRelease => {break;},
                    _ => {},
                }
            }
        }
    }

    pub fn blit(&mut self, img: &mut Image) {
        unsafe {
            xlib::XPutImage(self.display,
                            self.window,
                            self.gc,
                            img.ximage,
                            0,0,
                            0,0,
                            img.width,
                            img.height,)
        };
    }

    pub fn close(&mut self) {
        unsafe {
            xlib::XDestroyWindow(self.display, self.window);
            xlib::XCloseDisplay(self.display);
        }
    }
}

pub struct Image<'a> {
    ximage: &'a mut xlib::XImage,
    data: Vec<i8>,
    width: u32,
    height: u32,
}

impl<'a> Image<'a> {
    pub fn new(disp: &mut xlib::Display, vis: &mut xlib::Visual, width: u32, height: u32) -> Image<'a> {
        let bitmap_pad: i32 = 32;
        let bytes_per_line: i32 = (width as i32)*bitmap_pad/4;
        let mut data: Vec<i8> = vec![0; (width*height*4) as usize];
        let mut ximg_ref = unsafe {
            let ximg_ptr = xlib::XCreateImage(disp, vis, 24, xlib::ZPixmap, 0,
                                              data.as_mut_ptr(), width, height, bitmap_pad, bytes_per_line);
            xlib::XInitImage(ximg_ptr);
            &mut *ximg_ptr
        };

        Image {
            ximage: ximg_ref,
            data: data,
            width: width,
            height: height,
        }
    }
}
<|endoftext|>