<commit_before>use std::net::SocketAddr;
use std::time::Duration;
use std::thread::{self, JoinHandle};
use hyper::net::HttpListener;
use hyper::server::Server;
use ::Routes;
use hyper_handler::HyperHandler;

pub struct Clockwork {
    _routes: Routes,
    server_threads: usize,
}

impl Clockwork {
    pub fn new(routes: Routes) -> Self {
        Clockwork {
            _routes: routes,
            server_threads: ::num_cpus::get() * 8,
        }
    }

    pub fn server_threads(mut self, value: usize) -> Self {
        self.server_threads = value;
        self
    }

    pub fn http(self, addr: &SocketAddr) -> ClockworkJoinHandle {
        // Start the HTTP servers
        let listener = HttpListener::bind(addr).unwrap();
        let mut handles = Vec::new();
        for _ in 0..self.server_threads {
            let listener = listener.try_clone().unwrap();
            let handle = thread::spawn(move || {
                Self::server_thread(listener);
            });

            handles.push(handle);
        }

        // Return a handle for the caller to wait on
        ClockworkJoinHandle {
            handles: handles
        }
    }

    fn server_thread(listener: HttpListener) {
        let factory = |ctrl| {
            HyperHandler::new(ctrl)
        };

        // Set up the server itself
        let server = Server::new(listener)
            .keep_alive(true)
            .idle_timeout(Duration::from_secs(10))
            .max_sockets(4096);
        let (_listening, server_loop) = server.handle(factory).unwrap();

        // Run the HTTP server loop
        server_loop.run();
    }
}

/// A handle referring to a Clockwork listening server.
pub struct ClockworkJoinHandle {
    handles: Vec<JoinHandle<()>>
}

impl ClockworkJoinHandle {
    pub fn join(self) {
        for handle in self.handles {
            handle.join().unwrap();
        }
    }
}
<commit_msg>Add worker threads<commit_after>use std::net::SocketAddr;
use std::time::Duration;
use std::thread::{self, JoinHandle};
use std::sync::Arc;
use crossbeam::sync::MsQueue;
use hyper::net::HttpListener;
use hyper::server::Server;
use Routes;
use hyper_handler::HyperHandler;

pub struct Clockwork {
    _routes: Routes,
    worker_threads: usize,
    server_threads: usize,
}

impl Clockwork {
    pub fn new(routes: Routes) -> Self {
        let cpus = ::num_cpus::get();
        Clockwork {
            _routes: routes,
            worker_threads: cpus * 8,
            server_threads: cpus * 8,
        }
    }

    pub fn worker_threads(mut self, value: usize) -> Self {
        self.worker_threads = value;
        self
    }

    pub fn server_threads(mut self, value: usize) -> Self {
        self.server_threads = value;
        self
    }

    pub fn http(self, addr: &SocketAddr) -> ClockworkJoinHandle {
        let mut handles = Vec::new();

        // Create the workers
        let queue = Arc::new(MsQueue::new());
        for _ in 0..self.worker_threads {
            let queue = queue.clone();
            let handle = thread::spawn(move || {
                Self::worker_thread(queue);
            });

            handles.push(handle);
        }

        // Start the HTTP servers
        let listener = HttpListener::bind(addr).unwrap();
        for _ in 0..self.server_threads {
            let listener = listener.try_clone().unwrap();
            let handle = thread::spawn(move || {
                Self::server_thread(listener);
            });

            handles.push(handle);
        }

        // Return a handle for the caller to wait on
        ClockworkJoinHandle {
            handles: handles
        }
    }

    fn worker_thread(queue: Arc<MsQueue<WorkerCommand>>) {
        loop {
            let _work = queue.pop();
        }
    }

    fn server_thread(listener: HttpListener) {
        let factory = |ctrl| {
            HyperHandler::new(ctrl)
        };

        // Set up the server itself
        let server = Server::new(listener)
            .keep_alive(true)
            .idle_timeout(Duration::from_secs(10))
            .max_sockets(4096);
        let (_listening, server_loop) = server.handle(factory).unwrap();

        // Run the HTTP server loop
        server_loop.run();
    }
}

/// A handle referring to a Clockwork listening server.
pub struct ClockworkJoinHandle {
    handles: Vec<JoinHandle<()>>
}

impl ClockworkJoinHandle {
    pub fn join(self) {
        for handle in self.handles {
            handle.join().unwrap();
        }
    }
}

enum WorkerCommand {
    Request
}
<|endoftext|>


<commit_before>use std;
use std::io;

use ::as_u16;
use ::as_u32;

use ::errors::Result;
use ::errors::ErrorKind::*;

#[derive(Debug)]
struct Extent {
    block: u32,
    start: u64,
    len: u16,
}

pub struct TreeReader<R> {
    inner: R,
    pos: u64,
    len: u64,
    block_size: u32,
    extents: Vec<Extent>,
}

impl<R> TreeReader<R>
where R: io::Read + io::Seek {
    pub fn new(mut inner: R, block_size: u32, size: u64, core: [u8; ::INODE_CORE_SIZE]) -> Result<TreeReader<R>> {
        let extents = load_extent_tree(&mut inner, core, block_size)?;
        TreeReader::create(inner, block_size, size, extents)
    }

    fn create(inner: R, block_size: u32, size: u64, extents: Vec<Extent>) -> Result<TreeReader<R>> {
        Ok(TreeReader {
            pos: 0,
            len: size,
            inner,
            extents,
            block_size,
        })
    }

    pub fn into_inner(self) -> R {
        self.inner
    }
}

enum FoundBlock<'a> {
    Actual(&'a Extent),
    Sparse(u32),
}

fn find_block(block: u32, extents: &[Extent]) -> FoundBlock {
    for extent in extents {
        if block < extent.block {
            // we've gone past it
            return FoundBlock::Sparse(extent.block - block);
        }

        if block >= extent.block && block < extent.block + extent.len as u32 {
            // we're inside it
            return FoundBlock::Actual(extent);
        }
    }

    FoundBlock::Sparse(std::u32::MAX)
}

impl<R> io::Read for TreeReader<R>
    where R: io::Read + io::Seek {

    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if buf.is_empty() {
            return Ok(0);
        }

        let block_size = self.block_size as u64;

        let wanted_block = (self.pos / block_size) as u32;
        let read_of_this_block = self.pos % block_size;

        match find_block(wanted_block, &self.extents) {
            FoundBlock::Actual(extent) => {
                let bytes_through_extent = (block_size * (wanted_block - extent.block) as u64) + read_of_this_block;
                let remaining_bytes_in_extent = (extent.len as u64 * block_size) - bytes_through_extent;
                let to_read = std::cmp::min(remaining_bytes_in_extent, buf.len() as u64) as usize;
                let to_read = std::cmp::min(to_read as u64, self.len - self.pos) as usize;
                self.inner.seek(io::SeekFrom::Start(extent.start as u64 * block_size + bytes_through_extent))?;
                let read = self.inner.read(&mut buf[0..to_read])?;
                self.pos += read as u64;
                Ok(read)
            }
            FoundBlock::Sparse(max) => {
                let max_bytes = max as u64 * block_size;
                let read = std::cmp::min(max_bytes, buf.len() as u64) as usize;
                let read = std::cmp::min(read as u64, self.len - self.pos) as usize;
                zero(&mut buf[0..read]);
                self.pos += read as u64;
                Ok(read)
            }
        }
    }
}

impl<R> io::Seek for TreeReader<R>
where R: io::Read + io::Seek {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        match pos {
            io::SeekFrom::Start(set) => { self.pos = set }
            io::SeekFrom::Current(diff) => { self.pos = (self.pos as i64 + diff) as u64 }
            io::SeekFrom::End(set) => {
                assert!(set >= 0);
                self.pos = self.len - set as u64
            }
        }

        assert!(self.pos <= self.len);

        Ok(self.pos)
    }
}

fn add_found_extents<R>(
    block_size: u32,
    mut inner: &mut R,
    data: &[u8],
    expected_depth: u16,
    extents: &mut Vec<Extent>) -> Result<()>
where R: io::Read + io::Seek {

    ensure!(0x0a == data[0] && 0xf3 == data[1],
        AssumptionFailed("invalid extent magic".to_string()));

    let extent_entries = as_u16(&data[2..]);
    // 4..: max; doesn't seem to be useful during read
    let depth = as_u16(&data[6..]);
    // 8..: generation, not used in standard ext4

    ensure!(expected_depth == depth,
        AssumptionFailed(format!("depth incorrect: {} != {}", expected_depth, depth)));

    if 0 == depth {
        for en in 0..extent_entries {
            let raw_extent = &data[12 + en as usize * 12..];
            let ee_block = as_u32(raw_extent);
            let ee_len = as_u16(&raw_extent[4..]);
            let ee_start_hi = as_u16(&raw_extent[6..]);
            let ee_start_lo = as_u32(&raw_extent[8..]);
            let ee_start = ee_start_lo as u64 + 0x1000 * ee_start_hi as u64;

            extents.push(Extent {
                block: ee_block,
                start: ee_start,
                len: ee_len,
            });
        }

        return Ok(());
    }

    for en in 0..extent_entries {
        let extent_idx = &data[12 + en as usize * 12..];
        //            let ei_block = as_u32(extent_idx);
        let ei_leaf_lo = as_u32(&extent_idx[4..]);
        let ei_leaf_hi = as_u16(&extent_idx[8..]);
        let ee_leaf: u64 = ei_leaf_lo as u64 + ((ei_leaf_hi as u64) << 32);
        inner.seek(io::SeekFrom::Start(block_size as u64 * ee_leaf))?;
        let mut block = vec![0u8; block_size as usize];
        inner.read_exact(&mut block)?;
        add_found_extents(block_size, inner, &block, depth - 1, extents)?;
    }

    Ok(())
}

fn load_extent_tree<R>(mut inner: R, core: [u8; ::INODE_CORE_SIZE], block_size: u32) -> Result<Vec<Extent>>
    where R: io::Read + io::Seek {
    ensure!(0x0a == core[0] && 0xf3 == core[1],
        AssumptionFailed("invalid extent magic".to_string()));

    let extent_entries = as_u16(&core[2..]);
    // 4..: max; doesn't seem to be useful during read
    let depth = as_u16(&core[6..]);

    ensure!(depth <= 5,
        AssumptionFailed(format!("initial depth too high: {}", depth)));

    let mut extents = Vec::with_capacity(extent_entries as usize + depth as usize * 200);

    add_found_extents(block_size, &mut inner, &core, depth, &mut extents)?;

    extents.sort_by_key(|e| e.block);

    Ok(extents)
}

fn zero(mut buf: &mut [u8]) {
    unsafe {
        std::ptr::write_bytes(buf.as_mut_ptr(), 0u8, buf.len())
    }
}

#[cfg(test)]
mod tests {
    use std::io;
    use std::io::Read;
    use ::extents::TreeReader;
    use ::extents::Extent;

    #[test]
    fn simple_tree() {
        let data = (0..255u8).collect::<Vec<u8>>();
        let size = 4 + 4 * 2;
        let all_bytes = io::Cursor::new(data);
        let mut reader = TreeReader::create(all_bytes, 4, size as u64,
            vec![
                Extent {
                    block: 0,
                    start: 10,
                    len: 1,
                },
                Extent {
                    block: 1,
                    start: 20,
                    len: 2,
                }
            ]
        ).unwrap();

        let mut res = Vec::new();
        assert_eq!(size, reader.read_to_end(&mut res).unwrap());

        assert_eq!(vec![
            40, 41, 42, 43,
            80, 81, 82, 83,
            84, 85, 86, 87,
        ], res);
    }

    #[test]
    fn zero_buf() {
        let mut buf = [7u8; 5];
        assert_eq!(7, buf[0]);
        ::extents::zero(&mut buf);
        for i in &buf {
            assert_eq!(0, *i);
        }
    }
}
<commit_msg>don't use 'block' for the 'block' in an extent<commit_after>use std;
use std::io;

use ::as_u16;
use ::as_u32;

use ::errors::Result;
use ::errors::ErrorKind::*;

#[derive(Debug)]
struct Extent {
    /// The docs call this 'block' (like everything else). I've invented a different name.
    part: u32,
    start: u64,
    len: u16,
}

pub struct TreeReader<R> {
    inner: R,
    pos: u64,
    len: u64,
    block_size: u32,
    extents: Vec<Extent>,
}

impl<R> TreeReader<R>
where R: io::Read + io::Seek {
    pub fn new(mut inner: R, block_size: u32, size: u64, core: [u8; ::INODE_CORE_SIZE]) -> Result<TreeReader<R>> {
        let extents = load_extent_tree(&mut inner, core, block_size)?;
        TreeReader::create(inner, block_size, size, extents)
    }

    fn create(inner: R, block_size: u32, size: u64, extents: Vec<Extent>) -> Result<TreeReader<R>> {
        Ok(TreeReader {
            pos: 0,
            len: size,
            inner,
            extents,
            block_size,
        })
    }

    pub fn into_inner(self) -> R {
        self.inner
    }
}

enum FoundPart<'a> {
    Actual(&'a Extent),
    Sparse(u32),
}

fn find_part(part: u32, extents: &[Extent]) -> FoundPart {
    for extent in extents {
        if part < extent.part {
            // we've gone past it
            return FoundPart::Sparse(extent.part - part);
        }

        if part >= extent.part && part < extent.part + extent.len as u32 {
            // we're inside it
            return FoundPart::Actual(extent);
        }
    }

    FoundPart::Sparse(std::u32::MAX)
}

impl<R> io::Read for TreeReader<R>
    where R: io::Read + io::Seek {

    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if buf.is_empty() {
            return Ok(0);
        }

        let block_size = self.block_size as u64;

        let wanted_block = (self.pos / block_size) as u32;
        let read_of_this_block = self.pos % block_size;

        match find_part(wanted_block, &self.extents) {
            FoundPart::Actual(extent) => {
                let bytes_through_extent = (block_size * (wanted_block - extent.part) as u64) + read_of_this_block;
                let remaining_bytes_in_extent = (extent.len as u64 * block_size) - bytes_through_extent;
                let to_read = std::cmp::min(remaining_bytes_in_extent, buf.len() as u64) as usize;
                let to_read = std::cmp::min(to_read as u64, self.len - self.pos) as usize;
                self.inner.seek(io::SeekFrom::Start(extent.start as u64 * block_size + bytes_through_extent))?;
                let read = self.inner.read(&mut buf[0..to_read])?;
                self.pos += read as u64;
                Ok(read)
            }
            FoundPart::Sparse(max) => {
                let max_bytes = max as u64 * block_size;
                let read = std::cmp::min(max_bytes, buf.len() as u64) as usize;
                let read = std::cmp::min(read as u64, self.len - self.pos) as usize;
                zero(&mut buf[0..read]);
                self.pos += read as u64;
                Ok(read)
            }
        }
    }
}

impl<R> io::Seek for TreeReader<R>
where R: io::Read + io::Seek {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        match pos {
            io::SeekFrom::Start(set) => { self.pos = set }
            io::SeekFrom::Current(diff) => { self.pos = (self.pos as i64 + diff) as u64 }
            io::SeekFrom::End(set) => {
                assert!(set >= 0);
                self.pos = self.len - set as u64
            }
        }

        assert!(self.pos <= self.len);

        Ok(self.pos)
    }
}

fn add_found_extents<R>(
    block_size: u32,
    mut inner: &mut R,
    data: &[u8],
    expected_depth: u16,
    extents: &mut Vec<Extent>) -> Result<()>
where R: io::Read + io::Seek {

    ensure!(0x0a == data[0] && 0xf3 == data[1],
        AssumptionFailed("invalid extent magic".to_string()));

    let extent_entries = as_u16(&data[2..]);
    // 4..: max; doesn't seem to be useful during read
    let depth = as_u16(&data[6..]);
    // 8..: generation, not used in standard ext4

    ensure!(expected_depth == depth,
        AssumptionFailed(format!("depth incorrect: {} != {}", expected_depth, depth)));

    if 0 == depth {
        for en in 0..extent_entries {
            let raw_extent = &data[12 + en as usize * 12..];
            let ee_block = as_u32(raw_extent);
            let ee_len = as_u16(&raw_extent[4..]);
            let ee_start_hi = as_u16(&raw_extent[6..]);
            let ee_start_lo = as_u32(&raw_extent[8..]);
            let ee_start = ee_start_lo as u64 + 0x1000 * ee_start_hi as u64;

            extents.push(Extent {
                part: ee_block,
                start: ee_start,
                len: ee_len,
            });
        }

        return Ok(());
    }

    for en in 0..extent_entries {
        let extent_idx = &data[12 + en as usize * 12..];
        //            let ei_block = as_u32(extent_idx);
        let ei_leaf_lo = as_u32(&extent_idx[4..]);
        let ei_leaf_hi = as_u16(&extent_idx[8..]);
        let ee_leaf: u64 = ei_leaf_lo as u64 + ((ei_leaf_hi as u64) << 32);
        inner.seek(io::SeekFrom::Start(block_size as u64 * ee_leaf))?;
        let mut block = vec![0u8; block_size as usize];
        inner.read_exact(&mut block)?;
        add_found_extents(block_size, inner, &block, depth - 1, extents)?;
    }

    Ok(())
}

fn load_extent_tree<R>(mut inner: R, core: [u8; ::INODE_CORE_SIZE], block_size: u32) -> Result<Vec<Extent>>
    where R: io::Read + io::Seek {
    ensure!(0x0a == core[0] && 0xf3 == core[1],
        AssumptionFailed("invalid extent magic".to_string()));

    let extent_entries = as_u16(&core[2..]);
    // 4..: max; doesn't seem to be useful during read
    let depth = as_u16(&core[6..]);

    ensure!(depth <= 5,
        AssumptionFailed(format!("initial depth too high: {}", depth)));

    let mut extents = Vec::with_capacity(extent_entries as usize + depth as usize * 200);

    add_found_extents(block_size, &mut inner, &core, depth, &mut extents)?;

    extents.sort_by_key(|e| e.part);

    Ok(extents)
}

fn zero(mut buf: &mut [u8]) {
    unsafe {
        std::ptr::write_bytes(buf.as_mut_ptr(), 0u8, buf.len())
    }
}

#[cfg(test)]
mod tests {
    use std::io;
    use std::io::Read;
    use ::extents::TreeReader;
    use ::extents::Extent;

    #[test]
    fn simple_tree() {
        let data = (0..255u8).collect::<Vec<u8>>();
        let size = 4 + 4 * 2;
        let all_bytes = io::Cursor::new(data);
        let mut reader = TreeReader::create(all_bytes, 4, size as u64,
            vec![
                Extent {
                    part: 0,
                    start: 10,
                    len: 1,
                },
                Extent {
                    part: 1,
                    start: 20,
                    len: 2,
                }
            ]
        ).unwrap();

        let mut res = Vec::new();
        assert_eq!(size, reader.read_to_end(&mut res).unwrap());

        assert_eq!(vec![
            40, 41, 42, 43,
            80, 81, 82, 83,
            84, 85, 86, 87,
        ], res);
    }

    #[test]
    fn zero_buf() {
        let mut buf = [7u8; 5];
        assert_eq!(7, buf[0]);
        ::extents::zero(&mut buf);
        for i in &buf {
            assert_eq!(0, *i);
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2020 Fabian Schuiki

//! Lvalue expressions
//!
//! An MIR representation for all expressions that may appear on the left-hand
//! side of an assignment.

use crate::crate_prelude::*;
use crate::{
    mir::{
        rvalue::Rvalue,
        visit::{AcceptVisitor, Visitor, WalkVisitor},
    },
    ty::UnpackedType,
    ParamEnv,
};
use std::collections::HashMap;

/// An lvalue expression.
#[moore_derive::visit_without_foreach]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Lvalue<'a> {
    /// A unique id.
    pub id: NodeId,
    /// The expression node which spawned this lvalue.
    pub origin: NodeId,
    /// The environment within which the lvalue lives.
    pub env: ParamEnv,
    /// The span in the source file where the lvalue originates from.
    pub span: Span,
    /// The type of the expression.
    pub ty: &'a UnpackedType<'a>,
    /// The expression data.
    pub kind: LvalueKind<'a>,
}

impl<'a> Lvalue<'a> {
    /// Check whether the lvalue represents a lowering error tombstone.
    pub fn is_error(&self) -> bool {
        self.ty.is_error() || self.kind.is_error()
    }

    /// Get the `Intf` nested within `Index`, if one exists.
    pub fn get_intf(&self) -> Option<NodeId> {
        match self.kind {
            mir::LvalueKind::Index { value, .. } => value.get_intf(),
            mir::LvalueKind::Intf(intf) => Some(intf),
            _ => None,
        }
    }
}

/// The different forms an lvalue expression may take.
#[moore_derive::visit_without_foreach]
#[derive(Debug, Clone, Eq, PartialEq)]
#[allow(missing_docs)]
pub enum LvalueKind<'a> {
    /// Destructor for an array.
    DestructArray(HashMap<usize, &'a Lvalue<'a>>),
    /// Destructor for a struct.
    DestructStruct(Vec<&'a Lvalue<'a>>),
    /// A reference to a genvar declaration.
    Genvar(NodeId),
    /// A reference to a variable declaration.
    Var(NodeId),
    /// A reference to a port declaration.
    Port(NodeId),
    /// A reference to an interface.
    Intf(NodeId),
    /// A reference to an interface's signal.
    IntfSignal(&'a Lvalue<'a>, NodeId),
    /// A bit- or part-select.
    Index {
        value: &'a Lvalue<'a>,
        base: &'a Rvalue<'a>,
        length: usize,
    },
    /// A struct field access.
    Member { value: &'a Lvalue<'a>, field: usize },
    /// Concatenate multiple values.
    ///
    /// The values are cast to and treated as packed bit vectors, and the result
    /// is yet another packed bit vector.
    Concat(Vec<&'a Lvalue<'a>>),
    /// Repeat a value multiple times.
    ///
    /// The value is cast to and treated as a packed bit vector, and the result
    /// is yet another packed bit vector.
    Repeat(usize, &'a Lvalue<'a>),
    /// An error occurred during lowering.
    Error,
}

impl<'a> LvalueKind<'a> {
    /// Check whether the lvalue represents a lowering error tombstone.
    pub fn is_error(&self) -> bool {
        match self {
            LvalueKind::Error => true,
            _ => false,
        }
    }
}
<commit_msg>mir: Drop HashMap from DestructArray lvalue<commit_after>// Copyright (c) 2016-2020 Fabian Schuiki

//! Lvalue expressions
//!
//! An MIR representation for all expressions that may appear on the left-hand
//! side of an assignment.

use crate::crate_prelude::*;
use crate::{
    mir::{
        rvalue::Rvalue,
        visit::{AcceptVisitor, Visitor, WalkVisitor},
    },
    ty::UnpackedType,
    ParamEnv,
};

/// An lvalue expression.
#[moore_derive::visit_without_foreach]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Lvalue<'a> {
    /// A unique id.
    pub id: NodeId,
    /// The expression node which spawned this lvalue.
    pub origin: NodeId,
    /// The environment within which the lvalue lives.
    pub env: ParamEnv,
    /// The span in the source file where the lvalue originates from.
    pub span: Span,
    /// The type of the expression.
    pub ty: &'a UnpackedType<'a>,
    /// The expression data.
    pub kind: LvalueKind<'a>,
}

impl<'a> Lvalue<'a> {
    /// Check whether the lvalue represents a lowering error tombstone.
    pub fn is_error(&self) -> bool {
        self.ty.is_error() || self.kind.is_error()
    }

    /// Get the `Intf` nested within `Index`, if one exists.
    pub fn get_intf(&self) -> Option<NodeId> {
        match self.kind {
            mir::LvalueKind::Index { value, .. } => value.get_intf(),
            mir::LvalueKind::Intf(intf) => Some(intf),
            _ => None,
        }
    }
}

/// The different forms an lvalue expression may take.
#[moore_derive::visit_without_foreach]
#[derive(Debug, Clone, Eq, PartialEq)]
#[allow(missing_docs)]
pub enum LvalueKind<'a> {
    /// Destructor for an array.
    DestructArray(Vec<&'a Lvalue<'a>>),
    /// Destructor for a struct.
    DestructStruct(Vec<&'a Lvalue<'a>>),
    /// A reference to a genvar declaration.
    Genvar(NodeId),
    /// A reference to a variable declaration.
    Var(NodeId),
    /// A reference to a port declaration.
    Port(NodeId),
    /// A reference to an interface.
    Intf(NodeId),
    /// A reference to an interface's signal.
    IntfSignal(&'a Lvalue<'a>, NodeId),
    /// A bit- or part-select.
    Index {
        value: &'a Lvalue<'a>,
        base: &'a Rvalue<'a>,
        length: usize,
    },
    /// A struct field access.
    Member { value: &'a Lvalue<'a>, field: usize },
    /// Concatenate multiple values.
    ///
    /// The values are cast to and treated as packed bit vectors, and the result
    /// is yet another packed bit vector.
    Concat(Vec<&'a Lvalue<'a>>),
    /// Repeat a value multiple times.
    ///
    /// The value is cast to and treated as a packed bit vector, and the result
    /// is yet another packed bit vector.
    Repeat(usize, &'a Lvalue<'a>),
    /// An error occurred during lowering.
    Error,
}

impl<'a> LvalueKind<'a> {
    /// Check whether the lvalue represents a lowering error tombstone.
    pub fn is_error(&self) -> bool {
        match self {
            LvalueKind::Error => true,
            _ => false,
        }
    }
}
<|endoftext|>


<commit_before>use crate::{BeaconChain, BeaconChainTypes};
use eth2_hashing::hash;
use lighthouse_bootstrap::Bootstrapper;
use merkle_proof::MerkleTree;
use rayon::prelude::*;
use slog::Logger;
use ssz::Encode;
use state_processing::initialize_beacon_state_from_eth1;
use std::fs::File;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::SystemTime;
use tree_hash::{SignedRoot, TreeHash};
use types::{
    test_utils::generate_deterministic_keypairs, BeaconBlock, BeaconState, ChainSpec, Deposit,
    DepositData, Domain, EthSpec, Fork, Hash256, PublicKey, Signature,
};

enum BuildStrategy<T: BeaconChainTypes> {
    FromGenesis {
        genesis_state: Box<BeaconState<T::EthSpec>>,
        genesis_block: Box<BeaconBlock<T::EthSpec>>,
    },
    LoadFromStore,
}

pub struct BeaconChainBuilder<T: BeaconChainTypes> {
    build_strategy: BuildStrategy<T>,
    spec: ChainSpec,
    log: Logger,
}

impl<T: BeaconChainTypes> BeaconChainBuilder<T> {
    pub fn recent_genesis(
        validator_count: usize,
        minutes: u64,
        spec: ChainSpec,
        log: Logger,
    ) -> Result<Self, String> {
        Self::quick_start(recent_genesis_time(minutes), validator_count, spec, log)
    }

    pub fn quick_start(
        genesis_time: u64,
        validator_count: usize,
        spec: ChainSpec,
        log: Logger,
    ) -> Result<Self, String> {
        let genesis_state = interop_genesis_state(validator_count, genesis_time, &spec)?;

        Ok(Self::from_genesis_state(genesis_state, spec, log))
    }

    pub fn yaml_state(file: &PathBuf, spec: ChainSpec, log: Logger) -> Result<Self, String> {
        let file = File::open(file.clone())
            .map_err(|e| format!("Unable to open YAML genesis state file {:?}: {:?}", file, e))?;

        let genesis_state = serde_yaml::from_reader(file)
            .map_err(|e| format!("Unable to parse YAML genesis state file: {:?}", e))?;

        Ok(Self::from_genesis_state(genesis_state, spec, log))
    }

    pub fn http_bootstrap(server: &str, spec: ChainSpec, log: Logger) -> Result<Self, String> {
        let bootstrapper = Bootstrapper::from_server_string(server.to_string())
            .map_err(|e| format!("Failed to initialize bootstrap client: {}", e))?;

        let (genesis_state, genesis_block) = bootstrapper
            .genesis()
            .map_err(|e| format!("Failed to bootstrap genesis state: {}", e))?;

        Ok(Self {
            build_strategy: BuildStrategy::FromGenesis {
                genesis_block: Box::new(genesis_block),
                genesis_state: Box::new(genesis_state),
            },
            spec,
            log,
        })
    }

    fn from_genesis_state(
        genesis_state: BeaconState<T::EthSpec>,
        spec: ChainSpec,
        log: Logger,
    ) -> Self {
        Self {
            build_strategy: BuildStrategy::FromGenesis {
                genesis_block: Box::new(genesis_block(&genesis_state, &spec)),
                genesis_state: Box::new(genesis_state),
            },
            spec,
            log,
        }
    }

    pub fn from_store(spec: ChainSpec, log: Logger) -> Self {
        Self {
            build_strategy: BuildStrategy::LoadFromStore,
            spec,
            log,
        }
    }

    pub fn build(self, store: Arc<T::Store>) -> Result<BeaconChain<T>, String> {
        Ok(match self.build_strategy {
            BuildStrategy::LoadFromStore => BeaconChain::from_store(store, self.spec, self.log)
                .map_err(|e| format!("Error loading BeaconChain from database: {:?}", e))?
                .ok_or_else(|| format!("Unable to find exising BeaconChain in database."))?,
            BuildStrategy::FromGenesis {
                genesis_block,
                genesis_state,
            } => BeaconChain::from_genesis(
                store,
                genesis_state.as_ref().clone(),
                genesis_block.as_ref().clone(),
                self.spec,
                self.log,
            )
            .map_err(|e| format!("Failed to initialize new beacon chain: {:?}", e))?,
        })
    }
}

fn genesis_block<T: EthSpec>(genesis_state: &BeaconState<T>, spec: &ChainSpec) -> BeaconBlock<T> {
    let mut genesis_block = BeaconBlock::empty(&spec);

    genesis_block.state_root = genesis_state.canonical_root();

    genesis_block
}

/// Builds a genesis state as defined by the Eth2 interop procedure (see below).
///
/// Reference:
/// https://github.com/ethereum/eth2.0-pm/tree/6e41fcf383ebeb5125938850d8e9b4e9888389b4/interop/mocked_start
fn interop_genesis_state<T: EthSpec>(
    validator_count: usize,
    genesis_time: u64,
    spec: &ChainSpec,
) -> Result<BeaconState<T>, String> {
    let keypairs = generate_deterministic_keypairs(validator_count);
    let eth1_block_hash = Hash256::from_slice(&[42; 32]);
    let eth1_timestamp = 2_u64.pow(40);
    let amount = spec.max_effective_balance;
    dbg!(amount);

    let withdrawal_credentials = |pubkey: &PublicKey| {
        let mut credentials = hash(&pubkey.as_ssz_bytes());
        credentials[0] = spec.bls_withdrawal_prefix_byte;
        Hash256::from_slice(&credentials)
    };

    let datas = keypairs
        .into_par_iter()
        .map(|keypair| {
            let mut data = DepositData {
                withdrawal_credentials: withdrawal_credentials(&keypair.pk),
                pubkey: keypair.pk.into(),
                amount,
                signature: Signature::empty_signature().into(),
            };

            let domain = spec.get_domain(
                spec.genesis_slot.epoch(T::slots_per_epoch()),
                Domain::Deposit,
                &Fork::default(),
            );
            data.signature = Signature::new(&data.signed_root()[..], domain, &keypair.sk).into();

            data
        })
        .collect::<Vec<_>>();

    let deposit_root_leaves = datas
        .par_iter()
        .map(|data| Hash256::from_slice(&data.tree_hash_root()))
        .collect::<Vec<_>>();

    let mut proofs = vec![];
    for i in 1..=deposit_root_leaves.len() {
        // Note: this implementation is not so efficient.
        //
        // If `MerkleTree` had a push method, we could just build one tree and sample it instead of
        // rebuilding the tree for each deposit.
        let tree = MerkleTree::create(
            &deposit_root_leaves[0..i],
            spec.deposit_contract_tree_depth as usize,
        );

        let (_, mut proof) = tree.generate_proof(i - 1, spec.deposit_contract_tree_depth as usize);
        proof.push(Hash256::from_slice(&int_to_bytes32(i)));

        assert_eq!(
            proof.len(),
            spec.deposit_contract_tree_depth as usize + 1,
            "Deposit proof should be correct len"
        );

        proofs.push(proof);
    }

    let deposits = datas
        .into_par_iter()
        .zip(proofs.into_par_iter())
        .map(|(data, proof)| (data, proof.into()))
        .map(|(data, proof)| Deposit { proof, data })
        .collect::<Vec<_>>();

    let mut state =
        initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits, spec)
            .map_err(|e| format!("Unable to initialize genesis state: {:?}", e))?;

    state.genesis_time = genesis_time;

    Ok(state)
}

/// Returns `int` as little-endian bytes with a length of 32.
fn int_to_bytes32(int: usize) -> Vec<u8> {
    let mut vec = int.to_le_bytes().to_vec();
    vec.resize(32, 0);
    vec
}

/// Returns the system time, mod 30 minutes.
///
/// Used for easily creating testnets.
fn recent_genesis_time(minutes: u64) -> u64 {
    let now = SystemTime::now()
        .duration_since(SystemTime::UNIX_EPOCH)
        .unwrap()
        .as_secs();
    let secs_after_last_period = now.checked_rem(minutes * 60).unwrap_or(0);
    now - secs_after_last_period
}

#[cfg(test)]
mod test {
    use super::*;
    use types::{EthSpec, MinimalEthSpec};

    type TestEthSpec = MinimalEthSpec;

    #[test]
    fn interop_state() {
        let validator_count = 16;
        let genesis_time = 42;
        let spec = &TestEthSpec::default_spec();

        let state = interop_genesis_state::<TestEthSpec>(validator_count, genesis_time, spec)
            .expect("should build state");

        assert_eq!(
            state.eth1_data.block_hash,
            Hash256::from_slice(&[42; 32]),
            "eth1 block hash should be co-ordinated junk"
        );

        assert_eq!(
            state.genesis_time, genesis_time,
            "genesis time should be as specified"
        );

        for b in &state.balances {
            assert_eq!(
                *b, spec.max_effective_balance,
                "validator balances should be max effective balance"
            );
        }

        for v in &state.validators {
            let creds = v.withdrawal_credentials.as_bytes();
            assert_eq!(
                creds[0], spec.bls_withdrawal_prefix_byte,
                "first byte of withdrawal creds should be bls prefix"
            );
            assert_eq!(
                &creds[1..],
                &hash(&v.pubkey.as_ssz_bytes())[1..],
                "rest of withdrawal creds should be pubkey hash"
            )
        }

        assert_eq!(
            state.balances.len(),
            validator_count,
            "validator balances len should be correct"
        );

        assert_eq!(
            state.validators.len(),
            validator_count,
            "validator count should be correct"
        );
    }
}
<commit_msg>Remove stray dbg!<commit_after>use crate::{BeaconChain, BeaconChainTypes};
use eth2_hashing::hash;
use lighthouse_bootstrap::Bootstrapper;
use merkle_proof::MerkleTree;
use rayon::prelude::*;
use slog::Logger;
use ssz::Encode;
use state_processing::initialize_beacon_state_from_eth1;
use std::fs::File;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::SystemTime;
use tree_hash::{SignedRoot, TreeHash};
use types::{
    test_utils::generate_deterministic_keypairs, BeaconBlock, BeaconState, ChainSpec, Deposit,
    DepositData, Domain, EthSpec, Fork, Hash256, PublicKey, Signature,
};

enum BuildStrategy<T: BeaconChainTypes> {
    FromGenesis {
        genesis_state: Box<BeaconState<T::EthSpec>>,
        genesis_block: Box<BeaconBlock<T::EthSpec>>,
    },
    LoadFromStore,
}

pub struct BeaconChainBuilder<T: BeaconChainTypes> {
    build_strategy: BuildStrategy<T>,
    spec: ChainSpec,
    log: Logger,
}

impl<T: BeaconChainTypes> BeaconChainBuilder<T> {
    pub fn recent_genesis(
        validator_count: usize,
        minutes: u64,
        spec: ChainSpec,
        log: Logger,
    ) -> Result<Self, String> {
        Self::quick_start(recent_genesis_time(minutes), validator_count, spec, log)
    }

    pub fn quick_start(
        genesis_time: u64,
        validator_count: usize,
        spec: ChainSpec,
        log: Logger,
    ) -> Result<Self, String> {
        let genesis_state = interop_genesis_state(validator_count, genesis_time, &spec)?;

        Ok(Self::from_genesis_state(genesis_state, spec, log))
    }

    pub fn yaml_state(file: &PathBuf, spec: ChainSpec, log: Logger) -> Result<Self, String> {
        let file = File::open(file.clone())
            .map_err(|e| format!("Unable to open YAML genesis state file {:?}: {:?}", file, e))?;

        let genesis_state = serde_yaml::from_reader(file)
            .map_err(|e| format!("Unable to parse YAML genesis state file: {:?}", e))?;

        Ok(Self::from_genesis_state(genesis_state, spec, log))
    }

    pub fn http_bootstrap(server: &str, spec: ChainSpec, log: Logger) -> Result<Self, String> {
        let bootstrapper = Bootstrapper::from_server_string(server.to_string())
            .map_err(|e| format!("Failed to initialize bootstrap client: {}", e))?;

        let (genesis_state, genesis_block) = bootstrapper
            .genesis()
            .map_err(|e| format!("Failed to bootstrap genesis state: {}", e))?;

        Ok(Self {
            build_strategy: BuildStrategy::FromGenesis {
                genesis_block: Box::new(genesis_block),
                genesis_state: Box::new(genesis_state),
            },
            spec,
            log,
        })
    }

    fn from_genesis_state(
        genesis_state: BeaconState<T::EthSpec>,
        spec: ChainSpec,
        log: Logger,
    ) -> Self {
        Self {
            build_strategy: BuildStrategy::FromGenesis {
                genesis_block: Box::new(genesis_block(&genesis_state, &spec)),
                genesis_state: Box::new(genesis_state),
            },
            spec,
            log,
        }
    }

    pub fn from_store(spec: ChainSpec, log: Logger) -> Self {
        Self {
            build_strategy: BuildStrategy::LoadFromStore,
            spec,
            log,
        }
    }

    pub fn build(self, store: Arc<T::Store>) -> Result<BeaconChain<T>, String> {
        Ok(match self.build_strategy {
            BuildStrategy::LoadFromStore => BeaconChain::from_store(store, self.spec, self.log)
                .map_err(|e| format!("Error loading BeaconChain from database: {:?}", e))?
                .ok_or_else(|| format!("Unable to find exising BeaconChain in database."))?,
            BuildStrategy::FromGenesis {
                genesis_block,
                genesis_state,
            } => BeaconChain::from_genesis(
                store,
                genesis_state.as_ref().clone(),
                genesis_block.as_ref().clone(),
                self.spec,
                self.log,
            )
            .map_err(|e| format!("Failed to initialize new beacon chain: {:?}", e))?,
        })
    }
}

fn genesis_block<T: EthSpec>(genesis_state: &BeaconState<T>, spec: &ChainSpec) -> BeaconBlock<T> {
    let mut genesis_block = BeaconBlock::empty(&spec);

    genesis_block.state_root = genesis_state.canonical_root();

    genesis_block
}

/// Builds a genesis state as defined by the Eth2 interop procedure (see below).
///
/// Reference:
/// https://github.com/ethereum/eth2.0-pm/tree/6e41fcf383ebeb5125938850d8e9b4e9888389b4/interop/mocked_start
fn interop_genesis_state<T: EthSpec>(
    validator_count: usize,
    genesis_time: u64,
    spec: &ChainSpec,
) -> Result<BeaconState<T>, String> {
    let keypairs = generate_deterministic_keypairs(validator_count);
    let eth1_block_hash = Hash256::from_slice(&[42; 32]);
    let eth1_timestamp = 2_u64.pow(40);
    let amount = spec.max_effective_balance;

    let withdrawal_credentials = |pubkey: &PublicKey| {
        let mut credentials = hash(&pubkey.as_ssz_bytes());
        credentials[0] = spec.bls_withdrawal_prefix_byte;
        Hash256::from_slice(&credentials)
    };

    let datas = keypairs
        .into_par_iter()
        .map(|keypair| {
            let mut data = DepositData {
                withdrawal_credentials: withdrawal_credentials(&keypair.pk),
                pubkey: keypair.pk.into(),
                amount,
                signature: Signature::empty_signature().into(),
            };

            let domain = spec.get_domain(
                spec.genesis_slot.epoch(T::slots_per_epoch()),
                Domain::Deposit,
                &Fork::default(),
            );
            data.signature = Signature::new(&data.signed_root()[..], domain, &keypair.sk).into();

            data
        })
        .collect::<Vec<_>>();

    let deposit_root_leaves = datas
        .par_iter()
        .map(|data| Hash256::from_slice(&data.tree_hash_root()))
        .collect::<Vec<_>>();

    let mut proofs = vec![];
    for i in 1..=deposit_root_leaves.len() {
        // Note: this implementation is not so efficient.
        //
        // If `MerkleTree` had a push method, we could just build one tree and sample it instead of
        // rebuilding the tree for each deposit.
        let tree = MerkleTree::create(
            &deposit_root_leaves[0..i],
            spec.deposit_contract_tree_depth as usize,
        );

        let (_, mut proof) = tree.generate_proof(i - 1, spec.deposit_contract_tree_depth as usize);
        proof.push(Hash256::from_slice(&int_to_bytes32(i)));

        assert_eq!(
            proof.len(),
            spec.deposit_contract_tree_depth as usize + 1,
            "Deposit proof should be correct len"
        );

        proofs.push(proof);
    }

    let deposits = datas
        .into_par_iter()
        .zip(proofs.into_par_iter())
        .map(|(data, proof)| (data, proof.into()))
        .map(|(data, proof)| Deposit { proof, data })
        .collect::<Vec<_>>();

    let mut state =
        initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits, spec)
            .map_err(|e| format!("Unable to initialize genesis state: {:?}", e))?;

    state.genesis_time = genesis_time;

    Ok(state)
}

/// Returns `int` as little-endian bytes with a length of 32.
fn int_to_bytes32(int: usize) -> Vec<u8> {
    let mut vec = int.to_le_bytes().to_vec();
    vec.resize(32, 0);
    vec
}

/// Returns the system time, mod 30 minutes.
///
/// Used for easily creating testnets.
fn recent_genesis_time(minutes: u64) -> u64 {
    let now = SystemTime::now()
        .duration_since(SystemTime::UNIX_EPOCH)
        .unwrap()
        .as_secs();
    let secs_after_last_period = now.checked_rem(minutes * 60).unwrap_or(0);
    now - secs_after_last_period
}

#[cfg(test)]
mod test {
    use super::*;
    use types::{EthSpec, MinimalEthSpec};

    type TestEthSpec = MinimalEthSpec;

    #[test]
    fn interop_state() {
        let validator_count = 16;
        let genesis_time = 42;
        let spec = &TestEthSpec::default_spec();

        let state = interop_genesis_state::<TestEthSpec>(validator_count, genesis_time, spec)
            .expect("should build state");

        assert_eq!(
            state.eth1_data.block_hash,
            Hash256::from_slice(&[42; 32]),
            "eth1 block hash should be co-ordinated junk"
        );

        assert_eq!(
            state.genesis_time, genesis_time,
            "genesis time should be as specified"
        );

        for b in &state.balances {
            assert_eq!(
                *b, spec.max_effective_balance,
                "validator balances should be max effective balance"
            );
        }

        for v in &state.validators {
            let creds = v.withdrawal_credentials.as_bytes();
            assert_eq!(
                creds[0], spec.bls_withdrawal_prefix_byte,
                "first byte of withdrawal creds should be bls prefix"
            );
            assert_eq!(
                &creds[1..],
                &hash(&v.pubkey.as_ssz_bytes())[1..],
                "rest of withdrawal creds should be pubkey hash"
            )
        }

        assert_eq!(
            state.balances.len(),
            validator_count,
            "validator balances len should be correct"
        );

        assert_eq!(
            state.validators.len(),
            validator_count,
            "validator count should be correct"
        );
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]

#[plugin]
extern crate glium_macros;

extern crate glutin;
extern crate glium;

use glium::Surface;

mod teapot_model;

fn main() {
    use glium::DisplayBuild;

    // building the display, ie. the main object
    let display = glutin::WindowBuilder::new()
        .build_glium()
        .unwrap();

    // building the vertex and index buffers
    let (vertex_buffer, index_buffer) = match teapot_model::build_model() {
        (vertices, indices) => (
            glium::VertexBuffer::new(&display, vertices),
            glium::IndexBuffer::new(&display, indices)
        )
    };

    // the program
    let program = glium::Program::from_source(&display,
        // vertex shader
        "
            #version 110

            uniform mat4 matrix;

            attribute vec3 position;
            attribute vec3 normal;
            varying vec3 v_position;
            varying vec3 v_normal;

            void main() {
                v_position = position;
                v_normal = normal;
                gl_Position = vec4(v_position, 1.0) * matrix;
            }
        ",

        // fragment shader
        "
            #version 330

            in vec3 v_normal;

            const vec3 LIGHT = vec3(-0.2, 0.8, 0.1);

            void main() {
                float lum = max(dot(v_normal, normalize(LIGHT)), 0.0);
                vec3 color = (0.3 + 0.7 * lum) * vec3(1.0, 1.0, 1.0);
                gl_FragColor = vec4(color, 1.0);
            }
        ",

        // geometry shader
        None)
        .unwrap();

    // creating the uniforms structure
    #[uniforms]
    #[derive(Copy)]
    struct Uniforms {
        matrix: [[f32; 4]; 4],
    }

    // the main loop
    // each cycle will draw once
    'main: loop {
        use std::io::timer;
        use std::time::Duration;

        // building the uniforms
        let uniforms = Uniforms {
            matrix: [
                [0.05, 0.0, 0.0, 0.0],
                [0.0, 0.05, 0.0, 0.0],
                [0.0, 0.0, 0.05, 0.0],
                [0.0, 0.0, 0.0, 1.0f32]
            ]
        };

        // draw parameters
        let params = glium::DrawParameters {
            //depth_function: glium::DepthFunction::IfLess,
            .. std::default::Default::default()
        };

        // drawing a frame
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 0.0, 0.0);
        target.draw(&vertex_buffer, &index_buffer, &program, &uniforms, &params);
        target.finish();

        // sleeping for some time in order not to use up too much CPU
        timer::sleep(Duration::milliseconds(17));

        // polling and handling the events received by the window
        for event in display.poll_events().into_iter() {
            match event {
                glutin::Event::Closed => break 'main,
                _ => ()
            }
        }
    }
}
<commit_msg>Fix shader version in the teapot example<commit_after>#![feature(plugin)]

#[plugin]
extern crate glium_macros;

extern crate glutin;
extern crate glium;

use glium::Surface;

mod teapot_model;

fn main() {
    use glium::DisplayBuild;

    // building the display, ie. the main object
    let display = glutin::WindowBuilder::new()
        .build_glium()
        .unwrap();

    // building the vertex and index buffers
    let (vertex_buffer, index_buffer) = match teapot_model::build_model() {
        (vertices, indices) => (
            glium::VertexBuffer::new(&display, vertices),
            glium::IndexBuffer::new(&display, indices)
        )
    };

    // the program
    let program = glium::Program::from_source(&display,
        // vertex shader
        "
            #version 110

            uniform mat4 matrix;

            attribute vec3 position;
            attribute vec3 normal;
            varying vec3 v_position;
            varying vec3 v_normal;

            void main() {
                v_position = position;
                v_normal = normal;
                gl_Position = vec4(v_position, 1.0) * matrix;
            }
        ",

        // fragment shader
        "
            #version 110

            varying vec3 v_normal;

            const vec3 LIGHT = vec3(-0.2, 0.8, 0.1);

            void main() {
                float lum = max(dot(v_normal, normalize(LIGHT)), 0.0);
                vec3 color = (0.3 + 0.7 * lum) * vec3(1.0, 1.0, 1.0);
                gl_FragColor = vec4(color, 1.0);
            }
        ",

        // geometry shader
        None)
        .unwrap();

    // creating the uniforms structure
    #[uniforms]
    #[derive(Copy)]
    struct Uniforms {
        matrix: [[f32; 4]; 4],
    }

    // the main loop
    // each cycle will draw once
    'main: loop {
        use std::io::timer;
        use std::time::Duration;

        // building the uniforms
        let uniforms = Uniforms {
            matrix: [
                [0.05, 0.0, 0.0, 0.0],
                [0.0, 0.05, 0.0, 0.0],
                [0.0, 0.0, 0.05, 0.0],
                [0.0, 0.0, 0.0, 1.0f32]
            ]
        };

        // draw parameters
        let params = glium::DrawParameters {
            //depth_function: glium::DepthFunction::IfLess,
            .. std::default::Default::default()
        };

        // drawing a frame
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 0.0, 0.0);
        target.draw(&vertex_buffer, &index_buffer, &program, &uniforms, &params);
        target.finish();

        // sleeping for some time in order not to use up too much CPU
        timer::sleep(Duration::milliseconds(17));

        // polling and handling the events received by the window
        for event in display.poll_events().into_iter() {
            match event {
                glutin::Event::Closed => break 'main,
                _ => ()
            }
        }
    }
}
<|endoftext|>


<commit_before>use defs;
use defs::Word;
use term::lterm::LTerm;
use term::primary;

use num;

/// Represents raw layout of bignum digits in memory.
/// TODO: Operate without copying.
pub struct BignumPtr {
  p: *mut Word,
}

fn module() -> &'static str { "raw::rbignum: " }

impl BignumPtr {
  /// How many words of heap we need to store the bignum.
  #[inline]
  pub fn storage_size(big: &num::BigInt) -> Word {
    (big.bits() + (defs::WORD_BITS - 1) / defs::WORD_BITS)
  }

  /// Given a pointer initialize a boxed value header here, hence unsafe.
  /// Return a `RawBignum` wrapper.
  pub unsafe fn create_at(p: *mut Word, big: &num::BigInt) -> BignumPtr {
    let storage_sz = BignumPtr::storage_size(big);
    match big.sign() {
      num::bigint::Sign::Minus =>
        *p = primary::header::make_bignum_neg_header_raw(storage_sz),
      num::bigint::Sign::Plus =>
        *p = primary::header::make_bignum_pos_header_raw(storage_sz),
      _ => panic!("{}create_at - no sign", module())
    }
    BignumPtr { p }
  }

  /// Given a pointer to an already initialized tuple, just return a wrapper.
//  pub fn from_pointer(p: *mut Word, arity: Word) -> RawBignum {
//    RawBignum { p }
//  }

//  pub unsafe fn arity(&self) -> Word {
//    primary::get_value(*self.p)
//  }

//  /// Zero-based set element function
//  pub unsafe fn set_element_base0(&self, i: Word, val: LTerm) {
//    assert!(i < self.arity());
//    *self.p.offset(i as isize + 1) = val.raw()
//  }

//  pub unsafe fn get_element(&self, i: Word) -> LTerm {
//    LTerm::from_raw(*self.p.offset(i as isize + 1))
//  }

  /// Box the `self.p` pointer into `LTerm`.
  pub fn make_bignum(&self) -> LTerm { LTerm::make_box(self.p) }
}
<commit_msg>Remove unused module<commit_after><|endoftext|>


<commit_before>use std::collections::HashMap;

use parser::ast::{Function, Expr, Statement};
use math::rich_number::{Unit, RichNumber};
use math::conversion_table::ConversionTable;

use eval::fixity::Fixity;
use eval::context_item::ContextItem;
use eval::built_in_function::BuiltInFunction;
use eval::eval_tree_node::EvalTreeNode;

use eval::defaults as default_functions;

use prelude::setup_prelude;

#[derive(PartialEq, Debug)]
pub enum EvalError {
    UndefinedSymbol(String),
    UnexpectedSymbols,
    ExpectedParams(usize),
    InvalidSymbolDefinition {
        expected_params: usize,
        actual_params: usize,
    },
    ConversionUndefined {
        start: Unit,
        target: Unit,
    },
    InvalidParams(String),
}

pub type EvalResult = Result<ContextItem, EvalError>;

pub struct EvalContext {
    // Symbol name to context item definition
    symbol_table: HashMap<String, ContextItem>,
    // Unit to Symbol name
    units: HashMap<Unit, String>,
    // Used to define new units
    next_unit: Unit,
    conversion_table: ConversionTable,
}

impl EvalContext {
    pub fn new() -> EvalContext {
        EvalContext {
            symbol_table: HashMap::new(),
            units: HashMap::new(),
            next_unit: 1,
            conversion_table: ConversionTable::new(),
        }
    }

    /// Defines a reasonble set of default built_in methods
    pub fn defaults() -> EvalContext {
        let mut context = EvalContext::new();

        context.set_constant("PREFIX", Fixity::Prefix.to_string());
        context.set_constant("INFIX", Fixity::Infix.to_string());
        context.set_constant("POSTFIX", Fixity::Postfix.to_string());

        context.define_built_in_method_defaults(
            "operator",
            4,
            BuiltInFunction::new(default_functions::operator),
        );

        context.define_built_in_method_defaults(
            "defineUnit",
            1,
            BuiltInFunction::new(default_functions::define_unit),
        );

        context.define_built_in_method_defaults(
            "convert",
            2,
            BuiltInFunction::new(default_functions::convert),
        );

        context.define_built_in_method_defaults(
            "unitFor",
            1,
            BuiltInFunction::new(default_functions::unit_for),
        );

        context.define_built_in_method_defaults(
            "valueOf",
            1,
            BuiltInFunction::new(default_functions::value_of),
        );

        context.define_built_in_method_defaults(
            "conversion",
            3,
            BuiltInFunction::new(default_functions::conversion),
        );

        context
    }

    /// Defines a context with all the defaults as well as definitions
    /// for common operators and units
    pub fn prelude() -> EvalContext {
        let mut context = EvalContext::defaults();
        setup_prelude(&mut context);
        context
    }

    /// Gets a single value without evaluating it from the current context
    pub fn get(&self, name: &str) -> Option<ContextItem> {
        self.symbol_table.get(name).map(|item| (*item).clone())
    }

    /// Convenience method for setting a number in the context
    pub fn set_number(&mut self, name: &str, value: RichNumber) {
        self.set(name, ContextItem::Number(value))
    }

    /// Defines a function in the context
    pub fn define(
        &mut self,
        name: &str,
        fixity: Fixity,
        precedence: u8,
        function: Function,
    ) {
        self.set(name, ContextItem::new_definition(fixity, precedence, function));
    }

    /// Defines a function in the context with defaults for precedence and fixity
    pub fn define_defaults(
        &mut self,
        name: &str,
        function: Function,
    ) {
        self.set(name, ContextItem::function_defaults(function));
    }

    /// Defines a function linked to actual code rather than an expression
    pub fn define_built_in_method(
        &mut self,
        name: &str,
        fixity: Fixity,
        precedence: u8,
        params: usize,
        function: BuiltInFunction,
    ) {

        self.set(name, ContextItem::BuiltInMethod {
            fixity: fixity,
            precedence: precedence,
            params: params,
            function: function,
        });
    }

    /// Defines a built-in function in the context with defaults for precedence and fixity
    pub fn define_built_in_method_defaults(
        &mut self,
        name: &str,
        params: usize,
        function: BuiltInFunction,
    ) {
        self.set(name, ContextItem::built_in_defaults(function, params));
    }

    /// Creates a unique identifier for the given unit name
    /// Calling this more than once for the same unit name will end up
    /// with some duplicate definitons, should not be a huge deal but may
    /// lead to problems later on
    pub fn create_unit(&mut self, name: &str) -> Unit {
        let unit = self.next_unit;
        self.next_unit += 1;

        self.units.insert(unit, name.to_owned());

        unit
    }

    /// Creates a constant value
    pub fn set_constant(&mut self, name: &str, value: String) {
        self.set(name, ContextItem::Constant(value));
    }

    /// Creates a boolean value
    pub fn set_boolean(&mut self, name: &str, value: bool) {
        self.set(name, ContextItem::Boolean(value));
    }

    /// Adds to the current context (silently replaces if already present)
    pub fn set(&mut self, name: &str, value: ContextItem) {
        self.symbol_table.insert(name.to_owned(), value);
    }

    /// Converts the value to the given unit by doing appropriate
    /// transformations as prescribed by the conversion table
    /// Returns Err if no appropriate conversion is found
    pub fn convert(&mut self, value: RichNumber, unit: Option<Unit>) -> EvalResult {
        if value.unit.is_none() || unit.is_none() {
            Ok(ContextItem::Number(RichNumber::new(value.value, unit)))
        }
        else {
            let start = value.unit.unwrap();
            let unit = unit.unwrap();

            let conversions = self.conversion_table.conversion_steps(start, unit);

            if conversions.is_none() {
                Err(EvalError::ConversionUndefined {
                    start: start,
                    target: unit,
                })
            }
            else {
                let conversions = conversions.unwrap();

                let mut current = ContextItem::Number(value);
                for next_unit in conversions {
                    //TODO: unwrap_number() here may not be completely safe
                    //TODO: because it is dependent on the result of applying the converter
                    let current_number = current.unwrap_number();

                    // unwrap() is safe here because we used conversion_steps
                    let converter = self.conversion_table.get_converter(
                        current_number.unit.unwrap(),
                        next_unit
                    ).unwrap();

                    current = try!(self.apply_function(converter, vec![
                        ContextItem::Number(current_number.without_units()),
                    ]));
                }

                debug_assert!({
                    let c = current.clone().unwrap_number().unit;
                    !c.is_none() && c.unwrap() == unit
                });

                Ok(current)
            }
        }
    }

    pub fn apply(&mut self, statement: Statement) -> EvalResult {
        match statement {
            Statement::NamedFunction {name, definition} => {
                self.define_defaults(&name, definition);
                Ok(ContextItem::Nothing)
            },
            Statement::AnonymousFunction(_) => Ok(ContextItem::Nothing),
            Statement::Assignment {name, value} => {
                let value = try!(self.evaluate(value));
                self.set(&name, value);
                Ok(ContextItem::Nothing)
            },
            Statement::Expression(value) => self.evaluate(value),
        }
    }

    fn evaluate(&mut self, expr: Expr) -> EvalResult {
        let root = try!(EvalTreeNode::from_expr(self, expr));

        self.reduce(root)
    }

    fn reduce(&mut self, node: EvalTreeNode) -> EvalResult {
        let EvalTreeNode {
            item,
            children,
        } = node;

        let mut params = Vec::new();
        for child in children {
            params.push(try!(self.reduce(child)));
        }

        match item {
            ContextItem::BuiltInMethod { function, .. } => function.call(self, params),
            ContextItem::Definition { function, .. } => self.apply_function(function, params),
            otherwise => Ok(otherwise),
        }
    }

    /// Applies the given parameters to the given function
    fn apply_function(&mut self, function: Function, params: Vec<ContextItem>) -> EvalResult {
        unimplemented!();
    }
}

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

    use ast::*;
    use math::rich_number::RichNumber;

    #[test]
    fn get_set_in_context() {
        let mut context = EvalContext::new();
        assert_eq!(context.get("a"), None);

        let value = RichNumber::from(2f64);
        context.set_number("a", value.clone());
        assert_eq!(context.get("a").map(|n| n.unwrap_number()), Some(value));
    }

    #[test]
    fn define_variable() {
        let mut context = EvalContext::new();
        apply_string(&mut context, "x = 3");

        assert_eq!(context.get("x").map(|n| n.unwrap_number()), Some(RichNumber::from(3f64)));
    }

    #[test]
    fn basic_operators_and_precedence() {
        let result = apply_single("2 * 3 ** 2 - (100e-1 + -77.2) / 13").unwrap();
        assert_eq!(result.unwrap_number(), RichNumber::from(23.1692307692f64));
    }

    fn test_single_boolean(string: &str, expected: bool) {
        let result = apply_single(string).unwrap();
        assert_eq!(result.unwrap_boolean(), expected);
    }

    fn apply_single(string: &str) -> EvalResult {
        let mut context = EvalContext::prelude();
        let statement = parse_statement(string);

        context.apply(statement)
    }

    fn parse_statement(string: &str) -> Statement {
        let mut parsed = parse(string).unwrap();
        assert!(parsed.len() == 1, "parse_statement() was passed more than one statement");

        parsed.pop().unwrap()
    }

    fn apply_string(context: &mut EvalContext, string: &str) {
        apply_program(context, parse(string).unwrap());
    }

    fn apply_program(context: &mut EvalContext, program: Program) {
        for statement in program {
            context.apply(statement).expect("Error while applying statement");
        }
    }
}

<commit_msg>Starting to implement apply_function and adding the ability to return a function when it is provided no parameters<commit_after>use std::collections::HashMap;

use parser::ast::{Function, Expr, Statement};
use math::rich_number::{Unit, RichNumber};
use math::conversion_table::ConversionTable;

use eval::fixity::Fixity;
use eval::context_item::ContextItem;
use eval::built_in_function::BuiltInFunction;
use eval::eval_tree_node::EvalTreeNode;

use eval::defaults as default_functions;

use prelude::setup_prelude;

#[derive(PartialEq, Debug)]
pub enum EvalError {
    UndefinedSymbol(String),
    UnexpectedSymbols,
    ExpectedParams(usize),
    InvalidSymbolDefinition {
        expected_params: usize,
        actual_params: usize,
    },
    ConversionUndefined {
        start: Unit,
        target: Unit,
    },
    InvalidParams(String),
}

pub type EvalResult = Result<ContextItem, EvalError>;

pub struct EvalContext {
    // Symbol name to context item definition
    symbol_table: HashMap<String, ContextItem>,
    // Unit to Symbol name
    units: HashMap<Unit, String>,
    // Used to define new units
    next_unit: Unit,
    conversion_table: ConversionTable,
}

impl EvalContext {
    pub fn new() -> EvalContext {
        EvalContext {
            symbol_table: HashMap::new(),
            units: HashMap::new(),
            next_unit: 1,
            conversion_table: ConversionTable::new(),
        }
    }

    /// Defines a reasonble set of default built_in methods
    pub fn defaults() -> EvalContext {
        let mut context = EvalContext::new();

        context.set_constant("PREFIX", Fixity::Prefix.to_string());
        context.set_constant("INFIX", Fixity::Infix.to_string());
        context.set_constant("POSTFIX", Fixity::Postfix.to_string());

        context.define_built_in_method_defaults(
            "operator",
            4,
            BuiltInFunction::new(default_functions::operator),
        );

        context.define_built_in_method_defaults(
            "defineUnit",
            1,
            BuiltInFunction::new(default_functions::define_unit),
        );

        context.define_built_in_method_defaults(
            "convert",
            2,
            BuiltInFunction::new(default_functions::convert),
        );

        context.define_built_in_method_defaults(
            "unitFor",
            1,
            BuiltInFunction::new(default_functions::unit_for),
        );

        context.define_built_in_method_defaults(
            "valueOf",
            1,
            BuiltInFunction::new(default_functions::value_of),
        );

        context.define_built_in_method_defaults(
            "conversion",
            3,
            BuiltInFunction::new(default_functions::conversion),
        );

        context
    }

    /// Defines a context with all the defaults as well as definitions
    /// for common operators and units
    pub fn prelude() -> EvalContext {
        let mut context = EvalContext::defaults();
        setup_prelude(&mut context);
        context
    }

    /// Gets a single value without evaluating it from the current context
    pub fn get(&self, name: &str) -> Option<ContextItem> {
        self.symbol_table.get(name).map(|item| (*item).clone())
    }

    /// Convenience method for setting a number in the context
    pub fn set_number(&mut self, name: &str, value: RichNumber) {
        self.set(name, ContextItem::Number(value))
    }

    /// Defines a function in the context
    pub fn define(
        &mut self,
        name: &str,
        fixity: Fixity,
        precedence: u8,
        function: Function,
    ) {
        self.set(name, ContextItem::new_definition(fixity, precedence, function));
    }

    /// Defines a function in the context with defaults for precedence and fixity
    pub fn define_defaults(
        &mut self,
        name: &str,
        function: Function,
    ) {
        self.set(name, ContextItem::function_defaults(function));
    }

    /// Defines a function linked to actual code rather than an expression
    pub fn define_built_in_method(
        &mut self,
        name: &str,
        fixity: Fixity,
        precedence: u8,
        params: usize,
        function: BuiltInFunction,
    ) {

        self.set(name, ContextItem::BuiltInMethod {
            fixity: fixity,
            precedence: precedence,
            params: params,
            function: function,
        });
    }

    /// Defines a built-in function in the context with defaults for precedence and fixity
    pub fn define_built_in_method_defaults(
        &mut self,
        name: &str,
        params: usize,
        function: BuiltInFunction,
    ) {
        self.set(name, ContextItem::built_in_defaults(function, params));
    }

    /// Creates a unique identifier for the given unit name
    /// Calling this more than once for the same unit name will end up
    /// with some duplicate definitons, should not be a huge deal but may
    /// lead to problems later on
    pub fn create_unit(&mut self, name: &str) -> Unit {
        let unit = self.next_unit;
        self.next_unit += 1;

        self.units.insert(unit, name.to_owned());

        unit
    }

    /// Creates a constant value
    pub fn set_constant(&mut self, name: &str, value: String) {
        self.set(name, ContextItem::Constant(value));
    }

    /// Creates a boolean value
    pub fn set_boolean(&mut self, name: &str, value: bool) {
        self.set(name, ContextItem::Boolean(value));
    }

    /// Adds to the current context (silently replaces if already present)
    pub fn set(&mut self, name: &str, value: ContextItem) {
        self.symbol_table.insert(name.to_owned(), value);
    }

    /// Converts the value to the given unit by doing appropriate
    /// transformations as prescribed by the conversion table
    /// Returns Err if no appropriate conversion is found
    pub fn convert(&mut self, value: RichNumber, unit: Option<Unit>) -> EvalResult {
        if value.unit.is_none() || unit.is_none() {
            Ok(ContextItem::Number(RichNumber::new(value.value, unit)))
        }
        else {
            let start = value.unit.unwrap();
            let unit = unit.unwrap();

            let conversions = self.conversion_table.conversion_steps(start, unit);

            if conversions.is_none() {
                Err(EvalError::ConversionUndefined {
                    start: start,
                    target: unit,
                })
            }
            else {
                let conversions = conversions.unwrap();

                let mut current = ContextItem::Number(value);
                for next_unit in conversions {
                    //TODO: unwrap_number() here may not be completely safe
                    //TODO: because it is dependent on the result of applying the converter
                    let current_number = current.unwrap_number();

                    // unwrap() is safe here because we used conversion_steps
                    let converter = self.conversion_table.get_converter(
                        current_number.unit.unwrap(),
                        next_unit
                    ).unwrap();

                    current = try!(self.apply_function(&converter, vec![
                        ContextItem::Number(current_number.without_units()),
                    ]));
                }

                debug_assert!({
                    let c = current.clone().unwrap_number().unit;
                    !c.is_none() && c.unwrap() == unit
                });

                Ok(current)
            }
        }
    }

    pub fn apply(&mut self, statement: Statement) -> EvalResult {
        match statement {
            Statement::NamedFunction {name, definition} => {
                self.define_defaults(&name, definition);
                Ok(ContextItem::Nothing)
            },
            Statement::AnonymousFunction(_) => Ok(ContextItem::Nothing),
            Statement::Assignment {name, value} => {
                let value = try!(self.evaluate(value));
                self.set(&name, value);
                Ok(ContextItem::Nothing)
            },
            Statement::Expression(value) => self.evaluate(value),
        }
    }

    fn evaluate(&mut self, expr: Expr) -> EvalResult {
        let root = try!(EvalTreeNode::from_expr(self, expr));

        self.reduce(root)
    }

    fn reduce(&mut self, node: EvalTreeNode) -> EvalResult {
        let EvalTreeNode {
            item,
            children,
        } = node;

        let mut params = Vec::new();
        for child in children {
            params.push(try!(self.reduce(child)));
        }

        match item {
            ContextItem::BuiltInMethod { ref function, params: ref pn, .. } => {
                debug_assert!(*pn != 0,
                    "Functions cannot have zero parameters");

                // Special case: when no parameters are provided, return
                // the function itself.
                // Added to support (f) and anonymous syntax
                if params.len() == 0 {
                    Ok(item.clone())
                }
                else {
                    function.call(self, params)
                }
            },
            ContextItem::Definition { ref function, .. } => {
                if params.len() == 0 {
                    Ok(item.clone())
                }
                else {
                    self.apply_function(function, params)
                }
            },
            otherwise => Ok(otherwise),
        }
    }

    /// Applies the given parameters to the given function
    fn apply_function(&mut self, function: &Function, params: Vec<ContextItem>) -> EvalResult {
        let param_names = &function.params;
        if params.len() != param_names.len() {
            return Err(EvalError::ExpectedParams(param_names.len()));
        }

        let name_mapping = param_names.iter()
            .zip(params.iter())
            .collect::<Vec<_>>();
            //.collect::<HashMap<String, ContextItem>>();
        println!("{:?}", name_mapping);

        unimplemented!();
    }
}

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

    use ast::*;
    use math::rich_number::RichNumber;

    #[test]
    fn get_set_in_context() {
        let mut context = EvalContext::new();
        assert_eq!(context.get("a"), None);

        let value = RichNumber::from(2f64);
        context.set_number("a", value.clone());
        assert_eq!(context.get("a").map(|n| n.unwrap_number()), Some(value));
    }

    #[test]
    fn define_variable() {
        let mut context = EvalContext::new();
        apply_string(&mut context, "x = 3");

        assert_eq!(context.get("x").map(|n| n.unwrap_number()), Some(RichNumber::from(3f64)));
    }

    #[test]
    fn basic_operators_and_precedence() {
        let result = apply_single("2 * 3 ** 2 - (100e-1 + -77.2) / 13").unwrap();
        assert_eq!(result.unwrap_number(), RichNumber::from(23.1692307692f64));
    }

    fn test_single_boolean(string: &str, expected: bool) {
        let result = apply_single(string).unwrap();
        assert_eq!(result.unwrap_boolean(), expected);
    }

    fn apply_single(string: &str) -> EvalResult {
        let mut context = EvalContext::prelude();
        let statement = parse_statement(string);

        context.apply(statement)
    }

    fn parse_statement(string: &str) -> Statement {
        let mut parsed = parse(string).unwrap();
        assert!(parsed.len() == 1, "parse_statement() was passed more than one statement");

        parsed.pop().unwrap()
    }

    fn apply_string(context: &mut EvalContext, string: &str) {
        apply_program(context, parse(string).unwrap());
    }

    fn apply_program(context: &mut EvalContext, program: Program) {
        for statement in program {
            context.apply(statement).expect("Error while applying statement");
        }
    }
}

<|endoftext|>


<commit_before>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! A definition of `StorageKey` trait and implementations for common types.

use byteorder::{ByteOrder, BigEndian};
use crypto::{Hash, PublicKey, HASH_SIZE, PUBLIC_KEY_LENGTH};

/// A type that can be (de)serialized as a key in the blockchain storage.
///
/// Since keys are sorted in a serialized form, the big-endian encoding should be used
/// with unsigned integer types. Note however that the big-endian encoding
/// will **not** sort signed integer types in the natural order; a possible solution is
/// mapping the type to a corresponding unsigned one as shown in the example below.
///
/// # Examples
///
/// ```
/// # extern crate exonum;
/// # extern crate byteorder;
/// use std::mem;
/// use exonum::storage::StorageKey;
/// use byteorder::{BigEndian, ByteOrder};
///
/// struct Key {
///     a: i16,
///     b: u32,
/// }
///
/// impl StorageKey for Key {
///     fn size(&self) -> usize {
///         mem::size_of_val(&self.a) + mem::size_of_val(&self.b)
///     }
///
///     fn write(&self, buffer: &mut [u8]) {
///         // Maps `a` to the `u16` range in the natural order:
///         // -32768 -> 0, -32767 -> 1, ..., 32767 -> 65535
///         let mapped_a = self.a.wrapping_add(i16::min_value()) as u16;
///         BigEndian::write_u16(&mut buffer[0..2], mapped_a);
///         BigEndian::write_u32(&mut buffer[2..6], self.b);
///     }
///
///     fn read(buffer: &[u8]) -> Self {
///         let mapped_a = BigEndian::read_u16(&buffer[0..2]);
///         let a = mapped_a.wrapping_add(i16::min_value() as u16) as i16;
///         let b = BigEndian::read_u32(&buffer[2..6]);
///         Key { a, b }
///     }
/// }
/// # fn main() {
/// # // Check the natural ordering of keys
/// # let (mut x, mut y) = (vec![0u8; 6], vec![0u8; 6]);
/// # Key { a: -1, b: 2 }.write(&mut x);
/// # Key { a: 1, b: 513 }.write(&mut y);
/// # assert!(x < y);
/// # // Check the roundtrip
/// # let key = Key::read(&x);
/// # assert_eq!(key.a, -1);
/// # assert_eq!(key.b, 2);
/// # }
/// ```
pub trait StorageKey {
    /// Returns the size of the serialized key in bytes.
    fn size(&self) -> usize;

    /// Serializes the key into the specified buffer of bytes.
    ///
    /// The caller must guarantee that the size of the buffer is equal to the precalculated size
    /// of the serialized key.
    // TODO: should be unsafe (ECR-174)?
    fn write(&self, buffer: &mut [u8]);

    /// Deserializes the key from the specified buffer of bytes.
    // TODO: should be unsafe (ECR-174)?
    fn read(buffer: &[u8]) -> Self;
}

/// No-op implementation.
impl StorageKey for () {
    fn size(&self) -> usize {
        0
    }

    fn write(&self, _buffer: &mut [u8]) {
        // no-op
    }

    fn read(_buffer: &[u8]) -> Self {
        ()
    }
}

impl StorageKey for u8 {
    fn size(&self) -> usize {
        1
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer[0] = *self
    }

    fn read(buffer: &[u8]) -> Self {
        buffer[0]
    }
}

/// Uses encoding with the values mapped to `u8`
/// by adding the corresponding constant (`128`) to the value.
impl StorageKey for i8 {
    fn size(&self) -> usize {
        1
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer[0] = self.wrapping_add(i8::min_value()) as u8;
    }

    fn read(buffer: &[u8]) -> Self {
        buffer[0].wrapping_add(i8::min_value() as u8) as i8
    }
}

macro_rules! storage_key_for_ints {
    ($utype:ident, $itype:ident, $size:expr, $read_method:ident, $write_method:ident) => {
        /// Uses big-endian encoding.
        impl StorageKey for $utype {
            fn size(&self) -> usize {
                $size
            }

            fn write(&self, buffer: &mut [u8]) {
                BigEndian::$write_method(buffer, *self);
            }

            fn read(buffer: &[u8]) -> Self {
                BigEndian::$read_method(buffer)
            }
        }

        /// Uses big-endian encoding with the values mapped to the unsigned format
        /// by adding the corresponding constant to the value.
        impl StorageKey for $itype {
            fn size(&self) -> usize {
                $size
            }

            fn write(&self, buffer: &mut [u8]) {
                BigEndian::$write_method(
                    buffer,
                    self.wrapping_add($itype::min_value()) as $utype,
                );
            }

            fn read(buffer: &[u8]) -> Self {
                BigEndian::$read_method(buffer)
                    .wrapping_add($itype::min_value() as $utype) as $itype
            }
        }
    }
}

storage_key_for_ints!{u16, i16, 2, read_u16, write_u16}
storage_key_for_ints!{u32, i32, 4, read_u32, write_u32}
storage_key_for_ints!{u64, i64, 8, read_u64, write_u64}

impl StorageKey for Hash {
    fn size(&self) -> usize {
        HASH_SIZE
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_ref())
    }

    fn read(buffer: &[u8]) -> Self {
        Hash::from_slice(buffer).unwrap()
    }
}

impl StorageKey for PublicKey {
    fn size(&self) -> usize {
        PUBLIC_KEY_LENGTH
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_ref())
    }

    fn read(buffer: &[u8]) -> Self {
        PublicKey::from_slice(buffer).unwrap()
    }
}

impl StorageKey for Vec<u8> {
    fn size(&self) -> usize {
        self.len()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self)
    }

    fn read(buffer: &[u8]) -> Self {
        buffer.to_vec()
    }
}

/// Uses UTF-8 string serialization.
impl StorageKey for String {
    fn size(&self) -> usize {
        self.len()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_bytes())
    }

    fn read(buffer: &[u8]) -> Self {
        unsafe { ::std::str::from_utf8_unchecked(buffer).to_string() }
    }
}
<commit_msg>Test `StorageKey` impls for integer types<commit_after>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! A definition of `StorageKey` trait and implementations for common types.

use byteorder::{ByteOrder, BigEndian};
use crypto::{Hash, PublicKey, HASH_SIZE, PUBLIC_KEY_LENGTH};

/// A type that can be (de)serialized as a key in the blockchain storage.
///
/// Since keys are sorted in a serialized form, the big-endian encoding should be used
/// with unsigned integer types. Note however that the big-endian encoding
/// will **not** sort signed integer types in the natural order; a possible solution is
/// mapping the type to a corresponding unsigned one as shown in the example below.
///
/// # Examples
///
/// ```
/// # extern crate exonum;
/// # extern crate byteorder;
/// use std::mem;
/// use exonum::storage::StorageKey;
/// use byteorder::{BigEndian, ByteOrder};
///
/// struct Key {
///     a: i16,
///     b: u32,
/// }
///
/// impl StorageKey for Key {
///     fn size(&self) -> usize {
///         mem::size_of_val(&self.a) + mem::size_of_val(&self.b)
///     }
///
///     fn write(&self, buffer: &mut [u8]) {
///         // Maps `a` to the `u16` range in the natural order:
///         // -32768 -> 0, -32767 -> 1, ..., 32767 -> 65535
///         let mapped_a = self.a.wrapping_add(i16::min_value()) as u16;
///         BigEndian::write_u16(&mut buffer[0..2], mapped_a);
///         BigEndian::write_u32(&mut buffer[2..6], self.b);
///     }
///
///     fn read(buffer: &[u8]) -> Self {
///         let mapped_a = BigEndian::read_u16(&buffer[0..2]);
///         let a = mapped_a.wrapping_add(i16::min_value() as u16) as i16;
///         let b = BigEndian::read_u32(&buffer[2..6]);
///         Key { a, b }
///     }
/// }
/// # fn main() {
/// # // Check the natural ordering of keys
/// # let (mut x, mut y) = (vec![0u8; 6], vec![0u8; 6]);
/// # Key { a: -1, b: 2 }.write(&mut x);
/// # Key { a: 1, b: 513 }.write(&mut y);
/// # assert!(x < y);
/// # // Check the roundtrip
/// # let key = Key::read(&x);
/// # assert_eq!(key.a, -1);
/// # assert_eq!(key.b, 2);
/// # }
/// ```
pub trait StorageKey {
    /// Returns the size of the serialized key in bytes.
    fn size(&self) -> usize;

    /// Serializes the key into the specified buffer of bytes.
    ///
    /// The caller must guarantee that the size of the buffer is equal to the precalculated size
    /// of the serialized key.
    // TODO: should be unsafe (ECR-174)?
    fn write(&self, buffer: &mut [u8]);

    /// Deserializes the key from the specified buffer of bytes.
    // TODO: should be unsafe (ECR-174)?
    fn read(buffer: &[u8]) -> Self;
}

/// No-op implementation.
impl StorageKey for () {
    fn size(&self) -> usize {
        0
    }

    fn write(&self, _buffer: &mut [u8]) {
        // no-op
    }

    fn read(_buffer: &[u8]) -> Self {
        ()
    }
}

impl StorageKey for u8 {
    fn size(&self) -> usize {
        1
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer[0] = *self
    }

    fn read(buffer: &[u8]) -> Self {
        buffer[0]
    }
}

/// Uses encoding with the values mapped to `u8`
/// by adding the corresponding constant (`128`) to the value.
impl StorageKey for i8 {
    fn size(&self) -> usize {
        1
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer[0] = self.wrapping_add(i8::min_value()) as u8;
    }

    fn read(buffer: &[u8]) -> Self {
        buffer[0].wrapping_add(i8::min_value() as u8) as i8
    }
}

macro_rules! storage_key_for_ints {
    ($utype:ident, $itype:ident, $size:expr, $read_method:ident, $write_method:ident) => {
        /// Uses big-endian encoding.
        impl StorageKey for $utype {
            fn size(&self) -> usize {
                $size
            }

            fn write(&self, buffer: &mut [u8]) {
                BigEndian::$write_method(buffer, *self);
            }

            fn read(buffer: &[u8]) -> Self {
                BigEndian::$read_method(buffer)
            }
        }

        /// Uses big-endian encoding with the values mapped to the unsigned format
        /// by adding the corresponding constant to the value.
        impl StorageKey for $itype {
            fn size(&self) -> usize {
                $size
            }

            fn write(&self, buffer: &mut [u8]) {
                BigEndian::$write_method(
                    buffer,
                    self.wrapping_add($itype::min_value()) as $utype,
                );
            }

            fn read(buffer: &[u8]) -> Self {
                BigEndian::$read_method(buffer)
                    .wrapping_add($itype::min_value() as $utype) as $itype
            }
        }
    }
}

storage_key_for_ints!{u16, i16, 2, read_u16, write_u16}
storage_key_for_ints!{u32, i32, 4, read_u32, write_u32}
storage_key_for_ints!{u64, i64, 8, read_u64, write_u64}

impl StorageKey for Hash {
    fn size(&self) -> usize {
        HASH_SIZE
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_ref())
    }

    fn read(buffer: &[u8]) -> Self {
        Hash::from_slice(buffer).unwrap()
    }
}

impl StorageKey for PublicKey {
    fn size(&self) -> usize {
        PUBLIC_KEY_LENGTH
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_ref())
    }

    fn read(buffer: &[u8]) -> Self {
        PublicKey::from_slice(buffer).unwrap()
    }
}

impl StorageKey for Vec<u8> {
    fn size(&self) -> usize {
        self.len()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self)
    }

    fn read(buffer: &[u8]) -> Self {
        buffer.to_vec()
    }
}

/// Uses UTF-8 string serialization.
impl StorageKey for String {
    fn size(&self) -> usize {
        self.len()
    }

    fn write(&self, buffer: &mut [u8]) {
        buffer.copy_from_slice(self.as_bytes())
    }

    fn read(buffer: &[u8]) -> Self {
        unsafe { ::std::str::from_utf8_unchecked(buffer).to_string() }
    }
}

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

    // Number of samples for fuzz testing
    const FUZZ_SAMPLES: usize = 10_000;

    macro_rules! test_storage_key_for_int_type {
        (full $type:ident, $size:expr => $test_name:ident) => {
            #[test]
            fn $test_name() {
                // Roundtrip
                let mut buffer = [0u8; $size];
                for x in $type::min_value()..$type::max_value() {
                    x.write(&mut buffer);
                    assert_eq!($type::read(&buffer), x);
                }

                // Ordering
                let (mut x_buffer, mut y_buffer) = ([0u8; $size], [0u8; $size]);
                for x in $type::min_value()..$type::max_value() {
                    let y = x + 1;
                    x.write(&mut x_buffer);
                    y.write(&mut y_buffer);
                    assert!(x_buffer < y_buffer);
                }
            }
        };
        (fuzz $type:ident, $size:expr => $test_name:ident) => {
            #[test]
            fn $test_name() {
                use rand::{Rng, thread_rng};
                let mut rng = thread_rng();

                // Fuzzed roundtrip
                let mut buffer = [0u8; $size];
                for _ in 0..FUZZ_SAMPLES {
                    let x: $type = rng.gen();
                    x.write(&mut buffer);
                    assert_eq!($type::read(&buffer), x);
                }

                // Fuzzed ordering
                let (mut x_buffer, mut y_buffer) = ([0u8; $size], [0u8; $size]);
                let mut vals: Vec<$type> = rng.gen_iter().take(FUZZ_SAMPLES).collect();
                vals.sort();
                for w in vals.windows(2) {
                    let (x, y) = (w[0], w[1]);
                    x.write(&mut x_buffer);
                    y.write(&mut y_buffer);
                    assert!(x_buffer < y_buffer);
                }
            }
        }
    }

    test_storage_key_for_int_type!{full  u8, 1 => test_storage_key_for_u8}
    test_storage_key_for_int_type!{full  i8, 1 => test_storage_key_for_i8}
    test_storage_key_for_int_type!{full u16, 2 => test_storage_key_for_u16}
    test_storage_key_for_int_type!{full i16, 2 => test_storage_key_for_i16}
    test_storage_key_for_int_type!{fuzz u32, 4 => test_storage_key_for_u32}
    test_storage_key_for_int_type!{fuzz i32, 4 => test_storage_key_for_i32}
    test_storage_key_for_int_type!{fuzz u64, 8 => test_storage_key_for_u64}
    test_storage_key_for_int_type!{fuzz i64, 8 => test_storage_key_for_i64}
}
<|endoftext|>


<commit_before>// run-pass
// ignore-wasm32-bare no env vars

use std::env::*;

fn main() {
    for (k, v) in vars_os() {
        let v2 = var_os(&k);
        assert!(v2.as_ref().map(|s| &**s) == Some(&*v),
                "bad vars->var transition: {:?} {:?} {:?}", k, v, v2);
    }
}
<commit_msg>Auto merge of #79685 - sivadeilra:fix_env_vars_win, r=davidtwco<commit_after>// run-pass
// ignore-wasm32-bare no env vars

use std::env::*;

fn main() {
    for (k, v) in vars_os() {
        // On Windows, the environment variable NUMBER_OF_PROCESSORS has special meaning.
        // Unfortunately, you can get different answers, depending on whether you are
        // enumerating all environment variables or querying a specific variable.
        // This was causing this test to fail on machines with more than 64 processors.
        if cfg!(target_os = "windows") && k == "NUMBER_OF_PROCESSORS" {
            continue;
        }

        let v2 = var_os(&k);
        assert!(v2.as_ref().map(|s| &**s) == Some(&*v),
                "bad vars->var transition: {:?} {:?} {:?}", k, v, v2);
    }
}
<|endoftext|>