<commit_before>extern crate structopt;
#[macro_use]
extern crate structopt_derive;

use structopt::StructOpt;
use std::collections::BTreeSet;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct Component {
    input: usize,
    output: usize,
}

impl Component {
    fn flip(&self) -> Component {
        Component {
            input: self.output,
            output: self.input,
        }
    }
}

fn parse(input: &str) -> BTreeSet<Component> {
    let mut components = BTreeSet::new();
    for line in input.lines() {
        let (i, o) = line.split_at(
            line.find('/').expect(&format!("invalid line: {}", line)),
        );
        let new_comp = Component {
            input: i.trim().parse().expect(&format!("invalid size: {}", i)),
            output: o[1..]
                .trim()
                .parse()
                .expect(&format!("invalid size: {}", o)),
        };
        assert!(
            !components.contains(&new_comp)
                && !components.contains(&new_comp.flip()),
            "Repeat component found! You'll need a better algorithm."
        );
        components.insert(new_comp);
    }
    components
}

fn max_strength(start: usize, components: &BTreeSet<Component>) -> usize {
    components
        .iter()
        .filter_map(|component| {
            if component.input == start {
                let mut new_set = components.clone();
                new_set.remove(component);
                Some(
                    max_strength(component.output, &new_set) + component.input
                        + component.output,
                )
            } else if component.output == start {
                let mut new_set = components.clone();
                new_set.remove(component);
                Some(
                    max_strength(component.input, &new_set) + component.input
                        + component.output,
                )
            } else {
                None
            }
        })
        .max()
        .unwrap_or_default()
}

fn part1(components: &BTreeSet<Component>) -> usize {
    max_strength(0, components)
}

fn main() {
    let opt = Opt::from_args();
    let mut contents = String::new();
    if opt.input.to_str() == Some("-") {
        std::io::stdin()
            .read_to_string(&mut contents)
            .expect("could not read stdin");
    } else {
        let mut file = File::open(&opt.input)
            .expect(&format!("file {} not found", opt.input.display()));
        file.read_to_string(&mut contents)
            .expect(&format!("could not read file {}", opt.input.display()));
    }
    let components = parse(&contents);
    println!("Part 1: {}", part1(&components));
}

#[derive(StructOpt, Debug)]
#[structopt(name = "day24", about = "Advent of code 2017 day 24")]
struct Opt {
    #[structopt(help = "Input file", parse(from_os_str))]
    input: PathBuf,
}

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

    #[test]
    fn part1_test() {
        let input = concat!(
            "0/2\n",
            "2/2\n",
            "2/3\n",
            "3/4\n",
            "3/5\n",
            "0/1\n",
            "10/1\n",
            "9/10"
        );
        let components = parse(input);
        assert_eq!(part1(&components), 31);
    }
}
<commit_msg>2017 day 24 part 02<commit_after>extern crate structopt;
#[macro_use]
extern crate structopt_derive;

use structopt::StructOpt;
use std::collections::BTreeSet;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct Component {
    input: usize,
    output: usize,
}

impl Component {
    fn flip(&self) -> Component {
        Component {
            input: self.output,
            output: self.input,
        }
    }
}

fn parse(input: &str) -> BTreeSet<Component> {
    let mut components = BTreeSet::new();
    for line in input.lines() {
        let (i, o) = line.split_at(
            line.find('/').expect(&format!("invalid line: {}", line)),
        );
        let new_comp = Component {
            input: i.trim().parse().expect(&format!("invalid size: {}", i)),
            output: o[1..]
                .trim()
                .parse()
                .expect(&format!("invalid size: {}", o)),
        };
        assert!(
            !components.contains(&new_comp)
                && !components.contains(&new_comp.flip()),
            "Repeat component found! You'll need a better algorithm."
        );
        components.insert(new_comp);
    }
    components
}

fn strength<Iter>(iter: Iter) -> usize
where
    Iter: IntoIterator<Item = Component>,
{
    iter.into_iter().map(|c| c.input + c.output).sum()
}

fn max_strength(start: usize, components: &BTreeSet<Component>) -> usize {
    components
        .iter()
        .filter_map(|component| {
            if component.input == start {
                let mut new_set = components.clone();
                new_set.remove(component);
                Some(
                    max_strength(component.output, &new_set) + component.input
                        + component.output,
                )
            } else if component.output == start {
                let mut new_set = components.clone();
                new_set.remove(component);
                Some(
                    max_strength(component.input, &new_set) + component.input
                        + component.output,
                )
            } else {
                None
            }
        })
        .max()
        .unwrap_or_default()
}

fn part1(components: &BTreeSet<Component>) -> usize {
    max_strength(0, components)
}

fn possibilities(
    start: usize,
    components: &BTreeSet<Component>,
) -> Vec<Vec<Component>> {
    components
        .iter()
        .flat_map(|component| {
            if component.input == start {
                let mut new_set = components.clone();
                new_set.remove(component);
                let mut ps = possibilities(component.output, &new_set);
                for mut p in &mut ps {
                    p.push(*component);
                }
                ps.push(vec![*component]);
                ps
            } else if component.output == start {
                let mut new_set = components.clone();
                new_set.remove(component);
                let mut ps = possibilities(component.input, &new_set);
                for mut p in &mut ps {
                    p.push(component.flip());
                }
                ps.push(vec![*component]);
                ps
            } else {
                vec![]
            }
        })
        .collect()
}

fn part2(components: &BTreeSet<Component>) -> usize {
    possibilities(0, components)
        .into_iter()
        .max_by(|a, b| {
            a.len()
                .cmp(&b.len())
                .then_with(|| strength(a.clone()).cmp(&strength(b.clone())))
        })
        .map(strength)
        .unwrap_or_default()
}

fn main() {
    let opt = Opt::from_args();
    let mut contents = String::new();
    if opt.input.to_str() == Some("-") {
        std::io::stdin()
            .read_to_string(&mut contents)
            .expect("could not read stdin");
    } else {
        let mut file = File::open(&opt.input)
            .expect(&format!("file {} not found", opt.input.display()));
        file.read_to_string(&mut contents)
            .expect(&format!("could not read file {}", opt.input.display()));
    }
    let components = parse(&contents);
    println!("Part 1: {}", part1(&components));
    println!("Part 2: {}", part2(&components));
}

#[derive(StructOpt, Debug)]
#[structopt(name = "day24", about = "Advent of code 2017 day 24")]
struct Opt {
    #[structopt(help = "Input file", parse(from_os_str))]
    input: PathBuf,
}

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

    static INPUT: &str = concat!(
        "0/2\n",
        "2/2\n",
        "2/3\n",
        "3/4\n",
        "3/5\n",
        "0/1\n",
        "10/1\n",
        "9/10"
    );

    #[test]
    fn part1_test() {
        let components = parse(INPUT);
        assert_eq!(part1(&components), 31);
    }

    #[test]
    fn part2_test() {
        let components = parse(INPUT);
        assert_eq!(part2(&components), 19);
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

extern crate chrono;
extern crate clap;

extern crate fc_util;
extern crate jailer;

fn main() {
    if let Err(error) = jailer::run(
        jailer::clap_app().get_matches(),
        (chrono::Utc::now().timestamp_nanos() / 1000) as u64,
        fc_util::now_cputime_us(),
    ) {
        eprintln!("Jailer error: {}", error);
    }
}
<commit_msg>Panic when starting the jailer fails<commit_after>// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

extern crate chrono;
extern crate clap;

extern crate fc_util;
extern crate jailer;

fn main() {
    if let Err(error) = jailer::run(
        jailer::clap_app().get_matches(),
        (chrono::Utc::now().timestamp_nanos() / 1000) as u64,
        fc_util::now_cputime_us(),
    ) {
        panic!("Jailer error: {}", error);
    }
}
<|endoftext|>


<commit_before>#![warn(clippy::all, rust_2018_idioms)]

use cargo_registry::{boot, App, Env};
use std::{
    fs::File,
    sync::{mpsc::channel, Arc, Mutex},
    thread,
    time::Duration,
};

use civet::Server as CivetServer;
use conduit_hyper::Service;
use futures::prelude::*;
use reqwest::blocking::Client;

enum Server {
    Civet(CivetServer),
    Hyper(tokio::runtime::Runtime, tokio::task::JoinHandle<()>),
}

use Server::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize logging
    env_logger::init();

    let config = cargo_registry::Config::default();
    let client = Client::new();

    let app = App::new(&config, Some(client));
    let app = cargo_registry::build_handler(Arc::new(app));

    // On every server restart, ensure the categories available in the database match
    // the information in *src/categories.toml*.
    let categories_toml = include_str!("../boot/categories.toml");
    boot::categories::sync(categories_toml).unwrap();

    let heroku = dotenv::var("HEROKU").is_ok();
    let fastboot = dotenv::var("USE_FASTBOOT").is_ok();

    let port = if heroku {
        8888
    } else {
        dotenv::var("PORT")
            .ok()
            .and_then(|s| s.parse().ok())
            .unwrap_or(8888)
    };
    let threads = dotenv::var("SERVER_THREADS")
        .map(|s| s.parse().expect("SERVER_THREADS was not a valid number"))
        .unwrap_or_else(|_| {
            if config.env == Env::Development {
                1
            } else {
                50
            }
        });

    let server = if dotenv::var("USE_HYPER").is_ok() {
        use tokio::io::AsyncWriteExt;
        use tokio::signal::unix::{signal, SignalKind};

        println!("Booting with a hyper based server");

        let mut rt = tokio::runtime::Builder::new()
            .threaded_scheduler()
            .enable_all()
            .build()
            .unwrap();

        let handler = Arc::new(conduit_hyper::BlockingHandler::new(app, threads as usize));
        let make_service =
            hyper::service::make_service_fn(move |socket: &hyper::server::conn::AddrStream| {
                let addr = socket.remote_addr();
                let handler = handler.clone();
                async move { Service::from_blocking(handler, addr) }
            });

        let addr = ([127, 0, 0, 1], port).into();
        let server = rt.block_on(async { hyper::Server::bind(&addr).serve(make_service) });

        let mut sig_int = rt.block_on(async { signal(SignalKind::interrupt()) })?;
        let mut sig_term = rt.block_on(async { signal(SignalKind::terminate()) })?;

        let server = server.with_graceful_shutdown(async move {
            // Wait for either signal
            futures::select! {
                _ = sig_int.recv().fuse() => (),
                _ = sig_term.recv().fuse() => (),
            };
            let mut stdout = tokio::io::stdout();
            stdout.write_all(b"Starting graceful shutdown\n").await.ok();
        });

        let server = rt.spawn(async { server.await.unwrap() });
        Hyper(rt, server)
    } else {
        println!("Booting with a civet based server");
        let mut cfg = civet::Config::new();
        cfg.port(port).threads(threads).keep_alive(true);
        Civet(CivetServer::start(cfg, app).unwrap())
    };

    println!("listening on port {}", port);

    // Give tokio a chance to spawn the first worker thread
    thread::sleep(Duration::from_millis(10));

    // Creating this file tells heroku to tell nginx that the application is ready
    // to receive traffic.
    if heroku {
        let path = if fastboot {
            "/tmp/backend-initialized"
        } else {
            "/tmp/app-initialized"
        };
        println!("Writing to {}", path);
        File::create(path).unwrap();
    }

    // Block the main thread until the server has shutdown
    match server {
        Hyper(mut rt, server) => {
            rt.block_on(async { server.await.unwrap() });
        }
        Civet(server) => {
            let (tx, rx) = channel::<()>();
            ctrlc_handler(move || tx.send(()).unwrap_or(()));
            rx.recv().unwrap();
            drop(server);
        }
    }

    println!("Server has gracefully shutdown!");
    Ok(())
}

fn ctrlc_handler<F>(f: F)
where
    F: FnOnce() + Send + 'static,
{
    let call_once = Mutex::new(Some(f));

    ctrlc::set_handler(move || {
        if let Some(f) = call_once.lock().unwrap().take() {
            println!("Starting graceful shutdown");
            f();
        } else {
            println!("Already sent signal to start graceful shutdown");
        }
    })
    .unwrap();
}
<commit_msg>Auto merge of #2212 - jtgeibel:increase-dev-thread-count, r=Turbo87<commit_after>#![warn(clippy::all, rust_2018_idioms)]

use cargo_registry::{boot, App, Env};
use std::{
    fs::File,
    sync::{mpsc::channel, Arc, Mutex},
    thread,
    time::Duration,
};

use civet::Server as CivetServer;
use conduit_hyper::Service;
use futures::prelude::*;
use reqwest::blocking::Client;

enum Server {
    Civet(CivetServer),
    Hyper(tokio::runtime::Runtime, tokio::task::JoinHandle<()>),
}

use Server::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize logging
    env_logger::init();

    let config = cargo_registry::Config::default();
    let client = Client::new();

    let app = App::new(&config, Some(client));
    let app = cargo_registry::build_handler(Arc::new(app));

    // On every server restart, ensure the categories available in the database match
    // the information in *src/categories.toml*.
    let categories_toml = include_str!("../boot/categories.toml");
    boot::categories::sync(categories_toml).unwrap();

    let heroku = dotenv::var("HEROKU").is_ok();
    let fastboot = dotenv::var("USE_FASTBOOT").is_ok();

    let port = if heroku {
        8888
    } else {
        dotenv::var("PORT")
            .ok()
            .and_then(|s| s.parse().ok())
            .unwrap_or(8888)
    };
    let threads = dotenv::var("SERVER_THREADS")
        .map(|s| s.parse().expect("SERVER_THREADS was not a valid number"))
        .unwrap_or_else(|_| {
            if config.env == Env::Development {
                5
            } else {
                50
            }
        });

    let server = if dotenv::var("USE_HYPER").is_ok() {
        use tokio::io::AsyncWriteExt;
        use tokio::signal::unix::{signal, SignalKind};

        println!("Booting with a hyper based server");

        let mut rt = tokio::runtime::Builder::new()
            .threaded_scheduler()
            .enable_all()
            .build()
            .unwrap();

        let handler = Arc::new(conduit_hyper::BlockingHandler::new(app, threads as usize));
        let make_service =
            hyper::service::make_service_fn(move |socket: &hyper::server::conn::AddrStream| {
                let addr = socket.remote_addr();
                let handler = handler.clone();
                async move { Service::from_blocking(handler, addr) }
            });

        let addr = ([127, 0, 0, 1], port).into();
        let server = rt.block_on(async { hyper::Server::bind(&addr).serve(make_service) });

        let mut sig_int = rt.block_on(async { signal(SignalKind::interrupt()) })?;
        let mut sig_term = rt.block_on(async { signal(SignalKind::terminate()) })?;

        let server = server.with_graceful_shutdown(async move {
            // Wait for either signal
            futures::select! {
                _ = sig_int.recv().fuse() => (),
                _ = sig_term.recv().fuse() => (),
            };
            let mut stdout = tokio::io::stdout();
            stdout.write_all(b"Starting graceful shutdown\n").await.ok();
        });

        let server = rt.spawn(async { server.await.unwrap() });
        Hyper(rt, server)
    } else {
        println!("Booting with a civet based server");
        let mut cfg = civet::Config::new();
        cfg.port(port).threads(threads).keep_alive(true);
        Civet(CivetServer::start(cfg, app).unwrap())
    };

    println!("listening on port {}", port);

    // Give tokio a chance to spawn the first worker thread
    thread::sleep(Duration::from_millis(10));

    // Creating this file tells heroku to tell nginx that the application is ready
    // to receive traffic.
    if heroku {
        let path = if fastboot {
            "/tmp/backend-initialized"
        } else {
            "/tmp/app-initialized"
        };
        println!("Writing to {}", path);
        File::create(path).unwrap();
    }

    // Block the main thread until the server has shutdown
    match server {
        Hyper(mut rt, server) => {
            rt.block_on(async { server.await.unwrap() });
        }
        Civet(server) => {
            let (tx, rx) = channel::<()>();
            ctrlc_handler(move || tx.send(()).unwrap_or(()));
            rx.recv().unwrap();
            drop(server);
        }
    }

    println!("Server has gracefully shutdown!");
    Ok(())
}

fn ctrlc_handler<F>(f: F)
where
    F: FnOnce() + Send + 'static,
{
    let call_once = Mutex::new(Some(f));

    ctrlc::set_handler(move || {
        if let Some(f) = call_once.lock().unwrap().take() {
            println!("Starting graceful shutdown");
            f();
        } else {
            println!("Already sent signal to start graceful shutdown");
        }
    })
    .unwrap();
}
<|endoftext|>


<commit_before>extern crate ring;
extern crate udt;

use std::net::{UdpSocket, SocketAddr, IpAddr};
use std::str;
use std::fmt;
use udt::{UdtSocket, UdtError, UdtOpts, SocketType, SocketFamily};
use ring::aead;
use ring::rand;

// TODO config
const UDT_BUF_SIZE: i32 = 4096000;
pub const MAX_MESSAGE_SIZE: usize = 1024000;

pub mod crypto {
    use ring::aead;
    use ring::aead::{SealingKey, OpeningKey, Algorithm};
    use ring::rand::{SystemRandom, SecureRandom};
    static ALGORITHM: &'static Algorithm = &aead::AES_256_GCM;

    pub struct Handler {
        _working_nonce_buf: [u8; 32],
        _working_seal_buf: [u8; super::MAX_MESSAGE_SIZE],
        rand: SystemRandom,
        opening_key: OpeningKey,
        sealing_key: SealingKey,
    }

    pub fn gen_key() -> Vec<u8> {
        let rand = SystemRandom::new();
        let mut keybytes = vec![0u8; ALGORITHM.key_len()];
        rand.fill(&mut keybytes);
        keybytes
    }

    impl Handler {
        pub fn new(key: &[u8]) -> Handler {
            Handler {
                _working_seal_buf: [0u8; super::MAX_MESSAGE_SIZE],
                _working_nonce_buf: [0u8; 32],
                rand: SystemRandom::new(),
                opening_key: aead::OpeningKey::new(ALGORITHM, key).unwrap(),
                sealing_key: aead::SealingKey::new(ALGORITHM, key).unwrap(),
            }
        }

        pub fn seal(&mut self, buf: &mut [u8], len: usize) -> Result<usize, ()> {
            let nonce_len = ALGORITHM.nonce_len();
            let max_suffix_len = ALGORITHM.max_overhead_len();

            assert!(nonce_len < u8::max_value() as usize,
                    "Uh, why is the nonce size this big?");

            assert!(len <= buf.len() - max_suffix_len,
                    "Buffer doesn't have enough suffix padding.");

            let mut nonce = &mut self._working_nonce_buf[..nonce_len];
            self.rand.fill(&mut nonce).unwrap();

            let mut sealed = &mut self._working_seal_buf[..len + max_suffix_len];
            sealed[0..len].copy_from_slice(&buf[..len]);
            match aead::seal_in_place(&self.sealing_key,
                                      &nonce,
                                      &mut sealed,
                                      max_suffix_len,
                                      &[]) {
                Ok(seal_len) => {
                    buf[..nonce_len].copy_from_slice(&nonce[..]);
                    buf[nonce_len..nonce_len+seal_len].copy_from_slice(&sealed[..seal_len]);
                    Ok(nonce_len + seal_len)
                }
                Err(e) => {
                    Err(())
                }
            }
        }

        pub fn open(&mut self, buf: &mut [u8]) -> Result<usize, String> {
            let nonce_len = ALGORITHM.nonce_len();

            if buf.len() < nonce_len {
                return Err("msg not long enough to contain nonce".into());
            } else if buf.len() > super::MAX_MESSAGE_SIZE {
                return Err("max message size exceeded".into());
            }

            let nonce = &mut self._working_nonce_buf[..nonce_len];
            nonce.copy_from_slice(&buf[..nonce_len]);

            aead::open_in_place(&self.opening_key, &nonce, nonce_len, buf, &[])
                .map_err(|_| String::from("decrypt failed"))
        }
    }

    // Tests for the crypto module
    #[cfg(test)]
    mod test {

        #[test]
        fn raw_roundtrip() {
            use ring::aead;
            use ring::aead::{SealingKey, OpeningKey, Algorithm};
            use ring::rand::{SystemRandom, SecureRandom};

            let rng = SystemRandom::new();
            let mut key_bytes = vec![0u8; super::ALGORITHM.key_len()];
            let mut nonce_bytes = vec![0u8; super::ALGORITHM.nonce_len()];
            rng.fill(&mut key_bytes).unwrap();
            rng.fill(&mut nonce_bytes).unwrap();
            let key = SealingKey::new(super::ALGORITHM, &key_bytes).unwrap();

            let data = [1u8; 1350];
            let out_suffix_capacity = super::ALGORITHM.max_overhead_len();
            let mut in_out = vec![1u8; data.len() + out_suffix_capacity];
            aead::seal_in_place(&key, &nonce_bytes,
                                &mut in_out, out_suffix_capacity,
                                &[]).unwrap();

            let opening_key = OpeningKey::new(super::ALGORITHM, &key_bytes).unwrap();
            let len = aead::open_in_place(&opening_key, &nonce_bytes,
                                          0, &mut in_out, &[]).unwrap();

            assert_eq!(len, 1350);
            assert_eq!(&in_out[..len], &data[..]);
        }

        #[test]
        fn roundtrip() {
            use ::rand;
            use ::rand::distributions::{IndependentSample, Range};
            // generate some data, seal it, and then make sure it unseals to the same thing
            let mut rng = rand::thread_rng();
            let between = Range::new(10, 10000);

            let key = super::gen_key();
            let mut handler = super::Handler::new(&key);
            let data_size: usize = between.ind_sample(&mut rng);
            let mut data = vec![0u8; super::super::MAX_MESSAGE_SIZE];
            for i in 0..data_size {
                data[i] = rand::random();
            }

            let orig = data[..data_size].to_owned();

            let cipher_len = handler.seal(&mut data, data_size).unwrap();
            let decrypted_len = handler.open(&mut data[..cipher_len]).unwrap();
            assert_eq!(decrypted_len, data_size);
            assert_eq!(orig, &data[..decrypted_len], "original and decrypted don't match!");
        }

        #[test]
        fn key_sanity() {
            use std::collections::HashSet;

            let mut set: HashSet<Vec<u8>> = HashSet::with_capacity(10000);

            for _ in 0..10000 {
                let key = super::gen_key();
                assert!(set.insert(key));
            }
        }
    }

    #[cfg(all(feature = "nightly", test))]
    mod bench {
        extern crate test;
        const DATA_SIZE: usize = 1300;

        #[bench]
        fn bench_raw_seal(b: &mut test::Bencher) {
            use ring::aead;
            use ring::aead::{SealingKey, OpeningKey, Algorithm};
            use ring::rand::{SystemRandom, SecureRandom};

            let rng = SystemRandom::new();
            let mut key_bytes = vec![0u8; super::ALGORITHM.key_len()];
            let mut nonce_bytes = vec![0u8; super::ALGORITHM.nonce_len()];
            rng.fill(&mut key_bytes).unwrap();
            let key = SealingKey::new(super::ALGORITHM, &key_bytes).unwrap();

            let data = [1u8; DATA_SIZE];
            let out_suffix_capacity = super::ALGORITHM.max_overhead_len();
            let mut in_out = vec![1u8; data.len() + out_suffix_capacity];

            b.bytes = DATA_SIZE as u64;
            b.iter(|| {
                rng.fill(&mut nonce_bytes).unwrap();
                aead::seal_in_place(&key, &nonce_bytes, &mut in_out,
                                    out_suffix_capacity, &[]).unwrap()
            })
        }

        #[bench]
        fn bench_raw_open(b: &mut test::Bencher) {
            use ring::aead;
            use ring::aead::{SealingKey, OpeningKey, Algorithm};
            use ring::rand::{SystemRandom, SecureRandom};

            let rng = SystemRandom::new();
            let mut key_bytes = vec![0u8; super::ALGORITHM.key_len()];
            let mut nonce_bytes = vec![0u8; super::ALGORITHM.nonce_len()];
            rng.fill(&mut key_bytes).unwrap();
            rng.fill(&mut nonce_bytes).unwrap();
            let key = SealingKey::new(super::ALGORITHM, &key_bytes).unwrap();
            let opening_key = OpeningKey::new(super::ALGORITHM, &key_bytes).unwrap();

            let data = [1u8; DATA_SIZE];
            let out_suffix_capacity = super::ALGORITHM.max_overhead_len();
            let mut in_out = vec![1u8; data.len() + out_suffix_capacity];

            b.bytes = DATA_SIZE as u64;

            let sealed_len = aead::seal_in_place(&key, &nonce_bytes, &mut in_out,
                                                 out_suffix_capacity, &[]).unwrap();
            b.iter(|| aead::open_in_place(&opening_key, &nonce_bytes,
                                               0, &mut in_out, &[]))
        }

        #[bench]
        fn bench_seal(b: &mut test::Bencher) {
            let key = super::gen_key();
            let mut handler = super::Handler::new(&key);
            let mut buf = vec![0u8; super::super::MAX_MESSAGE_SIZE];
            b.bytes = DATA_SIZE as u64;
            b.iter(|| handler.seal(&mut buf, DATA_SIZE))
        }

        #[bench]
        fn bench_open(b: &mut test::Bencher) {
            let key = super::gen_key();
            let mut handler = super::Handler::new(&key);
            let mut buf = vec![0u8; super::super::MAX_MESSAGE_SIZE];
            let sealed_len = handler.seal(&mut buf, DATA_SIZE).unwrap();
            b.bytes = DATA_SIZE as u64;
            b.iter(|| handler.open(&mut buf[..sealed_len]))
        }
    }
}

fn new_udt_socket() -> UdtSocket {
    udt::init();
    let sock = UdtSocket::new(SocketFamily::AFInet, SocketType::Datagram).unwrap();
    sock.setsockopt(UdtOpts::UDP_RCVBUF, UDT_BUF_SIZE).unwrap();
    sock.setsockopt(UdtOpts::UDP_SNDBUF, UDT_BUF_SIZE).unwrap();
    sock
}

fn send(sock: &UdtSocket, key: &aead::SealingKey, buf: &mut [u8], len: usize) -> Result<(), UdtError> {
    unimplemented!();
    // FIXME don't unwrap, create an Error struct that can handle everything
    // if let Ok(sealed_len) = crypto::seal(buf, len, key) {
    //     sock.sendmsg(&buf[..sealed_len]).map(|_| ())
    // } else {
    //     Err(UdtError {
    //         err_code: -1,
    //         err_msg: "encryption failure".into(),
    //     })
    // }
}

fn recv(sock: &UdtSocket, key: &aead::OpeningKey, buf: &mut [u8]) -> Result<usize, UdtError> {
    unimplemented!();
    // let size = try!(sock.recvmsg(buf));
    // crypto::open(&mut buf[..size], key).map_err(|_| {
    //     UdtError {
    //         err_code: -1,
    //         err_msg: String::from("decryption failure"),
    //     }
    // })
}

pub struct PortRange {
    start: u16,
    end: u16,
}

pub trait Transceiver {
    fn send(&self, buf: &[u8]) -> Result<(), UdtError>;
    fn recv(&self, buf: &mut [u8]) -> Result<usize, UdtError>;
    fn close(&self) -> Result<(), UdtError>;
}

pub struct Server {
    pub ip_addr: IpAddr,
    pub port: u16,
    crypto: crypto::Handler,
    sock: UdtSocket,
}

pub struct Client {
    addr: SocketAddr,
    sock: UdtSocket,
    crypto: crypto::Handler,
}

pub struct ServerConnection<'a> {
    crypto: &'a crypto::Handler,
    sock: UdtSocket,
}

impl Client {
    pub fn new(addr: SocketAddr, key: &[u8]) -> Client {
        let sock = new_udt_socket();
        Client {
            addr: addr,
            sock: sock,
            crypto: crypto::Handler::new(key),
        }
    }

    pub fn connect(&self) -> Result<(), UdtError> {
        self.sock.connect(self.addr)
    }
}

impl Transceiver for Client {
    fn send(&self, buf: &[u8]) -> Result<(), UdtError> {
        unimplemented!();
        // send(&self.sock, &self.sealing_key, buf)
    }

    fn recv(&self, buf: &mut [u8]) -> Result<usize, UdtError> {
        unimplemented!();
        // recv(&self.sock, &self.opening_key, buf)
    }

    fn close(&self) -> Result<(), UdtError> {
        self.sock.close()
    }
}

impl Server {
    pub fn get_open_port(range: &PortRange) -> Result<u16, ()> {
        for p in range.start..range.end {
            if let Ok(_) = UdpSocket::bind(&format!("0.0.0.0:{}", p)[..]) {
                return Ok(p);
            }
        }
        Err(())
    }

    pub fn new(ip_addr: IpAddr, port: u16, key: &[u8]) -> Server {
        let sock = new_udt_socket();
        sock.bind(SocketAddr::new(ip_addr, port)).unwrap();
        Server {
            sock: sock,
            ip_addr: ip_addr,
            port: port,
            crypto: crypto::Handler::new(key),
        }
    }

    pub fn listen(&self) -> Result<(), UdtError> {
        self.sock.listen(2)
    }

    pub fn accept(&self) -> Result<ServerConnection, UdtError> {
        self.sock.accept().map(|(sock, _)| {
            ServerConnection {
                crypto: &self.crypto,
                sock: sock,
            }
        })
    }
}

impl<'a> ServerConnection<'a> {
    pub fn getpeer(&self) -> Result<SocketAddr, UdtError> {
        self.sock.getpeername()
    }
}

impl<'a> Transceiver for ServerConnection<'a> {
    fn send(&self, buf: &[u8]) -> Result<(), UdtError> {
        unimplemented!();
        // send(&self.sock, self.key, buf)
    }

    fn recv(&self, buf: &mut [u8]) -> Result<usize, UdtError> {
        unimplemented!();
        // recv(&self.sock, self.key, buf)
    }

    fn close(&self) -> Result<(), UdtError> {
        self.sock.close()
    }
}

impl<'a> PortRange {
    fn new(start: u16, end: u16) -> Result<PortRange, &'a str> {
        if start > end {
            Err("range end must be greater than or equal to start")
        } else {
            Ok(PortRange {
                start: start,
                end: end,
            })
        }
    }

    pub fn from(s: &str) -> Result<PortRange, &'a str> {
        let sections: Vec<&str> = s.split('-').collect();
        if sections.len() != 2 {
            return Err("Range must be specified in the form of \"<start>-<end>\"");
        }
        let (start, end) = (sections[0].parse::<u16>(), sections[1].parse::<u16>());
        if start.is_err() || end.is_err() {
            return Err("improperly formatted port range");
        }
        PortRange::new(start.unwrap(), end.unwrap())
    }
}

impl fmt::Display for PortRange {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}-{}", self.start, self.end)
    }
}
<commit_msg>AES_128_GCM gives *much* better performance (5Gbps on my MBP)<commit_after>extern crate ring;
extern crate udt;

use std::net::{UdpSocket, SocketAddr, IpAddr};
use std::str;
use std::fmt;
use udt::{UdtSocket, UdtError, UdtOpts, SocketType, SocketFamily};
use ring::aead;
use ring::rand;

// TODO config
const UDT_BUF_SIZE: i32 = 4096000;
pub const MAX_MESSAGE_SIZE: usize = 1024000;

pub mod crypto {
    use ring::aead;
    use ring::aead::{SealingKey, OpeningKey, Algorithm};
    use ring::rand::{SystemRandom, SecureRandom};
    static ALGORITHM: &'static Algorithm = &aead::AES_128_GCM;

    pub struct Handler {
        _working_nonce_buf: [u8; 32],
        _working_seal_buf: [u8; super::MAX_MESSAGE_SIZE],
        rand: SystemRandom,
        opening_key: OpeningKey,
        sealing_key: SealingKey,
    }

    pub fn gen_key() -> Vec<u8> {
        let rand = SystemRandom::new();
        let mut keybytes = vec![0u8; ALGORITHM.key_len()];
        rand.fill(&mut keybytes);
        keybytes
    }

    impl Handler {
        pub fn new(key: &[u8]) -> Handler {
            Handler {
                _working_seal_buf: [0u8; super::MAX_MESSAGE_SIZE],
                _working_nonce_buf: [0u8; 32],
                rand: SystemRandom::new(),
                opening_key: aead::OpeningKey::new(ALGORITHM, key).unwrap(),
                sealing_key: aead::SealingKey::new(ALGORITHM, key).unwrap(),
            }
        }

        pub fn seal(&mut self, buf: &mut [u8], len: usize) -> Result<usize, ()> {
            let nonce_len = ALGORITHM.nonce_len();
            let max_suffix_len = ALGORITHM.max_overhead_len();

            assert!(nonce_len < u8::max_value() as usize,
                    "Uh, why is the nonce size this big?");

            assert!(len <= buf.len() - max_suffix_len,
                    "Buffer doesn't have enough suffix padding.");

            let mut nonce = &mut self._working_nonce_buf[..nonce_len];
            self.rand.fill(&mut nonce).unwrap();

            let mut sealed = &mut self._working_seal_buf[..len + max_suffix_len];
            sealed[0..len].copy_from_slice(&buf[..len]);
            match aead::seal_in_place(&self.sealing_key,
                                      &nonce,
                                      &mut sealed,
                                      max_suffix_len,
                                      &[]) {
                Ok(seal_len) => {
                    buf[..nonce_len].copy_from_slice(&nonce[..]);
                    buf[nonce_len..nonce_len+seal_len].copy_from_slice(&sealed[..seal_len]);
                    Ok(nonce_len + seal_len)
                }
                Err(e) => {
                    Err(())
                }
            }
        }

        pub fn open(&mut self, buf: &mut [u8]) -> Result<usize, String> {
            let nonce_len = ALGORITHM.nonce_len();

            if buf.len() < nonce_len {
                return Err("msg not long enough to contain nonce".into());
            } else if buf.len() > super::MAX_MESSAGE_SIZE {
                return Err("max message size exceeded".into());
            }

            let nonce = &mut self._working_nonce_buf[..nonce_len];
            nonce.copy_from_slice(&buf[..nonce_len]);

            aead::open_in_place(&self.opening_key, &nonce, nonce_len, buf, &[])
                .map_err(|_| String::from("decrypt failed"))
        }
    }

    // Tests for the crypto module
    #[cfg(test)]
    mod test {

        #[test]
        fn raw_roundtrip() {
            use ring::aead;
            use ring::aead::{SealingKey, OpeningKey, Algorithm};
            use ring::rand::{SystemRandom, SecureRandom};

            let rng = SystemRandom::new();
            let mut key_bytes = vec![0u8; super::ALGORITHM.key_len()];
            let mut nonce_bytes = vec![0u8; super::ALGORITHM.nonce_len()];
            rng.fill(&mut key_bytes).unwrap();
            rng.fill(&mut nonce_bytes).unwrap();
            let key = SealingKey::new(super::ALGORITHM, &key_bytes).unwrap();

            let data = [1u8; 1350];
            let out_suffix_capacity = super::ALGORITHM.max_overhead_len();
            let mut in_out = vec![1u8; data.len() + out_suffix_capacity];
            aead::seal_in_place(&key, &nonce_bytes,
                                &mut in_out, out_suffix_capacity,
                                &[]).unwrap();

            let opening_key = OpeningKey::new(super::ALGORITHM, &key_bytes).unwrap();
            let len = aead::open_in_place(&opening_key, &nonce_bytes,
                                          0, &mut in_out, &[]).unwrap();

            assert_eq!(len, 1350);
            assert_eq!(&in_out[..len], &data[..]);
        }

        #[test]
        fn roundtrip() {
            use ::rand;
            use ::rand::distributions::{IndependentSample, Range};
            // generate some data, seal it, and then make sure it unseals to the same thing
            let mut rng = rand::thread_rng();
            let between = Range::new(10, 10000);

            let key = super::gen_key();
            let mut handler = super::Handler::new(&key);
            let data_size: usize = between.ind_sample(&mut rng);
            let mut data = vec![0u8; super::super::MAX_MESSAGE_SIZE];
            for i in 0..data_size {
                data[i] = rand::random();
            }

            let orig = data[..data_size].to_owned();

            let cipher_len = handler.seal(&mut data, data_size).unwrap();
            let decrypted_len = handler.open(&mut data[..cipher_len]).unwrap();
            assert_eq!(decrypted_len, data_size);
            assert_eq!(orig, &data[..decrypted_len], "original and decrypted don't match!");
        }

        #[test]
        fn key_sanity() {
            use std::collections::HashSet;

            let mut set: HashSet<Vec<u8>> = HashSet::with_capacity(10000);

            for _ in 0..10000 {
                let key = super::gen_key();
                assert!(set.insert(key));
            }
        }
    }

    #[cfg(all(feature = "nightly", test))]
    mod bench {
        extern crate test;
        const DATA_SIZE: usize = 1300;

        #[bench]
        fn bench_raw_seal(b: &mut test::Bencher) {
            use ring::aead;
            use ring::aead::{SealingKey, OpeningKey, Algorithm};
            use ring::rand::{SystemRandom, SecureRandom};

            let rng = SystemRandom::new();
            let mut key_bytes = vec![0u8; super::ALGORITHM.key_len()];
            let mut nonce_bytes = vec![0u8; super::ALGORITHM.nonce_len()];
            rng.fill(&mut key_bytes).unwrap();
            let key = SealingKey::new(super::ALGORITHM, &key_bytes).unwrap();

            let data = [1u8; DATA_SIZE];
            let out_suffix_capacity = super::ALGORITHM.max_overhead_len();
            let mut in_out = vec![1u8; data.len() + out_suffix_capacity];

            b.bytes = DATA_SIZE as u64;
            b.iter(|| {
                rng.fill(&mut nonce_bytes).unwrap();
                aead::seal_in_place(&key, &nonce_bytes, &mut in_out,
                                    out_suffix_capacity, &[]).unwrap()
            })
        }

        #[bench]
        fn bench_raw_open(b: &mut test::Bencher) {
            use ring::aead;
            use ring::aead::{SealingKey, OpeningKey, Algorithm};
            use ring::rand::{SystemRandom, SecureRandom};

            let rng = SystemRandom::new();
            let mut key_bytes = vec![0u8; super::ALGORITHM.key_len()];
            let mut nonce_bytes = vec![0u8; super::ALGORITHM.nonce_len()];
            rng.fill(&mut key_bytes).unwrap();
            rng.fill(&mut nonce_bytes).unwrap();
            let key = SealingKey::new(super::ALGORITHM, &key_bytes).unwrap();
            let opening_key = OpeningKey::new(super::ALGORITHM, &key_bytes).unwrap();

            let data = [1u8; DATA_SIZE];
            let out_suffix_capacity = super::ALGORITHM.max_overhead_len();
            let mut in_out = vec![1u8; data.len() + out_suffix_capacity];

            b.bytes = DATA_SIZE as u64;

            let sealed_len = aead::seal_in_place(&key, &nonce_bytes, &mut in_out,
                                                 out_suffix_capacity, &[]).unwrap();
            b.iter(|| aead::open_in_place(&opening_key, &nonce_bytes,
                                               0, &mut in_out, &[]))
        }

        #[bench]
        fn bench_seal(b: &mut test::Bencher) {
            let key = super::gen_key();
            let mut handler = super::Handler::new(&key);
            let mut buf = vec![0u8; super::super::MAX_MESSAGE_SIZE];
            b.bytes = DATA_SIZE as u64;
            b.iter(|| handler.seal(&mut buf, DATA_SIZE))
        }

        #[bench]
        fn bench_open(b: &mut test::Bencher) {
            let key = super::gen_key();
            let mut handler = super::Handler::new(&key);
            let mut buf = vec![0u8; super::super::MAX_MESSAGE_SIZE];
            let sealed_len = handler.seal(&mut buf, DATA_SIZE).unwrap();
            b.bytes = DATA_SIZE as u64;
            b.iter(|| handler.open(&mut buf[..sealed_len]))
        }
    }
}

fn new_udt_socket() -> UdtSocket {
    udt::init();
    let sock = UdtSocket::new(SocketFamily::AFInet, SocketType::Datagram).unwrap();
    sock.setsockopt(UdtOpts::UDP_RCVBUF, UDT_BUF_SIZE).unwrap();
    sock.setsockopt(UdtOpts::UDP_SNDBUF, UDT_BUF_SIZE).unwrap();
    sock
}

fn send(sock: &UdtSocket, key: &aead::SealingKey, buf: &mut [u8], len: usize) -> Result<(), UdtError> {
    unimplemented!();
    // FIXME don't unwrap, create an Error struct that can handle everything
    // if let Ok(sealed_len) = crypto::seal(buf, len, key) {
    //     sock.sendmsg(&buf[..sealed_len]).map(|_| ())
    // } else {
    //     Err(UdtError {
    //         err_code: -1,
    //         err_msg: "encryption failure".into(),
    //     })
    // }
}

fn recv(sock: &UdtSocket, key: &aead::OpeningKey, buf: &mut [u8]) -> Result<usize, UdtError> {
    unimplemented!();
    // let size = try!(sock.recvmsg(buf));
    // crypto::open(&mut buf[..size], key).map_err(|_| {
    //     UdtError {
    //         err_code: -1,
    //         err_msg: String::from("decryption failure"),
    //     }
    // })
}

pub struct PortRange {
    start: u16,
    end: u16,
}

pub trait Transceiver {
    fn send(&self, buf: &[u8]) -> Result<(), UdtError>;
    fn recv(&self, buf: &mut [u8]) -> Result<usize, UdtError>;
    fn close(&self) -> Result<(), UdtError>;
}

pub struct Server {
    pub ip_addr: IpAddr,
    pub port: u16,
    crypto: crypto::Handler,
    sock: UdtSocket,
}

pub struct Client {
    addr: SocketAddr,
    sock: UdtSocket,
    crypto: crypto::Handler,
}

pub struct ServerConnection<'a> {
    crypto: &'a crypto::Handler,
    sock: UdtSocket,
}

impl Client {
    pub fn new(addr: SocketAddr, key: &[u8]) -> Client {
        let sock = new_udt_socket();
        Client {
            addr: addr,
            sock: sock,
            crypto: crypto::Handler::new(key),
        }
    }

    pub fn connect(&self) -> Result<(), UdtError> {
        self.sock.connect(self.addr)
    }
}

impl Transceiver for Client {
    fn send(&self, buf: &[u8]) -> Result<(), UdtError> {
        unimplemented!();
        // send(&self.sock, &self.sealing_key, buf)
    }

    fn recv(&self, buf: &mut [u8]) -> Result<usize, UdtError> {
        unimplemented!();
        // recv(&self.sock, &self.opening_key, buf)
    }

    fn close(&self) -> Result<(), UdtError> {
        self.sock.close()
    }
}

impl Server {
    pub fn get_open_port(range: &PortRange) -> Result<u16, ()> {
        for p in range.start..range.end {
            if let Ok(_) = UdpSocket::bind(&format!("0.0.0.0:{}", p)[..]) {
                return Ok(p);
            }
        }
        Err(())
    }

    pub fn new(ip_addr: IpAddr, port: u16, key: &[u8]) -> Server {
        let sock = new_udt_socket();
        sock.bind(SocketAddr::new(ip_addr, port)).unwrap();
        Server {
            sock: sock,
            ip_addr: ip_addr,
            port: port,
            crypto: crypto::Handler::new(key),
        }
    }

    pub fn listen(&self) -> Result<(), UdtError> {
        self.sock.listen(2)
    }

    pub fn accept(&self) -> Result<ServerConnection, UdtError> {
        self.sock.accept().map(|(sock, _)| {
            ServerConnection {
                crypto: &self.crypto,
                sock: sock,
            }
        })
    }
}

impl<'a> ServerConnection<'a> {
    pub fn getpeer(&self) -> Result<SocketAddr, UdtError> {
        self.sock.getpeername()
    }
}

impl<'a> Transceiver for ServerConnection<'a> {
    fn send(&self, buf: &[u8]) -> Result<(), UdtError> {
        unimplemented!();
        // send(&self.sock, self.key, buf)
    }

    fn recv(&self, buf: &mut [u8]) -> Result<usize, UdtError> {
        unimplemented!();
        // recv(&self.sock, self.key, buf)
    }

    fn close(&self) -> Result<(), UdtError> {
        self.sock.close()
    }
}

impl<'a> PortRange {
    fn new(start: u16, end: u16) -> Result<PortRange, &'a str> {
        if start > end {
            Err("range end must be greater than or equal to start")
        } else {
            Ok(PortRange {
                start: start,
                end: end,
            })
        }
    }

    pub fn from(s: &str) -> Result<PortRange, &'a str> {
        let sections: Vec<&str> = s.split('-').collect();
        if sections.len() != 2 {
            return Err("Range must be specified in the form of \"<start>-<end>\"");
        }
        let (start, end) = (sections[0].parse::<u16>(), sections[1].parse::<u16>());
        if start.is_err() || end.is_err() {
            return Err("improperly formatted port range");
        }
        PortRange::new(start.unwrap(), end.unwrap())
    }
}

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


<commit_before>use num::{BigUint, One, Zero};

const BITS: usize = 255;
const A24: u32 = 121665;

/// This is horrible
/// and insecure
pub fn x_25519(k: &[u8], u: &[u8]) -> Vec<u8> {
    assert_eq!(32, k.len());
    assert_eq!((BITS + 7) / 8, u.len());
    let k = decode_scalar(k);
    let x_1 = decode_u_coordinate(u);
    let mut x_2 = One::one();
    let mut z_2 = Zero::zero();
    let mut x_3 = x_1.clone();
    let mut z_3 = One::one();
    let mut swap = Zero::zero();
    let a24: BigUint = A24.into();
    let p: BigUint = (BigUint::from(1u8) << 255) - BigUint::from(19u8);

    for t in (0..BITS).rev() {
        let k_t = (&k >> t) & BigUint::from(1u8);
        swap = swap ^ &k_t;
        cswap(&swap, &mut x_2, &mut x_3);
        cswap(&swap, &mut z_2, &mut z_3);
        swap = k_t;

        let a = (&x_2 + &z_2) % &p;
        let aa = &a * &a % &p;
        let b = (&p + &x_2 - &z_2) % &p;
        let bb = &b * &b % &p;
        let e = (&p + &aa - &bb) % &p;
        let c = (&x_3 + &z_3) % &p;
        let d = (&p + &x_3 - &z_3) % &p;
        let da = d * a % &p;
        let cb = c * b % &p;
        x_3 = (&da + &cb) % &p;
        x_3 = &x_3 * &x_3 % &p;
        z_3 = (&p + da - cb) % &p;
        z_3 = &x_1 * &z_3 * &z_3 % &p;
        x_2 = &aa * bb % &p;
        z_2 = &e * (aa + &a24 * &e) % &p;
    }
    cswap(&swap, &mut x_2, &mut x_3);
    cswap(&swap, &mut z_2, &mut z_3);
    (x_2 * pow(z_2, &p) % &p).to_bytes_le()
}

fn decode_u_coordinate(u: &[u8]) -> BigUint {
    let mut u_vec = u.to_vec();
    if BITS % 8 != 0 {
        if let Some(last) = u_vec.last_mut() {
            *last &= (1 << (BITS % 8)) - 1;
        }
    }
    BigUint::from_bytes_le(&u_vec)
}

fn decode_scalar(k: &[u8]) -> BigUint {
    let mut k_vec = k.to_vec();
    k_vec[0] &= 248;
    k_vec[31] &= 127;
    k_vec[31] |= 64;
    BigUint::from_bytes_le(&k_vec)
}

fn cswap(swap: &BigUint, x_2: &mut BigUint, x_3: &mut BigUint) {
    let dummy = mask(swap) & (&*x_2 ^ &*x_3);
    *x_2 = &*x_2 ^ &dummy;
    *x_3 = &*x_3 ^ &dummy;
}

fn mask(swap: &BigUint) -> BigUint {
    (BigUint::from(1u8) << 255) - swap
}

fn pow(z: BigUint, p: &BigUint) -> BigUint {
    let two: BigUint = 2u8.into();
    let mut res: BigUint = One::one();
    let mut base = z;
    let mut exponent = p - &two;
    while exponent > Zero::zero() {
        if &exponent % &two == One::one() {
            res = res * &base % p;
        }
        exponent = exponent >> 1;
        base = &base * &base % p;
    }
    res
}

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

    #[test]
    fn test_x_25519() {
        let k = h2b(
            "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
        );
        let u = h2b(
            "e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c",
        );
        let x = h2b(
            "c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552",
        );
        assert_eq!(x, x_25519(&k, &u));
    }
}
<commit_msg>curve25519: x_25519 -> x25519<commit_after>use num::{BigUint, One, Zero};

const BITS: usize = 255;
const A24: u32 = 121665;

/// This is horrible
/// and insecure
pub fn x25519(k: &[u8], u: &[u8]) -> Vec<u8> {
    assert_eq!(32, k.len());
    assert_eq!((BITS + 7) / 8, u.len());
    let k = decode_scalar(k);
    let x_1 = decode_u_coordinate(u);
    let mut x_2 = One::one();
    let mut z_2 = Zero::zero();
    let mut x_3 = x_1.clone();
    let mut z_3 = One::one();
    let mut swap = Zero::zero();
    let a24: BigUint = A24.into();
    let p: BigUint = (BigUint::from(1u8) << 255) - BigUint::from(19u8);

    for t in (0..BITS).rev() {
        let k_t = (&k >> t) & BigUint::from(1u8);
        swap = swap ^ &k_t;
        cswap(&swap, &mut x_2, &mut x_3);
        cswap(&swap, &mut z_2, &mut z_3);
        swap = k_t;

        let a = (&x_2 + &z_2) % &p;
        let aa = &a * &a % &p;
        let b = (&p + &x_2 - &z_2) % &p;
        let bb = &b * &b % &p;
        let e = (&p + &aa - &bb) % &p;
        let c = (&x_3 + &z_3) % &p;
        let d = (&p + &x_3 - &z_3) % &p;
        let da = d * a % &p;
        let cb = c * b % &p;
        x_3 = (&da + &cb) % &p;
        x_3 = &x_3 * &x_3 % &p;
        z_3 = (&p + da - cb) % &p;
        z_3 = &x_1 * &z_3 * &z_3 % &p;
        x_2 = &aa * bb % &p;
        z_2 = &e * (aa + &a24 * &e) % &p;
    }
    cswap(&swap, &mut x_2, &mut x_3);
    cswap(&swap, &mut z_2, &mut z_3);
    (x_2 * pow(z_2, &p) % &p).to_bytes_le()
}

fn decode_u_coordinate(u: &[u8]) -> BigUint {
    let mut u_vec = u.to_vec();
    if BITS % 8 != 0 {
        if let Some(last) = u_vec.last_mut() {
            *last &= (1 << (BITS % 8)) - 1;
        }
    }
    BigUint::from_bytes_le(&u_vec)
}

fn decode_scalar(k: &[u8]) -> BigUint {
    let mut k_vec = k.to_vec();
    k_vec[0] &= 248;
    k_vec[31] &= 127;
    k_vec[31] |= 64;
    BigUint::from_bytes_le(&k_vec)
}

fn cswap(swap: &BigUint, x_2: &mut BigUint, x_3: &mut BigUint) {
    let dummy = mask(swap) & (&*x_2 ^ &*x_3);
    *x_2 = &*x_2 ^ &dummy;
    *x_3 = &*x_3 ^ &dummy;
}

fn mask(swap: &BigUint) -> BigUint {
    (BigUint::from(1u8) << 255) - swap
}

fn pow(z: BigUint, p: &BigUint) -> BigUint {
    let two: BigUint = 2u8.into();
    let mut res: BigUint = One::one();
    let mut base = z;
    let mut exponent = p - &two;
    while exponent > Zero::zero() {
        if &exponent % &two == One::one() {
            res = res * &base % p;
        }
        exponent = exponent >> 1;
        base = &base * &base % p;
    }
    res
}

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

    #[test]
    fn test_x25519() {
        let k = h2b(
            "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
        );
        let u = h2b(
            "e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c",
        );
        let x = h2b(
            "c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552",
        );
        assert_eq!(x, x25519(&k, &u));
    }
}
<|endoftext|>


<commit_before>use std::fmt;

/// A duration decomposed into components.
///
/// `DecomposedTime` is mainly provided for a more human-readable and composable
/// representation of a `FloatDuration`. It may be converted back-and-forth
/// between `FloatDuration` at will.
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct DecomposedTime {
    pub days: u32,
    pub hours: u32,
    pub minutes: u32,
    pub seconds: u32,
    pub fractional_seconds: f64,
    pub sign: i8,
}

impl DecomposedTime {
    pub fn zero() -> DecomposedTime {
        DecomposedTime {
            days: 0,
            hours: 0,
            minutes: 0,
            seconds: 0,
            fractional_seconds: 0.0,
            sign: 1,
        }
    }

    pub fn from_components(days: u32,
                           hours: u32,
                           minutes: u32,
                           seconds: u32,
                           fractional_seconds: f64)
                           -> DecomposedTime {
        DecomposedTime {
            days,
            hours,
            minutes,
            seconds,
            fractional_seconds,
            sign: 1,
        }
    }

    pub fn negate(mut self) -> DecomposedTime {
        self.sign *= -1;
        self
    }
}

impl fmt::Display for DecomposedTime {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        if self.days > 0 {
            write!(fmt, "{}d ", self.days as u64)?;
        }

        if self.sign.is_negative() {
            write!(fmt, "-")?;
        }
        if self.fractional_seconds > 0.0 {
            write!(fmt,
                   "{:02}:{:02}:{}{}",
                   self.hours,
                   self.minutes,
                   if self.seconds < 10 { "0" } else { "" },
                   self.seconds as f64 + self.fractional_seconds)
        } else {
            write!(fmt,
                   "{:02}:{:02}:{:02}",
                   self.hours,
                   self.minutes,
                   self.seconds)
        }
    }
}
<commit_msg>Deleted `decomposed.rs`.<commit_after><|endoftext|>


<commit_before>use std::any::{Any, TypeId};
use std::collections::HashMap;

/// A "type map" used to associate data with pooled connections.
///
/// `Extensions` is a data structure mapping types to a value of that type. This
/// can be used to, for example, cache prepared statements along side their
/// connection.
#[derive(Default)]
pub struct Extensions(HashMap<TypeId, Box<Any + Sync + Send>>);

impl Extensions {
    /// Returns a new, empty `Extensions`.
    #[inline]
    pub fn new() -> Extensions {
        Extensions::default()
    }

    /// Inserts a new value into the map.
    ///
    /// Returns the previously stored value of that type, if present.
    pub fn insert<T>(&mut self, value: T) -> Option<T>
    where
        T: 'static + Sync + Send,
    {
        self.0
            .insert(TypeId::of::<T>(), Box::new(value))
            .and_then(|v| Box::<Any + 'static>::downcast(v).ok())
            .map(|v| *v)
    }

    /// Returns a shared reference to the stored value of the specified type.
    pub fn get<T>(&self) -> Option<&T>
    where
        T: 'static + Sync + Send,
    {
        self.0
            .get(&TypeId::of::<T>())
            .and_then(|v| v.downcast_ref())
    }

    /// Returns a mutable reference to the stored value of the specified type.
    pub fn get_mut<T>(&mut self) -> Option<&mut T>
    where
        T: 'static + Sync + Send,
    {
        self.0
            .get_mut(&TypeId::of::<T>())
            .and_then(|v| v.downcast_mut())
    }

    /// Removes the value of the specified type from the map, returning it.
    pub fn remove<T>(&mut self) -> Option<T>
    where
        T: 'static + Sync + Send,
    {
        self.0
            .remove(&TypeId::of::<T>())
            .and_then(|v| Box::<Any + 'static>::downcast(v).ok())
            .map(|v| *v)
    }

    /// Removes all values from the map.
    #[inline]
    pub fn clear(&mut self) {
        self.0.clear();
    }
}
<commit_msg>Add dyns to trait objects<commit_after>use std::any::{Any, TypeId};
use std::collections::HashMap;

/// A "type map" used to associate data with pooled connections.
///
/// `Extensions` is a data structure mapping types to a value of that type. This
/// can be used to, for example, cache prepared statements along side their
/// connection.
#[derive(Default)]
pub struct Extensions(HashMap<TypeId, Box<dyn Any + Sync + Send>>);

impl Extensions {
    /// Returns a new, empty `Extensions`.
    #[inline]
    pub fn new() -> Extensions {
        Extensions::default()
    }

    /// Inserts a new value into the map.
    ///
    /// Returns the previously stored value of that type, if present.
    pub fn insert<T>(&mut self, value: T) -> Option<T>
    where
        T: 'static + Sync + Send,
    {
        self.0
            .insert(TypeId::of::<T>(), Box::new(value))
            .and_then(|v| Box::<dyn Any + 'static>::downcast(v).ok())
            .map(|v| *v)
    }

    /// Returns a shared reference to the stored value of the specified type.
    pub fn get<T>(&self) -> Option<&T>
    where
        T: 'static + Sync + Send,
    {
        self.0
            .get(&TypeId::of::<T>())
            .and_then(|v| v.downcast_ref())
    }

    /// Returns a mutable reference to the stored value of the specified type.
    pub fn get_mut<T>(&mut self) -> Option<&mut T>
    where
        T: 'static + Sync + Send,
    {
        self.0
            .get_mut(&TypeId::of::<T>())
            .and_then(|v| v.downcast_mut())
    }

    /// Removes the value of the specified type from the map, returning it.
    pub fn remove<T>(&mut self) -> Option<T>
    where
        T: 'static + Sync + Send,
    {
        self.0
            .remove(&TypeId::of::<T>())
            .and_then(|v| Box::<dyn Any + 'static>::downcast(v).ok())
            .map(|v| *v)
    }

    /// Removes all values from the map.
    #[inline]
    pub fn clear(&mut self) {
        self.0.clear();
    }
}
<|endoftext|>


<commit_before>//! Manage SBD messages stored on the fileystem.
//!
//! Messages are stored in a directory hierarchy under a single root directory. Message storage and
//! retrieval are managed by a `Storage` object, which is configured for a single root directory.

use std::fs;
use std::path::{Path, PathBuf};

use glob::glob;

use super::{Message, Result};

const SBD_EXTENSION: &'static str = ".sbd";

/// A structure for managing storing and retriving SBD messages on a filesystem.
pub struct Storage {
    root: PathBuf,
}

/// An interator over the messages in a `Storage`.
pub struct StorageIterator;

impl Storage {
    /// Creates a new storage manager for a given root directory.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use sbd::filesystem::Storage;
    /// let storage = Storage::new("/var/iridium");
    /// ```
    pub fn new<P: AsRef<Path>>(root: P) -> Storage {
        Storage {
            root: root.as_ref().to_path_buf(),
        }
    }

    /// Stores a message on the filesystem.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use sbd::filesystem::Storage;
    /// use sbd::Message;
    /// let message: Message = Default::default();
    /// let storage = Storage::new("/var/iridium");
    /// storage.store(&message);
    /// ```
    pub fn store(&self, message: &Message) -> Result<PathBuf> {
        let mut path_buf = self.root.clone();
        path_buf.push(message.imei());
        path_buf.push(message.time_of_session().format("%y").to_string());
        path_buf.push(message.time_of_session().format("%m").to_string());
        try!(fs::create_dir_all(&path_buf));
        path_buf.push(message.time_of_session().format(&format!("%y%m%d_%H%M%S{}", SBD_EXTENSION)).to_string());
        let mut file = try!(fs::File::create(&path_buf));
        try!(message.write_to(&mut file));
        Ok(path_buf)
    }

    /// Retrieves all messages from the storage.
    ///
    /// Retrieval is just a blind scan of all files with a `.sbd` extension inside the root
    /// directory, which are then parsed into `Messages`.
    ///
    /// # Panics
    ///
    /// Panics if this storage's root directory can't be turned into a glob string.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use sbd::filesystem::Storage;
    /// let storage = Storage::new("/var/iridium");
    /// let messages = storage.retrieve_all().unwrap();
    /// ```
    pub fn retrieve_all(&self) -> Result<Vec<Message>> {
        let mut messages: Vec<Message> = Vec::new();
        let mut path_buf = self.root.clone();
        path_buf.push("**");
        path_buf.push(format!("*{}", SBD_EXTENSION));
        for entry in try!(glob(&path_buf.to_str().unwrap())) {
            messages.push(try!(Message::from_path(try!(entry))));
        }
        messages.sort();
        Ok(messages)
    }
}

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

    use tempdir::TempDir;

    use super::super::Message;

    #[test]
    fn new_storage() {
        Storage::new(TempDir::new("").unwrap().path());
    }

    #[test]
    fn store_message() {
        let storage = Storage::new(TempDir::new("").unwrap().path());
        let message: Message = Default::default();
        let pathbuf = storage.store(&message).unwrap();
        Message::from_path(pathbuf).unwrap();
    }

    #[test]
    fn iterate_over_messages() {
        let storage = Storage::new(TempDir::new("").unwrap().path());
        let message: Message = Default::default();
        storage.store(&message).unwrap();
        let messages = storage.retrieve_all().unwrap();
        assert_eq!(1, messages.len());
    }
}
<commit_msg>Stash while maybe actually getting iterators<commit_after>//! Manage SBD messages stored on the fileystem.
//!
//! Messages are stored in a directory hierarchy under a single root directory. Message storage and
//! retrieval are managed by a `Storage` object, which is configured for a single root directory.

use std::fs;
use std::path::{Path, PathBuf};

use glob::glob;

use super::{Message, Result};

const SBD_EXTENSION: &'static str = ".sbd";

/// A structure for managing storing and retriving SBD messages on a filesystem.
pub struct Storage {
    root: PathBuf,
}

/// An interator over the messages in a `Storage`.
pub struct StorageIterator;

/// The object yielded by a `StorageIterator`.
pub struct StorageEntry;

impl Iterator for StorageIterator {
    type Item = StorageEntry;

    fn next(&mut self) -> Option<Self::Item> {
        None
    }
}

impl<'a> IntoIterator for &'a Storage {
    type Item = StorageEntry;
    type IntoIter = StorageIterator;

    fn into_iter(self) -> Self::IntoIter {
        StorageIterator
    }
}

impl Storage {
    /// Creates a new storage manager for a given root directory.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use sbd::filesystem::Storage;
    /// let storage = Storage::new("/var/iridium");
    /// ```
    pub fn new<P: AsRef<Path>>(root: P) -> Storage {
        Storage {
            root: root.as_ref().to_path_buf(),
        }
    }

    /// Stores a message on the filesystem.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use sbd::filesystem::Storage;
    /// use sbd::Message;
    /// let message: Message = Default::default();
    /// let storage = Storage::new("/var/iridium");
    /// storage.store(&message);
    /// ```
    pub fn store(&self, message: &Message) -> Result<PathBuf> {
        let mut path_buf = self.root.clone();
        path_buf.push(message.imei());
        path_buf.push(message.time_of_session().format("%y").to_string());
        path_buf.push(message.time_of_session().format("%m").to_string());
        try!(fs::create_dir_all(&path_buf));
        path_buf.push(message.time_of_session().format(&format!("%y%m%d_%H%M%S{}", SBD_EXTENSION)).to_string());
        let mut file = try!(fs::File::create(&path_buf));
        try!(message.write_to(&mut file));
        Ok(path_buf)
    }

    pub fn retrieve_all(&self) -> Result<Vec<Message>> {
        let mut messages: Vec<Message> = Vec::new();
        let mut path_buf = self.root.clone();
        path_buf.push("**");
        path_buf.push(format!("*{}", SBD_EXTENSION));
        for entry in try!(glob(&path_buf.to_str().unwrap())) {
            messages.push(try!(Message::from_path(try!(entry))));
        }
        messages.sort();
        Ok(messages)
    }
}

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

    use tempdir::TempDir;

    use super::super::Message;

    #[test]
    fn new_storage() {
        Storage::new(TempDir::new("").unwrap().path());
    }

    #[test]
    fn store_message() {
        let storage = Storage::new(TempDir::new("").unwrap().path());
        let message: Message = Default::default();
        let pathbuf = storage.store(&message).unwrap();
        Message::from_path(pathbuf).unwrap();
    }

    #[test]
    fn iterate_over_messages() {
        let storage = Storage::new(TempDir::new("").unwrap().path());
        let message: Message = Default::default();
        storage.store(&message).unwrap();
        let messages = storage.into_iter().collect::<Vec<StorageEntry>>();
        assert_eq!(1, messages.len());
    }
}
<|endoftext|>


<commit_before>use scene::{Scene, BoxedScene, SceneCommand};
use piston_window::{PistonWindow, UpdateArgs, UpdateEvent, Context, G2d};
//use event::{RenderArgs, UpdateArgs};
//use input::{Button, Key};
//use graphics::Transformed;
//use entity::{Entity, RcEntity};
//use keyhandler::KeyHandler;
use std::cell::RefCell;

#[derive(Clone)]
pub enum CellState {
    Empty,
    Dirt,
    Stone,
    Wall
}

impl CellState {
    pub fn is_passable(&self) -> bool {
        match *self {
            CellState::Empty | CellState::Dirt => true,
            _ => false
        }
    }
}

/*struct World {
    cells: Vec<CellState>,
    entities: Vec<RcEntity>,
    player: RcEntity,
    width: u32,
    height: u32
}

pub struct Adjacents {
    pub top: Option<(CellState, Option<RcEntity>)>,
    pub left: Option<(CellState, Option<RcEntity>)>,
    pub bottom: Option<(CellState, Option<RcEntity>)>,
    pub right: Option<(CellState, Option<RcEntity>)>
}

impl World {
    pub fn new(width: u32, height: u32) -> World {
        let mut entities = vec![];
        let mut cells = vec![CellState::Dirt; (width * height) as usize];
        let player = Entity::new(1,1);
        let borrow = player.clone();
        entities.push(player);
        cells[1] = CellState::Empty;
        cells[width as usize] = CellState::Empty;
        cells[width as usize + 1] = CellState::Empty;
        cells[width as usize + 2] = CellState::Empty;
        cells[(width as usize * 2) + 1] = CellState::Stone;

        World {
            cells: cells,
            entities: entities,
            width: width,
            height: height,
            player: borrow
        }
    }

    pub fn render(&self, context: &graphics::Context, gl: &mut GlGraphics, tick: u64) {
        for entity in self.entities.iter() {
            entity.borrow().render(context, gl, tick);
        }
    }

    pub fn at_pos(&self, x: u32, y: u32) -> (CellState, Option<RcEntity>) {
        let index = x + (y * self.width);
        return (self.cells[index as usize].clone(), None);
    }

    pub fn adjacents(&self, x: u32, y: u32) -> Adjacents {
        let top = if y > 0 {
            Some(self.at_pos(x, y - 1))
        } else {
            None
        };

        let left = if x > 0 {
            Some(self.at_pos(x - 1, y))
        } else {
            None
        };

        let bottom = if y < self.height - 1 {
            Some(self.at_pos(x, y + 1))
        } else {
            None
        };

        let right = if x < self.width - 1 {
            Some(self.at_pos(x + 1, y))
        } else {
            None
        };

        Adjacents{top: top, left: left, bottom: bottom, right: right}
    }

    pub fn set_pos(&mut self, x: u32, y: u32, state: CellState) {
        let index = x + (y * self.width);
        self.cells[index as usize] = state;
    }
}*/

pub struct GameScene {
    quit: bool,
    //world: World,
    //keyhandler: KeyHandler,
    tick: u64,
    next_think: u64,
    camera_pos: (f64, f64)
}

impl GameScene {
    pub fn new() -> BoxedScene {
        Box::new(GameScene {
            quit: false,
            //world: World::new(10, 10),
            //keyhandler: KeyHandler::new(),
            tick: 0,
            next_think: 0,
            camera_pos: (0.0, 0.0)
        })
    }

    /*fn adjust_camera_position(&mut self) {
        let (old_x, old_y) = self.camera_pos;
        let player = self.world.player.borrow();
        self.camera_pos = ((player.x * 32)  as f64, (player.y * 32) as f64);
    }*/

    fn render(&self, context: Context, gl: &mut G2d) {
        const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];
        const BROWN: [f32; 4] = [0.2, 0.2, 0.0, 1.0];
        const GREY: [f32; 4] = [0.2, 0.2, 0.2, 1.0];
        const WHITE: [f32; 4] = [1.0; 4];
        const CELL_SIZE: u32 = 32;

        let (camera_x, camera_y) = self.camera_pos;

        /*let context = &graphics::Context::abs(args.width as f64, args.height as f64)
            .trans(((args.width / 2) - (CELL_SIZE / 2)) as f64, ((args.height / 2) - (CELL_SIZE / 2)) as f64) //Camera is in the centre of the screen
            .trans(-camera_x, -camera_y);

        gl.draw(args.viewport(), |_, gl| {
            graphics::clear(BLACK, gl);
            for (i, cell) in self.world.cells.iter().enumerate() {
                let x = (i as u32 % self.world.width) * CELL_SIZE;
                let y = (i as u32 / self.world.height) * CELL_SIZE;

                match *cell {
                    CellState::Dirt => {
                        graphics::rectangle(BROWN, graphics::rectangle::square(x as f64, y as f64, CELL_SIZE as f64), context.transform, gl);
                    },
                    CellState::Stone => {
                        graphics::rectangle(GREY, graphics::rectangle::square(x as f64, y as f64, CELL_SIZE as f64), context.transform, gl);
                    },
                    CellState::Wall => {
                        graphics::rectangle(WHITE, graphics::rectangle::square(x as f64, y as f64, CELL_SIZE as f64), context.transform, gl);
                    }
                    _ => ()
                }
            };
            self.world.render(context, gl, self.tick);
        });*/

    }

    fn think(&mut self, args: &UpdateArgs) -> Option<SceneCommand> {
        self.tick += (args.dt * 100000.0) as u64;
        //self.keyhandler.think(self.tick);

        if self.tick >= self.next_think {
            self.next_think += 10000;
            {
                //FIXME: Make this use weak references once we have them
                /*let entity = self.world.player.clone();
                let mut entity = entity.borrow_mut();
                //Move existing
                let x = entity.x;
                let y = entity.y;
                entity.think(self.tick, &self.world.adjacents(x, y));

                let x = entity.x;
                let y = entity.y;
                self.world.set_pos(x, y, CellState::Empty);

                //Handle player input
                match self.keyhandler.last_key() {
                    Some((key, tick)) => {
                        let difference = self.tick - tick;
                        if difference < 8000 || difference > 20000 {
                            let x = entity.x;
                            let y = entity.y;
                            entity.input(key, &self.world.adjacents(x, y));
                        }
                    },
                    None => ()
                }*/
            }

            //self.adjust_camera_position();
        }

        if self.quit {
            Some(SceneCommand::PopScene)
        } else {
            None
        }
    }

    /*fn press(&mut self, button: &Button) {
        match button {
            &Button::Keyboard(key) => {
                self.keyhandler.press(key)
            },
            _ => ()
        };
        //self.quit = true;
    }

    fn release(&mut self, button: &Button) {
        match button {
            &Button::Keyboard(key) => {
                self.keyhandler.release(key)
            },
            _ => ()
        };
    }*/
}

impl Scene for GameScene {
    fn handle_event(&mut self, e: &PistonWindow) -> Option<SceneCommand> {
        if let Some(u) = e.update_args() {
            self.think(&u)
        } else {
            e.draw_2d(|context, g| {
                self.render(context, g);
            });
            None
        }
    }
}
<commit_msg>Trying to get things to render again<commit_after>use scene::{Scene, BoxedScene, SceneCommand};
use piston_window::{PistonWindow, UpdateArgs, UpdateEvent, Context, G2d, Transformed};
use piston_window;
//use event::{RenderArgs, UpdateArgs};
//use input::{Button, Key};
//use graphics::Transformed;
//use entity::{Entity, RcEntity};
//use keyhandler::KeyHandler;
use std::cell::RefCell;

#[derive(Clone)]
pub enum CellState {
    Empty,
    Dirt,
    Stone,
    Wall
}

impl CellState {
    pub fn is_passable(&self) -> bool {
        match *self {
            CellState::Empty | CellState::Dirt => true,
            _ => false
        }
    }
}

struct World {
    cells: Vec<CellState>,
    //entities: Vec<RcEntity>,
    //player: RcEntity,
    width: u32,
    height: u32
}

/*pub struct Adjacents {
    pub top: Option<(CellState, Option<RcEntity>)>,
    pub left: Option<(CellState, Option<RcEntity>)>,
    pub bottom: Option<(CellState, Option<RcEntity>)>,
    pub right: Option<(CellState, Option<RcEntity>)>
}*/

impl World {
    pub fn new(width: u32, height: u32) -> World {
        //let mut entities = vec![];
        let mut cells = vec![CellState::Dirt; (width * height) as usize];
        //let player = Entity::new(1,1);
        //let borrow = player.clone();
        //entities.push(player);
        cells[1] = CellState::Empty;
        cells[width as usize] = CellState::Empty;
        cells[width as usize + 1] = CellState::Empty;
        cells[width as usize + 2] = CellState::Empty;
        cells[(width as usize * 2) + 1] = CellState::Stone;

        World {
            cells: cells,
            //entities: entities,
            width: width,
            height: height,
            //player: borrow
        }
    }

    /*pub fn render(&self, context: &graphics::Context, gl: &mut GlGraphics, tick: u64) {
        for entity in self.entities.iter() {
            entity.borrow().render(context, gl, tick);
        }
    }*/

    /*pub fn at_pos(&self, x: u32, y: u32) -> (CellState, Option<RcEntity>) {
        let index = x + (y * self.width);
        return (self.cells[index as usize].clone(), None);
    }*/

    /*pub fn adjacents(&self, x: u32, y: u32) -> Adjacents {
        let top = if y > 0 {
            Some(self.at_pos(x, y - 1))
        } else {
            None
        };

        let left = if x > 0 {
            Some(self.at_pos(x - 1, y))
        } else {
            None
        };

        let bottom = if y < self.height - 1 {
            Some(self.at_pos(x, y + 1))
        } else {
            None
        };

        let right = if x < self.width - 1 {
            Some(self.at_pos(x + 1, y))
        } else {
            None
        };

        Adjacents{top: top, left: left, bottom: bottom, right: right}
    }*/

    pub fn set_pos(&mut self, x: u32, y: u32, state: CellState) {
        let index = x + (y * self.width);
        self.cells[index as usize] = state;
    }
}

pub struct GameScene {
    quit: bool,
    world: World,
    //keyhandler: KeyHandler,
    tick: u64,
    next_think: u64,
    camera_pos: (f64, f64)
}

impl GameScene {
    pub fn new() -> BoxedScene {
        Box::new(GameScene {
            quit: false,
            world: World::new(10, 10),
            //keyhandler: KeyHandler::new(),
            tick: 0,
            next_think: 0,
            camera_pos: (0.0, 0.0)
        })
    }

    /*fn adjust_camera_position(&mut self) {
        let (old_x, old_y) = self.camera_pos;
        let player = self.world.player.borrow();
        self.camera_pos = ((player.x * 32)  as f64, (player.y * 32) as f64);
    }*/

    fn render(&self, context: Context, gl: &mut G2d) {
        const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];
        const BROWN: [f32; 4] = [0.2, 0.2, 0.0, 1.0];
        const GREY: [f32; 4] = [0.2, 0.2, 0.2, 1.0];
        const WHITE: [f32; 4] = [1.0; 4];
        const CELL_SIZE: u32 = 32;

        let (camera_x, camera_y) = self.camera_pos;
        piston_window::clear(BLACK, gl);
        let size = context.get_view_size();
        let width = size[0];
        let height = size[1];

        let context = context
            .trans(((width as u64 / 2) - (CELL_SIZE as u64 / 2)) as f64, ((height as u64 / 2) - (CELL_SIZE as u64 / 2)) as f64) //Camera is in the centre of the screen
            .trans(-camera_x, -camera_y);

        for (i, cell) in self.world.cells.iter().enumerate() {
            let x = (i as u32 % self.world.width) * CELL_SIZE;
            let y = (i as u32 / self.world.height) * CELL_SIZE;

            match *cell {
                CellState::Dirt => {
                    piston_window::rectangle(BROWN, piston_window::rectangle::square(x as f64, y as f64, CELL_SIZE as f64), context.transform, gl);
                },
                CellState::Stone => {
                    piston_window::rectangle(GREY, piston_window::rectangle::square(x as f64, y as f64, CELL_SIZE as f64), context.transform, gl);
                },
                CellState::Wall => {
                    piston_window::rectangle(WHITE, piston_window::rectangle::square(x as f64, y as f64, CELL_SIZE as f64), context.transform, gl);
                }
                _ => ()
            }
        };
        //self.world.render(context, gl, self.tick);

    }

    fn think(&mut self, args: &UpdateArgs) -> Option<SceneCommand> {
        self.tick += (args.dt * 100000.0) as u64;
        //self.keyhandler.think(self.tick);

        if self.tick >= self.next_think {
            self.next_think += 10000;
            {
                //FIXME: Make this use weak references once we have them
                /*let entity = self.world.player.clone();
                let mut entity = entity.borrow_mut();
                //Move existing
                let x = entity.x;
                let y = entity.y;
                entity.think(self.tick, &self.world.adjacents(x, y));

                let x = entity.x;
                let y = entity.y;
                self.world.set_pos(x, y, CellState::Empty);

                //Handle player input
                match self.keyhandler.last_key() {
                    Some((key, tick)) => {
                        let difference = self.tick - tick;
                        if difference < 8000 || difference > 20000 {
                            let x = entity.x;
                            let y = entity.y;
                            entity.input(key, &self.world.adjacents(x, y));
                        }
                    },
                    None => ()
                }*/
            }

            //self.adjust_camera_position();
        }

        if self.quit {
            Some(SceneCommand::PopScene)
        } else {
            None
        }
    }

    /*fn press(&mut self, button: &Button) {
        match button {
            &Button::Keyboard(key) => {
                self.keyhandler.press(key)
            },
            _ => ()
        };
        //self.quit = true;
    }

    fn release(&mut self, button: &Button) {
        match button {
            &Button::Keyboard(key) => {
                self.keyhandler.release(key)
            },
            _ => ()
        };
    }*/
}

impl Scene for GameScene {
    fn handle_event(&mut self, e: &PistonWindow) -> Option<SceneCommand> {
        if let Some(u) = e.update_args() {
            self.think(&u)
        } else {
            e.draw_2d(|context, g| {
                self.render(context, g);
            });
            None
        }
    }
}
<|endoftext|>


<commit_before>use interpreter::{LispValue, EvalResult, Int, Float, Cons, Nil, Bool};
use std::rc::Rc;

// add function - exposed as (+) to Lisp
pub fn add(params: Vec<Rc<LispValue>>) -> EvalResult {
    params.into_iter()
        .fold(Ok(Int(0)), |a, b| {
            match a {
                Ok(acc) => match (acc, b.deref()) {
                    (Int(r), &Int(a)) => Ok(Int(r + a)),
                    (Int(r), &Float(a)) => Ok(Float((r as f64) + a)),
                    (Float(r), &Int(a)) => Ok(Float(r + (a as f64))),
                    (Float(r), &Float(a)) => Ok(Float(r + a)),
                    (_, ref rb) => Err(format!("Wrong type: {}", rb))
                },
                Err(e) => Err(e)
            }
        })
        .map(|e| Rc::new(e))
}

// subtraction function - exposed as (-) to Lisp
pub fn sub(params: Vec<Rc<LispValue>>) -> EvalResult {
    if params.len() == 0 {
        return Err("Incorrect number of parameters".to_string());
    }
    let initial = match params[0].deref() {
        &Int(r) => Int(r),
        &Float(r) => Float(r),
        e => return Err(format!("Wrong type: {}", e))
    };
    params.into_iter()
        .skip(1)
        .fold(Ok(initial), |a, b| {
            match a {
                Ok(acc) => match (acc, b.deref()) {
                    (Int(r), &Int(a)) => Ok(Int(r - a)),
                    (Int(r), &Float(a)) => Ok(Float((r as f64) - a)),
                    (Float(r), &Int(a)) => Ok(Float(r - (a as f64))),
                    (Float(r), &Float(a)) => Ok(Float(r - a)),
                    (_, ref rb) => Err(format!("Wrong type: {}", rb))
                },
                Err(e) => Err(e)
            }
        })
        .map(|e| Rc::new(e))
}

// multiplication function - exposed as (*) to Lisp
pub fn mul(params: Vec<Rc<LispValue>>) -> EvalResult {
    params.into_iter()
        .fold(Ok(Int(1)), |a, b| {
            match a {
                Ok(acc) => match (acc, b.deref()) {
                    (Int(r), &Int(a)) => Ok(Int(r * a)),
                    (Int(r), &Float(a)) => Ok(Float((r as f64) * a)),
                    (Float(r), &Int(a)) => Ok(Float(r * (a as f64))),
                    (Float(r), &Float(a)) => Ok(Float(r * a)),
                    (_, ref rb) => Err(format!("Wrong type: {}", rb))
                },
                Err(e) => Err(e)
            }
        })
        .map(|e| Rc::new(e))
}

// division function - exposed as (/) to Lisp
pub fn div(params: Vec<Rc<LispValue>>) -> EvalResult {
    if params.len() == 0 {
        return Err("Incorrect number of parameters".to_string());
    }
    let initial = match params[0].deref() {
        &Int(r) => Int(r),
        &Float(r) => Float(r),
        e => return Err(format!("Wrong type: {}", e))
    };
    params.into_iter()
        .skip(1)
        .fold(Ok(initial), |a, b| {
            match a {
                Ok(acc) => match (acc, b.deref()) {
                    (Int(r), &Int(a)) => if a == 0 { Err(format!("Division by zero")) } else { Ok(Float(r as f32 / a as f32)) },
                    (Int(r), &Float(a)) => if a == 0.0 { Err(format!("Division by zero")) } else { Ok(Float((r as f32) / a)) },
                    (Float(r), &Int(a)) => if a == 0 { Err(format!("Division by zero")) } else { Ok(Float(r / (a as f32))) },
                    (Float(r), &Float(a)) => if a == 0.0 { Err(format!("Division by zero")) } else { Ok(Float(r / a)) },
                    (_, ref rb) => Err(format!("Wrong type: {}", rb))
                },
                Err(e) => Err(e)
            }
        })
        .map(|e| Rc::new(e))
}

// car function - exposed as (car) to Lisp
pub fn car(params: Vec<Rc<LispValue>>) -> EvalResult {
    if params.len() != 1 {
        return Err("Incorrect number of parameters".to_string())
    }
    match params[0].deref() {
        &Cons(ref car, _) => Ok(car.clone()),
        &Nil => Err("Cannot take the car of an empty list".to_string()),
        _ => Err("Cannot take the car of a non-list".to_string())
    }
}

// cdr function - exposed as (cdr) to Lisp
pub fn cdr(params: Vec<Rc<LispValue>>) -> EvalResult {
    if params.len() != 1 {
        return Err("Incorrect number of parameters".to_string())
    }
    match params[0].deref() {
        &Cons(_, ref cdr) => Ok(cdr.clone()),
        &Nil => Err("Cannot take the cdr of an empty list".to_string()),
        _ => Err("Cannot take the cdr of a non-list".to_string())
    }
}

// eq function - exposed as (=) to Lisp.
pub fn eq(params: Vec<Rc<LispValue>>) -> EvalResult {
    if params.len() == 0 {
        return Ok(Rc::new(Bool(true)));
    }
    let first = params[0].clone();
    let res = params.into_iter()
        .fold(true, |a, b| {
            a && b == first
        });
    Ok(Rc::new(Bool(res)))
}

pub fn display(params: Vec<Rc<LispValue>>) -> EvalResult {
    for ref value in params.iter() {
        println!("{}", value);
    }
    Ok(Rc::new(Nil))
}
<commit_msg>f32 -> f64<commit_after>use interpreter::{LispValue, EvalResult, Int, Float, Cons, Nil, Bool};
use std::rc::Rc;

// add function - exposed as (+) to Lisp
pub fn add(params: Vec<Rc<LispValue>>) -> EvalResult {
    params.into_iter()
        .fold(Ok(Int(0)), |a, b| {
            match a {
                Ok(acc) => match (acc, b.deref()) {
                    (Int(r), &Int(a)) => Ok(Int(r + a)),
                    (Int(r), &Float(a)) => Ok(Float((r as f64) + a)),
                    (Float(r), &Int(a)) => Ok(Float(r + (a as f64))),
                    (Float(r), &Float(a)) => Ok(Float(r + a)),
                    (_, ref rb) => Err(format!("Wrong type: {}", rb))
                },
                Err(e) => Err(e)
            }
        })
        .map(|e| Rc::new(e))
}

// subtraction function - exposed as (-) to Lisp
pub fn sub(params: Vec<Rc<LispValue>>) -> EvalResult {
    if params.len() == 0 {
        return Err("Incorrect number of parameters".to_string());
    }
    let initial = match params[0].deref() {
        &Int(r) => Int(r),
        &Float(r) => Float(r),
        e => return Err(format!("Wrong type: {}", e))
    };
    params.into_iter()
        .skip(1)
        .fold(Ok(initial), |a, b| {
            match a {
                Ok(acc) => match (acc, b.deref()) {
                    (Int(r), &Int(a)) => Ok(Int(r - a)),
                    (Int(r), &Float(a)) => Ok(Float((r as f64) - a)),
                    (Float(r), &Int(a)) => Ok(Float(r - (a as f64))),
                    (Float(r), &Float(a)) => Ok(Float(r - a)),
                    (_, ref rb) => Err(format!("Wrong type: {}", rb))
                },
                Err(e) => Err(e)
            }
        })
        .map(|e| Rc::new(e))
}

// multiplication function - exposed as (*) to Lisp
pub fn mul(params: Vec<Rc<LispValue>>) -> EvalResult {
    params.into_iter()
        .fold(Ok(Int(1)), |a, b| {
            match a {
                Ok(acc) => match (acc, b.deref()) {
                    (Int(r), &Int(a)) => Ok(Int(r * a)),
                    (Int(r), &Float(a)) => Ok(Float((r as f64) * a)),
                    (Float(r), &Int(a)) => Ok(Float(r * (a as f64))),
                    (Float(r), &Float(a)) => Ok(Float(r * a)),
                    (_, ref rb) => Err(format!("Wrong type: {}", rb))
                },
                Err(e) => Err(e)
            }
        })
        .map(|e| Rc::new(e))
}

// division function - exposed as (/) to Lisp
pub fn div(params: Vec<Rc<LispValue>>) -> EvalResult {
    if params.len() == 0 {
        return Err("Incorrect number of parameters".to_string());
    }
    let initial = match params[0].deref() {
        &Int(r) => Int(r),
        &Float(r) => Float(r),
        e => return Err(format!("Wrong type: {}", e))
    };
    params.into_iter()
        .skip(1)
        .fold(Ok(initial), |a, b| {
            match a {
                Ok(acc) => match (acc, b.deref()) {
                    (Int(r), &Int(a)) => if a == 0 { Err(format!("Division by zero")) } else { Ok(Float(r as f64 / a as f64)) },
                    (Int(r), &Float(a)) => if a == 0.0 { Err(format!("Division by zero")) } else { Ok(Float((r as f64) / a)) },
                    (Float(r), &Int(a)) => if a == 0 { Err(format!("Division by zero")) } else { Ok(Float(r / (a as f64))) },
                    (Float(r), &Float(a)) => if a == 0.0 { Err(format!("Division by zero")) } else { Ok(Float(r / a)) },
                    (_, ref rb) => Err(format!("Wrong type: {}", rb))
                },
                Err(e) => Err(e)
            }
        })
        .map(|e| Rc::new(e))
}

// car function - exposed as (car) to Lisp
pub fn car(params: Vec<Rc<LispValue>>) -> EvalResult {
    if params.len() != 1 {
        return Err("Incorrect number of parameters".to_string())
    }
    match params[0].deref() {
        &Cons(ref car, _) => Ok(car.clone()),
        &Nil => Err("Cannot take the car of an empty list".to_string()),
        _ => Err("Cannot take the car of a non-list".to_string())
    }
}

// cdr function - exposed as (cdr) to Lisp
pub fn cdr(params: Vec<Rc<LispValue>>) -> EvalResult {
    if params.len() != 1 {
        return Err("Incorrect number of parameters".to_string())
    }
    match params[0].deref() {
        &Cons(_, ref cdr) => Ok(cdr.clone()),
        &Nil => Err("Cannot take the cdr of an empty list".to_string()),
        _ => Err("Cannot take the cdr of a non-list".to_string())
    }
}

// eq function - exposed as (=) to Lisp.
pub fn eq(params: Vec<Rc<LispValue>>) -> EvalResult {
    if params.len() == 0 {
        return Ok(Rc::new(Bool(true)));
    }
    let first = params[0].clone();
    let res = params.into_iter()
        .fold(true, |a, b| {
            a && b == first
        });
    Ok(Rc::new(Bool(res)))
}

pub fn display(params: Vec<Rc<LispValue>>) -> EvalResult {
    for ref value in params.iter() {
        println!("{}", value);
    }
    Ok(Rc::new(Nil))
}
<|endoftext|>


<commit_before>use dbus::arg::{Array};
use dbus::MessageItem;

use super::{DBusFactory, DBusObjPath};

pub fn setup(f: &mut DBusFactory) -> DBusObjPath{
    //let f = Factory::new_fn::<()>();

    // TODO
    // Not working, choking on "1 lifetime parameter" expected for arg to outarg
    // Expanded it myself, seems fine, will have to debug later. For now writing
    // out the boiler plate is not that bad.
    /*
    dbus_interface! {
        path: "/org/way_cooler/pixels";
        name: "org.way_cooler.pixels";

        fn Get() -> success: DBusResult<Array<u32, Vec<u32>>> {
            let result: Vec<MessageItem> = vec![MessageItem::UInt32(5u32)];
            Ok(MessageItem::Array(result, "(u)".into()))
        }
    }
*/

    f.object_path("/org/way_cooler/Pixels", ()).introspectable().add(
        f.interface("org.way_cooler.Pixels", ()).add_m(
            f.method("hello", (), |m| {
                // Also can just return a (&*result).into() (a slice) which IS faster...
                //let result = vec![5u8];
                let result: Vec<MessageItem> = vec![MessageItem::UInt32(5u32)];
                Ok(vec![m.msg.method_return().append((MessageItem::Array(result, "(u)".into())))])
            }).outarg::<Array<u32, Vec<u32>>, _>("success")
        )
    )
}
<commit_msg>Return an array of u32s, not array of struct u32s<commit_after>use dbus::arg::{Array};
use dbus::MessageItem;

use super::{DBusFactory, DBusObjPath};

pub fn setup(f: &mut DBusFactory) -> DBusObjPath{
    //let f = Factory::new_fn::<()>();

    // TODO
    // Not working, choking on "1 lifetime parameter" expected for arg to outarg
    // Expanded it myself, seems fine, will have to debug later. For now writing
    // out the boiler plate is not that bad.
    /*
    dbus_interface! {
        path: "/org/way_cooler/pixels";
        name: "org.way_cooler.pixels";

        fn Get() -> success: DBusResult<Array<u32, Vec<u32>>> {
            let result: Vec<MessageItem> = vec![MessageItem::UInt32(5u32)];
            Ok(MessageItem::Array(result, "(u)".into()))
        }
    }
*/

    f.object_path("/org/way_cooler/Pixels", ()).introspectable().add(
        f.interface("org.way_cooler.Pixels", ()).add_m(
            f.method("hello", (), |m| {
                // Also can just return a (&*result).into() (a slice) which IS faster...
                //let result = vec![5u8];
                let result: Vec<MessageItem> = vec![MessageItem::UInt32(5u32)];
                Ok(vec![m.msg.method_return().append((MessageItem::Array(result, "u".into())))])
            }).outarg::<Array<u32, Vec<u32>>, _>("success")
        )
    )
}
<|endoftext|>