<commit_before>/*! Example IRC bot

    This sample bot uses the library to connect to Freenode, under the nickname "rustirclib###"
    (where ### is a random number). It then joins the channel ##rustirclib, says hello, and prints
    to standard output any messages sent to the channel.

    Any incoming message of the form "rustirclib###: some message" will elicit a generic response.

    Any incoming message of the form "!rustirclib### quit" will cause the bot to shut down.
 */

#[crate_id = "github.com/kballard/rust-irclib#ircbot:0.1"];
#[crate_type = "bin"];

extern mod irc;

use irc::conn::{Conn, Line, Event, IRCCmd, IRCCode, IRCAction};

use std::{rand, str};
use std::rand::Rng;

fn main() {
    let mut opts = irc::conn::Options::new("chat.freenode.net", irc::conn::DefaultPort);

    let nick = format!("rustirclib{}", rand::task_rng().gen_range(100u, 1000u));
    opts.nick = nick.as_slice();
    match irc::conn::connect(opts, handler) {
        Ok(()) => println("Exiting..."),
        Err(err) => println!("Connection error: {}", err)
    }
}

fn handler(conn: &mut Conn, event: Event) {
    match event {
        irc::conn::Connected => println("Connected"),
        irc::conn::Disconnected => println("Disconnected"),
        irc::conn::LineReceived(line) => {
            match line {
                Line{command: IRCCode(1), ..} => {
                    println("Logged in");
                    // we've logged in
                    conn.join(bytes!("##rustirclib"))
                }
                Line{command: IRCCmd(~"JOIN"), args, prefix: Some(prefix) } => {
                    if prefix.nick() != conn.me().nick() {
                        return;
                    }
                    if args.is_empty() {
                        let line = Line{command: IRCCmd(~"JOIN"), args: args, prefix: Some(prefix)};
                        println!("ERROR: Invalid JOIN message received: {}", line_desc(&line));
                        return;
                    }
                    let chan = args[0];
                    conn.privmsg(chan, bytes!("Hello"));
                    let chan = str::from_utf8_opt(chan).unwrap_or("(invalid utf8)");
                    println!("JOINED: {}", chan);
                }
                Line{command: IRCCmd(cmd@~"PRIVMSG"), args, prefix } |
                Line{command: IRCCmd(cmd@~"NOTICE"), args, prefix } => {
                    let (src, dst, msg) = match (args, prefix.is_some()) {
                        ([dst, msg], true) => {
                            (prefix.as_ref().unwrap().nick(), dst, msg)
                        }
                        (args, _) => {
                            let line = Line{command: IRCCmd(cmd), args: args, prefix: prefix};
                            println!("ERROR: Unexpected PRIVMSG line: {}", line_desc(&line));
                            return;
                        }
                    };
                    let dsts = str::from_utf8_opt(dst).unwrap_or("(invalid utf8)");
                    let srcs = str::from_utf8_opt(src).unwrap_or("(invalid utf8)");
                    let msgs = str::from_utf8_opt(msg).unwrap_or("(invalid utf8)");
                    println!("<-- {}({}) {}: {}", cmd, dsts, srcs, msgs);
                    handle_privmsg(conn, msg, src, dst)
                }
                Line{command: IRCAction(dst), args, prefix } => {
                    let (src, msg) = match (args, prefix.is_some()) {
                        ([msg], true) => {
                            (prefix.as_ref().unwrap().nick(), msg)
                        }
                        (args, _) => {
                            let line = Line{command: IRCAction(dst), args: args, prefix: prefix};
                            println!("ERROR: Unexpected ACTION line: {}", line_desc(&line));
                            return;
                        }
                    };
                    let dst = str::from_utf8_opt(dst).unwrap_or("(invalid utf8)");
                    let src = str::from_utf8_opt(src).unwrap_or("(invalid utf8)");
                    let msg = str::from_utf8_opt(msg).unwrap_or("(invalid utf8)");
                    println!("<-- PRIVMSG({}) {} {}", dst, src, msg);
                }
                _ => ()
            }
        }
    }
}

fn handle_privmsg(conn: &mut Conn, msg: &[u8], src: &[u8], dst: &[u8]) {
    enum MsgType<'a> {
        DirectedMessage,
        CommandMessage(&'a [u8]),
        NormalMessage
    }
    let msgtype = {
        let nick = conn.me().nick();
        if msg.starts_with(nick) && msg.slice_from(nick.len()).starts_with(bytes!(": ")) &&
        msg.len() > nick.len() + 2 {
            DirectedMessage
        } else if msg.starts_with(bytes!("!")) && msg.slice_from(1).starts_with(nick) &&
                msg.slice_from(nick.len()+1).starts_with(bytes!(" ")) {
            let args = msg.slice_from(conn.me().nick().len()+2);
            let mut argit = args.split(|&b| b == ' ' as u8).skip_while(|v| v.is_empty());
            match argit.next() {
                Some(arg) => CommandMessage(arg),
                None => CommandMessage(bytes!(""))
            }
        } else {
            NormalMessage
        }
    };
    match msgtype {
        DirectedMessage => {
            let reply = if dst == conn.me().nick() { src } else { dst };
            let msg = src + bytes!(": Hello");
            conn.privmsg(reply, msg);
            let src = str::from_utf8_opt(conn.me().nick()).unwrap_or("(invalid utf8)");
            let reply = str::from_utf8_opt(reply).unwrap_or("(invalid utf8)");
            let msg = str::from_utf8_opt(msg).unwrap_or("(invalid utf8)");
            println!("--> PRIVMSG({}) {}: {}", reply, src, msg);
        }
        CommandMessage(cmd) if cmd == bytes!("quit") => {
            println("Quitting...");
            conn.quit();
        }
        _ => ()
    }
}

fn line_desc(line: &Line) -> ~str {
    let raw = line.to_raw();
    let raws = str::from_utf8_opt(raw);
    raws.map(|s| s.to_owned()).unwrap_or_else(|| format!("{:?}", raw))
}
<commit_msg>Tweak one error message in the example<commit_after>/*! Example IRC bot

    This sample bot uses the library to connect to Freenode, under the nickname "rustirclib###"
    (where ### is a random number). It then joins the channel ##rustirclib, says hello, and prints
    to standard output any messages sent to the channel.

    Any incoming message of the form "rustirclib###: some message" will elicit a generic response.

    Any incoming message of the form "!rustirclib### quit" will cause the bot to shut down.
 */

#[crate_id = "github.com/kballard/rust-irclib#ircbot:0.1"];
#[crate_type = "bin"];

extern mod irc;

use irc::conn::{Conn, Line, Event, IRCCmd, IRCCode, IRCAction};

use std::{rand, str};
use std::rand::Rng;

fn main() {
    let mut opts = irc::conn::Options::new("chat.freenode.net", irc::conn::DefaultPort);

    let nick = format!("rustirclib{}", rand::task_rng().gen_range(100u, 1000u));
    opts.nick = nick.as_slice();
    match irc::conn::connect(opts, handler) {
        Ok(()) => println("Exiting..."),
        Err(err) => println!("Connection error: {}", err)
    }
}

fn handler(conn: &mut Conn, event: Event) {
    match event {
        irc::conn::Connected => println("Connected"),
        irc::conn::Disconnected => println("Disconnected"),
        irc::conn::LineReceived(line) => {
            match line {
                Line{command: IRCCode(1), ..} => {
                    println("Logged in");
                    // we've logged in
                    conn.join(bytes!("##rustirclib"))
                }
                Line{command: IRCCmd(~"JOIN"), args, prefix: Some(prefix) } => {
                    if prefix.nick() != conn.me().nick() {
                        return;
                    }
                    if args.is_empty() {
                        let line = Line{command: IRCCmd(~"JOIN"), args: args, prefix: Some(prefix)};
                        println!("ERROR: Invalid JOIN message received: {}", line_desc(&line));
                        return;
                    }
                    let chan = args[0];
                    conn.privmsg(chan, bytes!("Hello"));
                    let chan = str::from_utf8_opt(chan).unwrap_or("(invalid utf8)");
                    println!("JOINED: {}", chan);
                }
                Line{command: IRCCmd(cmd@~"PRIVMSG"), args, prefix } |
                Line{command: IRCCmd(cmd@~"NOTICE"), args, prefix } => {
                    let (src, dst, msg) = match (args, prefix.is_some()) {
                        ([dst, msg], true) => {
                            (prefix.as_ref().unwrap().nick(), dst, msg)
                        }
                        (args, _) => {
                            print!("ERROR: Unexpected {} line: ", cmd);
                            let line = Line{command: IRCCmd(cmd), args: args, prefix: prefix};
                            println!("{}", line_desc(&line));
                            return;
                        }
                    };
                    let dsts = str::from_utf8_opt(dst).unwrap_or("(invalid utf8)");
                    let srcs = str::from_utf8_opt(src).unwrap_or("(invalid utf8)");
                    let msgs = str::from_utf8_opt(msg).unwrap_or("(invalid utf8)");
                    println!("<-- {}({}) {}: {}", cmd, dsts, srcs, msgs);
                    handle_privmsg(conn, msg, src, dst)
                }
                Line{command: IRCAction(dst), args, prefix } => {
                    let (src, msg) = match (args, prefix.is_some()) {
                        ([msg], true) => {
                            (prefix.as_ref().unwrap().nick(), msg)
                        }
                        (args, _) => {
                            let line = Line{command: IRCAction(dst), args: args, prefix: prefix};
                            println!("ERROR: Unexpected ACTION line: {}", line_desc(&line));
                            return;
                        }
                    };
                    let dst = str::from_utf8_opt(dst).unwrap_or("(invalid utf8)");
                    let src = str::from_utf8_opt(src).unwrap_or("(invalid utf8)");
                    let msg = str::from_utf8_opt(msg).unwrap_or("(invalid utf8)");
                    println!("<-- PRIVMSG({}) {} {}", dst, src, msg);
                }
                _ => ()
            }
        }
    }
}

fn handle_privmsg(conn: &mut Conn, msg: &[u8], src: &[u8], dst: &[u8]) {
    enum MsgType<'a> {
        DirectedMessage,
        CommandMessage(&'a [u8]),
        NormalMessage
    }
    let msgtype = {
        let nick = conn.me().nick();
        if msg.starts_with(nick) && msg.slice_from(nick.len()).starts_with(bytes!(": ")) &&
        msg.len() > nick.len() + 2 {
            DirectedMessage
        } else if msg.starts_with(bytes!("!")) && msg.slice_from(1).starts_with(nick) &&
                msg.slice_from(nick.len()+1).starts_with(bytes!(" ")) {
            let args = msg.slice_from(conn.me().nick().len()+2);
            let mut argit = args.split(|&b| b == ' ' as u8).skip_while(|v| v.is_empty());
            match argit.next() {
                Some(arg) => CommandMessage(arg),
                None => CommandMessage(bytes!(""))
            }
        } else {
            NormalMessage
        }
    };
    match msgtype {
        DirectedMessage => {
            let reply = if dst == conn.me().nick() { src } else { dst };
            let msg = src + bytes!(": Hello");
            conn.privmsg(reply, msg);
            let src = str::from_utf8_opt(conn.me().nick()).unwrap_or("(invalid utf8)");
            let reply = str::from_utf8_opt(reply).unwrap_or("(invalid utf8)");
            let msg = str::from_utf8_opt(msg).unwrap_or("(invalid utf8)");
            println!("--> PRIVMSG({}) {}: {}", reply, src, msg);
        }
        CommandMessage(cmd) if cmd == bytes!("quit") => {
            println("Quitting...");
            conn.quit();
        }
        _ => ()
    }
}

fn line_desc(line: &Line) -> ~str {
    let raw = line.to_raw();
    let raws = str::from_utf8_opt(raw);
    raws.map(|s| s.to_owned()).unwrap_or_else(|| format!("{:?}", raw))
}
<|endoftext|>


<commit_before>use std::{
    fs::{self, File},
    io::{BufRead, BufReader},
    path::Path,
};

use crate::Result;

type VersionFn = fn(&str) -> bool;
const SPLITS: &[(&str, VersionFn)] = &[
    ("https://matrix.org/docs/spec/client_server/", |s| {
        // We cannot include the `#` because for every lib.rs file with spec docs the
        // URL is `../rx.x.x.html`
        s.starts_with("r0.6.1") || s.starts_with("unstable#")
    }),
    ("https://matrix.org/docs/spec/server_server/", |s| {
        s.starts_with("r0.1.4") || s.starts_with("unstable#")
    }),
    ("https://matrix.org/docs/spec/application_service/", |s| {
        s.starts_with("r0.1.2") || s.starts_with("unstable#")
    }),
    ("https://matrix.org/docs/spec/identity_service/", |s| {
        s.starts_with("r0.3.0") || s.starts_with("unstable#")
    }),
    ("https://matrix.org/docs/spec/push_gateway/", |s| {
        s.starts_with("r0.1.1") || s.starts_with("unstable#")
    }),
];

pub(crate) fn check_spec_links(path: &Path) -> Result<()> {
    println!("Checking all Matrix Spec links point to same version...");
    // This is WAY overkill but since there are a few mixed in ruma-common
    // and this would catch any wrong version anywhere it's probably ok
    for (split, version_fn) in SPLITS {
        walk_dirs(path, split, *version_fn)?;
    }
    Ok(())
}

fn walk_dirs(path: &Path, split: &str, version_match: fn(&str) -> bool) -> Result<()> {
    if path.is_dir() {
        for entry in fs::read_dir(path)? {
            let entry = entry?;
            let path = entry.path();
            if path.is_dir() {
                walk_dirs(&path, split, version_match)?;
            } else {
                let mut buf = String::new();
                let mut content = BufReader::new(File::open(&path)?);

                // We can assume a spec link will never overflow to another line
                while content.read_line(&mut buf)? > 0 {
                    // If for some reason a line has 2 spec links
                    for (idx, _) in buf.match_indices(split) {
                        if !version_match(&buf[idx + split.len()..]) {
                            return err(&path, &buf);
                        }
                    }
                    buf.clear();
                }
            }
        }
    }
    Ok(())
}

fn err(path: &Path, snippet: &str) -> Result<()> {
    Err(format!(
        "error: spec URL with wrong version number\nfile: {}\n\nsnippet:\n{}",
        path.display(),
        &snippet[0..25]
    )
    .into())
}
<commit_msg>Check spec links version for v1.1<commit_after>use std::{
    fs::{self, File},
    io::{BufRead, BufReader},
    path::Path,
};

use crate::Result;

type VersionFn = fn(&str) -> bool;
const SPLITS: &[(&str, VersionFn)] = &[
    ("https://matrix.org/docs/spec/client_server/", |s| {
        // We cannot include the `#` because for every lib.rs file with spec docs the
        // URL is `../rx.x.x.html`
        s.starts_with("r0.6.1") || s.starts_with("unstable#")
    }),
    ("https://matrix.org/docs/spec/server_server/", |s| {
        s.starts_with("r0.1.4") || s.starts_with("unstable#")
    }),
    ("https://matrix.org/docs/spec/application_service/", |s| {
        s.starts_with("r0.1.2") || s.starts_with("unstable#")
    }),
    ("https://matrix.org/docs/spec/identity_service/", |s| {
        s.starts_with("r0.3.0") || s.starts_with("unstable#")
    }),
    ("https://matrix.org/docs/spec/push_gateway/", |s| {
        s.starts_with("r0.1.1") || s.starts_with("unstable#")
    }),
    ("https://spec.matrix.org/", |s| s.starts_with("v1.1") || s.starts_with("unstable")),
];

pub(crate) fn check_spec_links(path: &Path) -> Result<()> {
    println!("Checking all Matrix Spec links point to same version...");
    // This is WAY overkill but since there are a few mixed in ruma-common
    // and this would catch any wrong version anywhere it's probably ok
    for (split, version_fn) in SPLITS {
        walk_dirs(path, split, *version_fn)?;
    }
    Ok(())
}

fn walk_dirs(path: &Path, split: &str, version_match: fn(&str) -> bool) -> Result<()> {
    if path.is_dir() {
        for entry in fs::read_dir(path)? {
            let entry = entry?;
            let path = entry.path();
            if path.is_dir() {
                walk_dirs(&path, split, version_match)?;
            } else {
                let mut buf = String::new();
                let mut content = BufReader::new(File::open(&path)?);

                // We can assume a spec link will never overflow to another line
                while content.read_line(&mut buf)? > 0 {
                    // If for some reason a line has 2 spec links
                    for (idx, _) in buf.match_indices(split) {
                        if !version_match(&buf[idx + split.len()..]) {
                            return err(&path, &buf);
                        }
                    }
                    buf.clear();
                }
            }
        }
    }
    Ok(())
}

fn err(path: &Path, snippet: &str) -> Result<()> {
    Err(format!(
        "error: spec URL with wrong version number\nfile: {}\n\nsnippet:\n{}",
        path.display(),
        &snippet[0..25]
    )
    .into())
}
<|endoftext|>


<commit_before>use crate::*;
use futures::future::join;
use serde::Serialize;
use std::fs;
use std::process::Command;
use structopt::StructOpt;

#[derive(Serialize, Debug, Clone, StructOpt)]
pub struct NetworkConfig {
    /// Delay in milliseconds
    #[structopt(long, default_value = "0")]
    pub delay: u64,
    /// Jitter in milliseconds
    #[structopt(long, default_value = "0")]
    pub jitter: u64,
    /// Delay correlation percentage (range: [0.0-100.0])
    #[structopt(long, default_value = "0")]
    pub delay_correlation: f32,
    /// Independent chance of packet loss (range: [0.0-100.0])
    #[structopt(long, default_value = "0")]
    pub random_loss: f32,
    /// Random packet loss correlation (range: [0.0-100.0])
    #[structopt(long, default_value = "0")]
    pub random_loss_correlation: f32,
    /// Network loopback interface.
    #[structopt(long, default_value = "lo")]
    #[serde(skip)]
    pub interface: String,
    /// Rate limit of simulated wire. Defaults to 1Gigabit.
    #[structopt(long, default_value = "1073741824")]
    pub rate_limit_kbps: usize,
}

impl Default for NetworkConfig {
    fn default() -> Self {
        Self {
            delay: 0,
            jitter: 0,
            delay_correlation: 0.0,
            random_loss: 0.0,
            random_loss_correlation: 0.0,
            interface: String::from("lo"),
            rate_limit_kbps: 1073741824,
        }
    }
}

impl NetworkConfig {
    fn reset(&self) {
        Command::new("tc")
            .args(&["qdisc", "del", "dev", self.interface.as_str(), "root"])
            .output()
            .expect("resetting network loopback interface");
    }

    fn apply(&self) {
        let output = Command::new("tc")
            .args(&[
                "qdisc",
                "add",
                "dev",
                &self.interface,
                "root",
                "netem",
                "delay",
                &format!("{}", self.delay / 2 * 1000),
                &format!("{}", self.jitter / 2 * 1000),
                &format!("{}", self.delay_correlation),
                "loss",
                "random",
                &format!("{}%", self.random_loss / 2.),
                &format!("{}%", self.random_loss_correlation),
                "rate",
                &format!("{}kbit", self.rate_limit_kbps),
            ])
            .output()
            .expect("applying delay");
        assert_eq!(
            output.status.code(),
            Some(0),
            "Failure apllying: {:#?}",
            output
        )
    }
}

#[derive(StructOpt)]
pub struct Options {
    #[structopt(flatten)]
    pub network_config: NetworkConfig,
    #[structopt(flatten)]
    pub client_options: client::Options,
    /// Whether to launch a server in this process at the client's expected
    /// server address.
    #[structopt(long)]
    pub start_server: bool,
    #[structopt(long, short = "o")]
    pub output: Option<String>,
}

async fn run_client(options: &Options) -> Result<client::Summary> {
    client::client_main(options.client_options.clone()).await
}

async fn run(options: &Options) -> Result<client::Summary> {
    let server_options = server::Options {
        address: options.client_options.address,
        protocol: options.client_options.protocol,
    };

    let (results, server_result) =
        join(run_client(&options), server::server_main(server_options)).await;

    server_result.and_then(|_| results)
}

pub async fn runner_main(options: Options) -> Result<client::Summary> {
    options.network_config.reset();
    options.network_config.apply();

    let results = run(&options).await;

    options.network_config.reset();

    let results = results?;

    if let Some(output) = options.output {
        let writer = fs::File::create(output)?;
        let mut writer = csv::Writer::from_writer(writer);

        for report in &results.trip_reports {
            writer.serialize(report)?;
        }
    }

    Ok(results)
}
<commit_msg>Allow limiting queue size<commit_after>use crate::*;
use futures::future::join;
use serde::Serialize;
use std::fs;
use std::process::Command;
use structopt::StructOpt;

#[derive(Serialize, Debug, Clone, StructOpt)]
pub struct NetworkConfig {
    /// Delay in milliseconds
    #[structopt(long, default_value = "0")]
    pub delay: u64,
    /// Jitter in milliseconds
    #[structopt(long, default_value = "0")]
    pub jitter: u64,
    /// Delay correlation percentage (range: [0.0-100.0])
    #[structopt(long, default_value = "0")]
    pub delay_correlation: f32,
    /// Independent chance of packet loss (range: [0.0-100.0])
    #[structopt(long, default_value = "0")]
    pub random_loss: f32,
    /// Random packet loss correlation (range: [0.0-100.0])
    #[structopt(long, default_value = "0")]
    pub random_loss_correlation: f32,
    /// Network loopback interface.
    #[structopt(long, default_value = "lo")]
    #[serde(skip)]
    pub interface: String,
    /// Rate limit of simulated wire. Defaults to 1Gigabit.
    #[structopt(long, default_value = "1073741824")]
    pub rate_limit_kbps: usize,
    #[structopt(long, default_value="1000")]
    pub packet_limit: usize,
}

impl Default for NetworkConfig {
    fn default() -> Self {
        Self {
            delay: 0,
            jitter: 0,
            delay_correlation: 0.0,
            random_loss: 0.0,
            random_loss_correlation: 0.0,
            interface: String::from("lo"),
            rate_limit_kbps: 1073741824,
            packet_limit: 1000
        }
    }
}

impl NetworkConfig {
    fn reset(&self) {
        Command::new("tc")
            .args(&["qdisc", "del", "dev", self.interface.as_str(), "root"])
            .output()
            .expect("resetting network loopback interface");
    }

    fn apply(&self) {
        let output = Command::new("tc")
            .args(&[
                "qdisc",
                "add",
                "dev",
                &self.interface,
                "root",
                "netem",
                "delay",
                &format!("{}", self.delay / 2 * 1000),
                &format!("{}", self.jitter / 2 * 1000),
                &format!("{}", self.delay_correlation),
                "loss",
                "random",
                &format!("{}%", self.random_loss / 2.),
                &format!("{}%", self.random_loss_correlation),
                "rate",
                &format!("{}kbit", self.rate_limit_kbps),
                "limit",
                &format!("{}", self.packet_limit / 2)
            ])
            .output()
            .expect("applying delay");
        assert_eq!(
            output.status.code(),
            Some(0),
            "Failure apllying: {:#?}",
            output
        )
    }
}

#[derive(StructOpt)]
pub struct Options {
    #[structopt(flatten)]
    pub network_config: NetworkConfig,
    #[structopt(flatten)]
    pub client_options: client::Options,
    /// Whether to launch a server in this process at the client's expected
    /// server address.
    #[structopt(long)]
    pub start_server: bool,
    #[structopt(long, short = "o")]
    pub output: Option<String>,
}

async fn run_client(options: &Options) -> Result<client::Summary> {
    client::client_main(options.client_options.clone()).await
}

async fn run(options: &Options) -> Result<client::Summary> {
    let server_options = server::Options {
        address: options.client_options.address,
        protocol: options.client_options.protocol,
    };

    let (results, server_result) =
        join(run_client(&options), server::server_main(server_options)).await;

    server_result.and_then(|_| results)
}

pub async fn runner_main(options: Options) -> Result<client::Summary> {
    options.network_config.reset();
    options.network_config.apply();

    let results = run(&options).await;

    options.network_config.reset();

    let results = results?;

    if let Some(output) = options.output {
        let writer = fs::File::create(output)?;
        let mut writer = csv::Writer::from_writer(writer);

        for report in &results.trip_reports {
            writer.serialize(report)?;
        }
    }

    Ok(results)
}
<|endoftext|>


<commit_before>#![feature(test)]
#![feature(i128_type)]

extern crate rand;
extern crate test;
extern crate flat_map;

use std::collections::BTreeMap;
use std::iter::FromIterator;
use flat_map::FlatMap;
use test::Bencher;

type Key = u64;
type Value = u64;

const NUM_KEYS: usize = 2 << 12;
const NUM_VALUES: usize = 1 << 12;

fn flat_map_setup() -> (
    FlatMap<Key, Value>,
    Vec<Key>,
) {
    let num_items = 1 << 25;

    let mut keys = Vec::new();
    let mut key_vals = Vec::with_capacity(num_items);
    for i in 0..NUM_KEYS*NUM_VALUES {
        keys.push(i as u64);
        let value = rand::random::<u64>();
        key_vals.push((i as u64, value))
    }

    let map: FlatMap<_, _> = key_vals.into_iter().collect();
    (map, keys)
}

fn btree_map_setup() -> (
    BTreeMap<Key, Value>,
    Vec<Key>,
) {
    let num_items = 1 << 25;

    let mut keys = Vec::new();
    let mut key_vals = Vec::with_capacity(num_items);
    for i in 0..NUM_KEYS*NUM_VALUES {
        keys.push(i as u64);
        let value = rand::random::<u64>();
        key_vals.push((i as u64, value))
    }

    let map = BTreeMap::from_iter(key_vals);
    (map, keys)
}

#[bench]
fn bench_flat_map_from_iter(b: &mut Bencher) {
    let num_keys = 1 << 10;
    let num_values = 1 << 10;
    let mut keys = Vec::new();
    let mut key_vals = Vec::with_capacity(num_keys * num_values);
    for i in 0..num_keys*num_values {
        keys.push(i as u64);
        let value = rand::random::<u64>();
        key_vals.push((i as u64, value))
    }

    b.iter(|| {
        let map = FlatMap::from_iter(key_vals.clone());
        map
    })
}

#[bench]
fn bench_flat_map_insert(b: &mut Bencher) {
    let (mut map, keys) = flat_map_setup();
    b.iter(|| {
        let i = rand::random::<usize>() % keys.len();
        map.insert(keys[i], rand::random())
    })
}

#[bench]
fn bench_flat_map_get(b: &mut Bencher) {
    let (map, keys) = flat_map_setup();
    b.iter(|| {
        let i = rand::random::<usize>() % keys.len();
        map.get(&keys[i])
    })
}

#[bench]
fn bench_btree_map_from_iter(b: &mut Bencher) {
    let num_keys = 1 << 10;
    let num_values = 1 << 10;
    let mut keys = Vec::new();
    let mut key_vals = Vec::with_capacity(num_keys * num_values);
    for i in 0..num_keys*num_values {
        keys.push(i as u64);
        let value = rand::random::<u64>();
        key_vals.push((i as u64, value))
    }

    b.iter(|| {
        let map = BTreeMap::from_iter(key_vals.clone());
        map
    })
}

#[bench]
fn bench_btree_map_insert(b: &mut Bencher) {
    let (mut map, keys) = btree_map_setup();
    b.iter(|| {
        let i = rand::random::<usize>() % keys.len();
        map.insert(keys[i], rand::random())
    })
}

#[bench]
fn bench_btree_map_get(b: &mut Bencher) {
    let (map, keys) = btree_map_setup();
    b.iter(|| {
        let i = rand::random::<usize>() % keys.len();
        map.get(&keys[i])
    })
}
<commit_msg>improve benchmarks, reduce random noise<commit_after>#![feature(test)]
#![feature(i128_type)]

extern crate rand;
extern crate test;
extern crate flat_map;

use std::collections::BTreeMap;
use std::iter::FromIterator;
use flat_map::FlatMap;
use test::Bencher;
use rand::Rng;
use rand::distributions::{IndependentSample, Range};

type Key = u64;
type Value = u64;

const NUM_KEYS: usize = 2 << 12;
const NUM_VALUES: usize = 1 << 12;

fn flat_map_setup() -> (
    FlatMap<Key, Value>,
    Vec<Key>,
) {
    let num_items = 1 << 25;
    let mut keys = Vec::new();
    let mut key_vals = Vec::with_capacity(num_items);
    let mut rng = rand::IsaacRng::new_unseeded();
    for i in 0..NUM_KEYS*NUM_VALUES {
        keys.push(i as Key);
        let value = rng.gen::<Value>();
        key_vals.push((i as Key, value))
    }
    let map: FlatMap<_, _> = key_vals.into_iter().collect();
    (map, keys)
}

fn btree_map_setup() -> (
    BTreeMap<Key, Value>,
    Vec<Key>,
) {
    let num_items = 1 << 25;
    let mut keys = Vec::new();
    let mut key_vals = Vec::with_capacity(num_items);
    let mut rng = rand::IsaacRng::new_unseeded();
    for i in 0..NUM_KEYS*NUM_VALUES {
        keys.push(i as Key);
        let value = rng.gen::<Value>();
        key_vals.push((i as Value, value))
    }
    let map = BTreeMap::from_iter(key_vals);
    (map, keys)
}

#[bench]
fn bench_flat_map_from_iter(b: &mut Bencher) {
    let num_keys = 1 << 10;
    let num_values = 1 << 10;
    let mut keys = Vec::new();
    let mut key_vals = Vec::with_capacity(num_keys * num_values);
    let mut rng = rand::IsaacRng::new_unseeded();
    for i in 0..num_keys*num_values {
        keys.push(i as Key);
        let value = rng.gen::<Value>();
        key_vals.push((i as Key, value))
    }
    b.iter(|| {
        let map = FlatMap::from_iter(key_vals.clone());
        map
    })
}

#[bench]
fn bench_flat_map_insert(b: &mut Bencher) {
    let (mut map, keys) = flat_map_setup();
    let mut rng = rand::IsaacRng::new_unseeded();
    let between = Range::new(0, keys.len());
    b.iter(|| {
        let i = between.ind_sample(&mut rng);
        map.insert(keys[i], rng.gen::<Value>());
    })
}

#[bench]
fn bench_flat_map_get(b: &mut Bencher) {
    let (map, keys) = flat_map_setup();
    let mut rng = rand::IsaacRng::new_unseeded();
    let between = Range::new(0, keys.len());
    b.iter(|| {
        let i = between.ind_sample(&mut rng);
        map.get(&keys[i])
    })
}

#[bench]
fn bench_btree_map_from_iter(b: &mut Bencher) {
    let num_keys = 1 << 10;
    let num_values = 1 << 10;
    let mut keys = Vec::new();
    let mut key_vals = Vec::with_capacity(num_keys * num_values);
    let mut rng = rand::IsaacRng::new_unseeded();
    for i in 0..num_keys*num_values {
        keys.push(i as Key);
        let value = rng.gen::<Value>();
        key_vals.push((i as Key, value))
    }
    b.iter(|| {
        let map = BTreeMap::from_iter(key_vals.clone());
        map
    })
}

#[bench]
fn bench_btree_map_insert(b: &mut Bencher) {
    let (mut map, keys) = btree_map_setup();
    let mut rng = rand::IsaacRng::new_unseeded();
    let between = Range::new(0, keys.len());
    b.iter(|| {
        let i = between.ind_sample(&mut rng);
        map.insert(keys[i], rng.gen::<Value>());
    })
}

#[bench]
fn bench_btree_map_get(b: &mut Bencher) {
    let (map, keys) = btree_map_setup();
    let mut rng = rand::IsaacRng::new_unseeded();
    let between = Range::new(0, keys.len());
    b.iter(|| {
        let i = between.ind_sample(&mut rng);
        map.get(&keys[i])
    })
}
<|endoftext|>


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

#![feature(phase)]
#![crate_name = "cube"]

extern crate cgmath;
extern crate gfx;
#[phase(plugin)]
extern crate gfx_macros;
extern crate glfw;
extern crate native;

use cgmath::FixedArray;
use cgmath::{Matrix, Point3, Vector3};
use cgmath::{Transform, AffineMatrix3};
use gfx::{Device, DeviceHelper, ToSlice};
use glfw::Context;

#[vertex_format]
struct Vertex {
    #[as_float]
    #[name = "a_Pos"]
    pos: [i8, ..3],

    #[as_float]
    #[name = "a_TexCoord"]
    tex_coord: [u8, ..2],
}

// The shader_param attribute makes sure the following struct can be used to
// pass parameters to a shader. Its argument is the name of the type that will
// be generated to represent your the program. Search for `CubeBatch` below, to
// see how it's used.
#[shader_param(CubeBatch)]
struct Params {
    #[name = "u_Transform"]
    transform: [[f32, ..4], ..4],

    #[name = "t_Color"]
    color: gfx::shade::TextureParam,
}

static VERTEX_SRC: gfx::ShaderSource<'static> = shaders! {
GLSL_120: b"
    #version 120

    attribute vec3 a_Pos;
    attribute vec2 a_TexCoord;
    varying vec2 v_TexCoord;

    uniform mat4 u_Transform;

    void main() {
        v_TexCoord = a_TexCoord;
        gl_Position = u_Transform * vec4(a_Pos, 1.0);
    }
"
GLSL_150: b"
    #version 150 core

    in vec3 a_Pos;
    in vec2 a_TexCoord;
    out vec2 v_TexCoord;

    uniform mat4 u_Transform;

    void main() {
        v_TexCoord = a_TexCoord;
        gl_Position = u_Transform * vec4(a_Pos, 1.0);
    }
"
};

static FRAGMENT_SRC: gfx::ShaderSource<'static> = shaders! {
GLSL_120: b"
    #version 120

    varying vec2 v_TexCoord;
    uniform sampler2D t_Color;

    void main() {
        vec4 tex = texture2D(t_Color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        gl_FragColor = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"
GLSL_150: b"
    #version 150 core

    in vec2 v_TexCoord;
    out vec4 o_Color;

    uniform sampler2D t_Color;
    void main() {
        vec4 tex = texture(t_Color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        o_Color = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"
};

//----------------------------------------

// We need to run on the main thread, so ensure we are using the `native` runtime. This is
// technically not needed, since this is the default, but it's not guaranteed.
#[start]
fn start(argc: int, argv: *const *const u8) -> int {
     native::start(argc, argv, main)
}

fn main() {
    let glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    glfw.window_hint(glfw::ContextVersion(3, 2));
    glfw.window_hint(glfw::OpenglForwardCompat(true));
    glfw.window_hint(glfw::OpenglProfile(glfw::OpenGlCoreProfile));

    let (window, events) = glfw
        .create_window(640, 480, "Cube example", glfw::Windowed)
        .expect("Failed to create GLFW window.");

    window.make_current();
    glfw.set_error_callback(glfw::FAIL_ON_ERRORS);
    window.set_key_polling(true);

    let (w, h) = window.get_framebuffer_size();
    let frame = gfx::Frame::new(w as u16, h as u16);

    let mut device = gfx::GlDevice::new(|s| window.get_proc_address(s));

    let vertex_data = [
        // top (0, 0, 1)
        Vertex { pos: [-1, -1,  1], tex_coord: [0, 0] },
        Vertex { pos: [ 1, -1,  1], tex_coord: [1, 0] },
        Vertex { pos: [ 1,  1,  1], tex_coord: [1, 1] },
        Vertex { pos: [-1,  1,  1], tex_coord: [0, 1] },
        // bottom (0, 0, -1)
        Vertex { pos: [ 1,  1, -1], tex_coord: [0, 0] },
        Vertex { pos: [-1,  1, -1], tex_coord: [1, 0] },
        Vertex { pos: [-1, -1, -1], tex_coord: [1, 1] },
        Vertex { pos: [ 1, -1, -1], tex_coord: [0, 1] },
        // right (1, 0, 0)
        Vertex { pos: [ 1, -1, -1], tex_coord: [0, 0] },
        Vertex { pos: [ 1,  1, -1], tex_coord: [1, 0] },
        Vertex { pos: [ 1,  1,  1], tex_coord: [1, 1] },
        Vertex { pos: [ 1, -1,  1], tex_coord: [0, 1] },
        // left (-1, 0, 0)
        Vertex { pos: [-1,  1,  1], tex_coord: [0, 0] },
        Vertex { pos: [-1, -1,  1], tex_coord: [1, 0] },
        Vertex { pos: [-1, -1, -1], tex_coord: [1, 1] },
        Vertex { pos: [-1,  1, -1], tex_coord: [0, 1] },
        // front (0, 1, 0)
        Vertex { pos: [-1,  1, -1], tex_coord: [0, 0] },
        Vertex { pos: [ 1,  1, -1], tex_coord: [1, 0] },
        Vertex { pos: [ 1,  1,  1], tex_coord: [1, 1] },
        Vertex { pos: [-1,  1,  1], tex_coord: [0, 1] },
        // back (0, -1, 0)
        Vertex { pos: [ 1, -1,  1], tex_coord: [0, 0] },
        Vertex { pos: [-1, -1,  1], tex_coord: [1, 0] },
        Vertex { pos: [-1, -1, -1], tex_coord: [1, 1] },
        Vertex { pos: [ 1, -1, -1], tex_coord: [0, 1] },
    ];

    let mesh = device.create_mesh(vertex_data);

    let index_data: &[u8] = [
         0,  1,  2,  2,  3,  0, // top
         4,  5,  6,  6,  7,  4, // bottom
         8,  9, 10, 10, 11,  8, // right
        12, 13, 14, 14, 16, 12, // left
        16, 17, 18, 18, 19, 16, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    let slice = device
        .create_buffer_static::<u8>(index_data)
        .to_slice(gfx::TriangleList);

    let texture_info = gfx::tex::TextureInfo {
        width: 1,
        height: 1,
        depth: 1,
        levels: 1,
        kind: gfx::tex::Texture2D,
        format: gfx::tex::RGBA8,
    };
    let image_info = texture_info.to_image_info();
    let texture = device.create_texture(texture_info).unwrap();
    device.update_texture(&texture, &image_info,
                          [0x20u8, 0xA0u8, 0xC0u8, 0x00u8])
        .unwrap();

    let sampler = device.create_sampler(
        gfx::tex::SamplerInfo::new(gfx::tex::Bilinear,
                                   gfx::tex::Clamp)
    );

    let program = device.link_program(VERTEX_SRC.clone(), FRAGMENT_SRC.clone())
                        .unwrap();
    let state = gfx::DrawState::new().depth(gfx::state::LessEqual, true);

    let mut graphics = gfx::Graphics::new(device);
    let batch: CubeBatch = graphics.make_batch(&program, &mesh, slice, &state).unwrap();

    let view: AffineMatrix3<f32> = Transform::look_at(
        &Point3::new(1.5f32, -5.0, 3.0),
        &Point3::new(0f32, 0.0, 0.0),
        &Vector3::unit_z(),
    );
    let aspect = w as f32 / h as f32;
    let proj = cgmath::perspective(cgmath::deg(45.0f32), aspect, 1.0, 10.0);

    let data = Params {
        transform: proj.mul_m(&view.mat).into_fixed(),
        color: (texture, Some(sampler)),
    };

    let clear_data = gfx::ClearData {
        color: [0.3, 0.3, 0.3, 1.0],
        depth: 1.0,
        stencil: 0,
    };

    while !window.should_close() {
        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            match event {
                glfw::KeyEvent(glfw::KeyEscape, _, glfw::Press, _) =>
                    window.set_should_close(true),
                _ => {},
            }
        }

        graphics.clear(clear_data, gfx::COLOR | gfx::DEPTH, &frame);
        graphics.draw(&batch, &data, &frame);
        graphics.end_frame();

        window.swap_buffers();
    }
}
<commit_msg>Corrected cube example: faces now have correct winding.<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![feature(phase)]
#![crate_name = "cube"]

extern crate cgmath;
extern crate gfx;
#[phase(plugin)]
extern crate gfx_macros;
extern crate glfw;
extern crate native;

use cgmath::FixedArray;
use cgmath::{Matrix, Point3, Vector3};
use cgmath::{Transform, AffineMatrix3};
use gfx::{Device, DeviceHelper, ToSlice};
use glfw::Context;

#[vertex_format]
struct Vertex {
    #[as_float]
    #[name = "a_Pos"]
    pos: [i8, ..3],

    #[as_float]
    #[name = "a_TexCoord"]
    tex_coord: [u8, ..2],
}

// The shader_param attribute makes sure the following struct can be used to
// pass parameters to a shader. Its argument is the name of the type that will
// be generated to represent your the program. Search for `CubeBatch` below, to
// see how it's used.
#[shader_param(CubeBatch)]
struct Params {
    #[name = "u_Transform"]
    transform: [[f32, ..4], ..4],

    #[name = "t_Color"]
    color: gfx::shade::TextureParam,
}

static VERTEX_SRC: gfx::ShaderSource<'static> = shaders! {
GLSL_120: b"
    #version 120

    attribute vec3 a_Pos;
    attribute vec2 a_TexCoord;
    varying vec2 v_TexCoord;

    uniform mat4 u_Transform;

    void main() {
        v_TexCoord = a_TexCoord;
        gl_Position = u_Transform * vec4(a_Pos, 1.0);
    }
"
GLSL_150: b"
    #version 150 core

    in vec3 a_Pos;
    in vec2 a_TexCoord;
    out vec2 v_TexCoord;

    uniform mat4 u_Transform;

    void main() {
        v_TexCoord = a_TexCoord;
        gl_Position = u_Transform * vec4(a_Pos, 1.0);
    }
"
};

static FRAGMENT_SRC: gfx::ShaderSource<'static> = shaders! {
GLSL_120: b"
    #version 120

    varying vec2 v_TexCoord;
    uniform sampler2D t_Color;

    void main() {
        vec4 tex = texture2D(t_Color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        gl_FragColor = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"
GLSL_150: b"
    #version 150 core

    in vec2 v_TexCoord;
    out vec4 o_Color;

    uniform sampler2D t_Color;
    void main() {
        vec4 tex = texture(t_Color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        o_Color = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"
};

//----------------------------------------

// We need to run on the main thread, so ensure we are using the `native` runtime. This is
// technically not needed, since this is the default, but it's not guaranteed.
#[start]
fn start(argc: int, argv: *const *const u8) -> int {
     native::start(argc, argv, main)
}

fn main() {
    let glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    glfw.window_hint(glfw::ContextVersion(3, 2));
    glfw.window_hint(glfw::OpenglForwardCompat(true));
    glfw.window_hint(glfw::OpenglProfile(glfw::OpenGlCoreProfile));

    let (window, events) = glfw
        .create_window(640, 480, "Cube example", glfw::Windowed)
        .expect("Failed to create GLFW window.");

    window.make_current();
    glfw.set_error_callback(glfw::FAIL_ON_ERRORS);
    window.set_key_polling(true);

    let (w, h) = window.get_framebuffer_size();
    let frame = gfx::Frame::new(w as u16, h as u16);

    let mut device = gfx::GlDevice::new(|s| window.get_proc_address(s));

    let vertex_data = [
        // top (0, 0, 1)
        Vertex { pos: [-1, -1,  1], tex_coord: [0, 0] },
        Vertex { pos: [ 1, -1,  1], tex_coord: [1, 0] },
        Vertex { pos: [ 1,  1,  1], tex_coord: [1, 1] },
        Vertex { pos: [-1,  1,  1], tex_coord: [0, 1] },
        // bottom (0, 0, -1)
        Vertex { pos: [-1,  1, -1], tex_coord: [1, 0] },
        Vertex { pos: [ 1,  1, -1], tex_coord: [0, 0] },
        Vertex { pos: [ 1, -1, -1], tex_coord: [0, 1] },
        Vertex { pos: [-1, -1, -1], tex_coord: [1, 1] },
        // right (1, 0, 0)
        Vertex { pos: [ 1, -1, -1], tex_coord: [0, 0] },
        Vertex { pos: [ 1,  1, -1], tex_coord: [1, 0] },
        Vertex { pos: [ 1,  1,  1], tex_coord: [1, 1] },
        Vertex { pos: [ 1, -1,  1], tex_coord: [0, 1] },
        // left (-1, 0, 0)
        Vertex { pos: [-1, -1,  1], tex_coord: [1, 0] },
        Vertex { pos: [-1,  1,  1], tex_coord: [0, 0] },
        Vertex { pos: [-1,  1, -1], tex_coord: [0, 1] },
        Vertex { pos: [-1, -1, -1], tex_coord: [1, 1] },
        // front (0, 1, 0)
        Vertex { pos: [ 1,  1, -1], tex_coord: [1, 0] },
        Vertex { pos: [-1,  1, -1], tex_coord: [0, 0] },
        Vertex { pos: [-1,  1,  1], tex_coord: [0, 1] },
        Vertex { pos: [ 1,  1,  1], tex_coord: [1, 1] },
        // back (0, -1, 0)
        Vertex { pos: [ 1, -1,  1], tex_coord: [0, 0] },
        Vertex { pos: [-1, -1,  1], tex_coord: [1, 0] },
        Vertex { pos: [-1, -1, -1], tex_coord: [1, 1] },
        Vertex { pos: [ 1, -1, -1], tex_coord: [0, 1] },
    ];

    let mesh = device.create_mesh(vertex_data);

    let index_data: &[u8] = [
         0,  1,  2,  2,  3,  0, // top
         4,  5,  6,  6,  7,  4, // bottom
         8,  9, 10, 10, 11,  8, // right
        12, 13, 14, 14, 15, 12, // left
        16, 17, 18, 18, 19, 16, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    let slice = device
        .create_buffer_static::<u8>(index_data)
        .to_slice(gfx::TriangleList);

    let texture_info = gfx::tex::TextureInfo {
        width: 1,
        height: 1,
        depth: 1,
        levels: 1,
        kind: gfx::tex::Texture2D,
        format: gfx::tex::RGBA8,
    };
    let image_info = texture_info.to_image_info();
    let texture = device.create_texture(texture_info).unwrap();
    device.update_texture(&texture, &image_info,
                          [0x20u8, 0xA0u8, 0xC0u8, 0x00u8])
        .unwrap();

    let sampler = device.create_sampler(
        gfx::tex::SamplerInfo::new(gfx::tex::Bilinear,
                                   gfx::tex::Clamp)
    );

    let program = device.link_program(VERTEX_SRC.clone(), FRAGMENT_SRC.clone())
                        .unwrap();
    let state = gfx::DrawState::new().depth(gfx::state::LessEqual, true);

    let mut graphics = gfx::Graphics::new(device);
    let batch: CubeBatch = graphics.make_batch(&program, &mesh, slice, &state).unwrap();

    let view: AffineMatrix3<f32> = Transform::look_at(
        &Point3::new(1.5f32, -5.0, 3.0),
        &Point3::new(0f32, 0.0, 0.0),
        &Vector3::unit_z(),
    );
    let aspect = w as f32 / h as f32;
    let proj = cgmath::perspective(cgmath::deg(45.0f32), aspect, 1.0, 10.0);

    let data = Params {
        transform: proj.mul_m(&view.mat).into_fixed(),
        color: (texture, Some(sampler)),
    };

    let clear_data = gfx::ClearData {
        color: [0.3, 0.3, 0.3, 1.0],
        depth: 1.0,
        stencil: 0,
    };

    while !window.should_close() {
        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            match event {
                glfw::KeyEvent(glfw::KeyEscape, _, glfw::Press, _) =>
                    window.set_should_close(true),
                _ => {},
            }
        }

        graphics.clear(clear_data, gfx::COLOR | gfx::DEPTH, &frame);
        graphics.draw(&batch, &data, &frame);
        graphics.end_frame();

        window.swap_buffers();
    }
}
<|endoftext|>


<commit_before>extern crate iron;
extern crate time;

use iron::prelude::*;
use iron::{Handler, AroundMiddleware};
use iron::status;

enum LoggerMode {
    Silent,
    Tiny,
    Large
}

struct Logger {
    mode: LoggerMode
}

struct LoggerHandler<H: Handler> { logger: Logger, handler: H }

impl Logger {
    fn new(mode: LoggerMode) -> Logger {
        Logger { mode: mode }
    }

    fn log(&self, req: &Request, res: Result<&Response, &IronError>, time: u64) {
        match self.mode {
            LoggerMode::Silent => {},
            LoggerMode::Tiny => println!("Req: {:?}\nRes: {:?}\nTook: {}", req, res, time),
            LoggerMode::Large => println!("Request: {:?}\nResponse: {:?}\nResponse-Time: {}", req, res, time)
        }
    }
}

impl<H: Handler> Handler for LoggerHandler<H> {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        let entry = ::time::precise_time_ns();
        let res = self.handler.handle(req);
        self.logger.log(req, res.as_ref(), ::time::precise_time_ns() - entry);
        res
    }
}

impl AroundMiddleware for Logger {
    fn around(self, handler: Box<Handler>) -> Box<Handler> {
        Box::new(LoggerHandler {
            logger: self,
            handler: handler
        }) as Box<Handler>
    }
}

fn hello_world(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, "Hello World!")))
}

fn main() {
    let tiny = Iron::new(Logger::new(LoggerMode::Tiny).around(Box::new(hello_world)));
    let silent = Iron::new(Logger::new(LoggerMode::Silent).around(Box::new(hello_world)));
    let large = Iron::new(Logger::new(LoggerMode::Large).around(Box::new(hello_world)));

    println!("Starting servers on 2000, 3000, and 4000");

    tiny.listen("localhost:2000").unwrap();
    silent.listen("localhost:3000").unwrap();
    large.listen("localhost:4000").unwrap();

}

<commit_msg>(fix) Fixed broken example blocking silent / large from starting<commit_after>extern crate iron;
extern crate time;

use iron::prelude::*;
use iron::{Handler, AroundMiddleware};
use iron::status;

enum LoggerMode {
    Silent,
    Tiny,
    Large
}

struct Logger {
    mode: LoggerMode
}

struct LoggerHandler<H: Handler> { logger: Logger, handler: H }

impl Logger {
    fn new(mode: LoggerMode) -> Logger {
        Logger { mode: mode }
    }

    fn log(&self, req: &Request, res: Result<&Response, &IronError>, time: u64) {
        match self.mode {
            LoggerMode::Silent => {},
            LoggerMode::Tiny => println!("Req: {:?}\nRes: {:?}\nTook: {}", req, res, time),
            LoggerMode::Large => println!("Request: {:?}\nResponse: {:?}\nResponse-Time: {}", req, res, time)
        }
    }
}

impl<H: Handler> Handler for LoggerHandler<H> {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        let entry = ::time::precise_time_ns();
        let res = self.handler.handle(req);
        self.logger.log(req, res.as_ref(), ::time::precise_time_ns() - entry);
        res
    }
}

impl AroundMiddleware for Logger {
    fn around(self, handler: Box<Handler>) -> Box<Handler> {
        Box::new(LoggerHandler {
            logger: self,
            handler: handler
        }) as Box<Handler>
    }
}

fn hello_world(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, "Hello World!")))
}

fn main() {
    let tiny = Iron::new(Logger::new(LoggerMode::Tiny).around(Box::new(hello_world)));
    let silent = Iron::new(Logger::new(LoggerMode::Silent).around(Box::new(hello_world)));
    let large = Iron::new(Logger::new(LoggerMode::Large).around(Box::new(hello_world)));

    let _tiny_listening = tiny.listen("localhost:2000").unwrap();
    let _silent_listening = silent.listen("localhost:3000").unwrap();
    let _large_listening = large.listen("localhost:4000").unwrap();

    println!("Servers listening on 2000, 3000, and 4000");
}

<|endoftext|>


<commit_before>#[macro_use]
extern crate log;

extern crate abstract_ns;
extern crate futures;
extern crate getopts;
extern crate ns_dns_tokio;
extern crate rand;
extern crate tokio_core;
extern crate tokio_io;
extern crate net2;

// the device under test
extern crate net_interceptor;

use futures::{Future, Stream, IntoFuture};
use futures::sync::oneshot;
use futures::sync::oneshot::{Sender};
use tokio_core::net::{TcpListener};
use tokio_core::reactor::{Core, Timeout};

use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::sync::{Arc, Barrier};
use std::thread;

use net_interceptor::logging::unittestlogger;

// Timeout for reactor based tests in seconds
const TIMEOUT: u64 = 5;

fn stopper(oneshot_sender_stream: Sender<i64>) -> Arc<Barrier> {
    // barrier awaits the releaser thread and the signalling one
    let barrier = Arc::new(Barrier::new(2));
    let copy_for_thread = barrier.clone();
    // the releaser thread
    let builder = thread::Builder::new()
        .name("core shutdown barrier thread".into());
    builder.spawn(move || {
        debug!("waiting for end");
        copy_for_thread.wait();
        debug!("signalling end");
        // release the future blockig core.run()
        oneshot_sender_stream.send(1).unwrap();
    }).unwrap();
    barrier
}

#[test]
fn test_infra_connect() {
    unittestlogger();

    // this is the main event loop, powered by tokio core
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let bind_socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 0);

    let listener = net2::TcpBuilder::new_v4().unwrap()
        // .reuse_address(true).unwrap()
        .bind(bind_socket_addr).unwrap()
        // 2 = allow two connection requests in the backlog
        .listen(2).unwrap();

    let listen_port = listener.local_addr().unwrap();
    let contextid = listen_port.port();
    warn!("Listening on {} in context {}", listen_port, contextid);

    let sock = TcpListener::from_listener(listener, &bind_socket_addr, &handle).unwrap();

    let (tx, signal) = oneshot::channel::<i64>();
    let barrier = stopper(tx);

    let result = sock.incoming().for_each(move |(socket, addr)| {
        //protocol.bind_connection(&handle, socket, addr, AlphaBravo::new(&path));

        warn!("connection from {} in context {}", addr, contextid);
        barrier.wait();
        Ok(())
    });

    // register the acceptor in the reactor core
    // the map_err is a hack to satisfy connections.for_each above
    handle.spawn(result.map_err(|_|()));

    let fut = Timeout::new(std::time::Duration::from_secs(TIMEOUT), &handle).into_future();
    let timeout = fut.flatten();

    let fut2 = timeout.and_then(|_| {
        assert!(false, "timeout expired waiting for connection in context {}", contextid);
        Ok(())
    });

    match core.run(fut2.select2(signal)) {
        Err(e) => { panic!("oh no!") },
        Result => { },
        _ => { },
    };

    //drop(result);
}

#[test]
fn test_two_times() {
    test_infra_connect();
    test_infra_connect();
}
<commit_msg>works but fails, since timeout kicks in as expected<commit_after>#[macro_use]
extern crate log;

extern crate abstract_ns;
extern crate futures;
extern crate getopts;
extern crate ns_dns_tokio;
extern crate rand;
extern crate tokio_core;
extern crate tokio_io;
extern crate net2;

// the device under test
extern crate net_interceptor;

use futures::{Future, Stream, IntoFuture};
use futures::sync::oneshot;
use futures::sync::oneshot::{Sender};
use tokio_core::net::{TcpListener};
use tokio_core::reactor::{Core, Timeout};

use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::sync::{Arc, Barrier};
use std::thread;

use net_interceptor::logging::unittestlogger;

// Timeout for reactor based tests in seconds
const TIMEOUT: u64 = 5;

fn stopper(oneshot_sender_stream: Sender<i64>) -> Arc<Barrier> {
    // barrier awaits the releaser thread and the signalling one
    let barrier = Arc::new(Barrier::new(2));
    let copy_for_thread = barrier.clone();
    // the releaser thread
    let builder = thread::Builder::new()
        .name("barrier to signal thread".into());
    builder.spawn(move || {
        debug!("waiting for end");
        copy_for_thread.wait();
        debug!("signalling end");
        // release the future blockig core.run()
        oneshot_sender_stream.send(1).unwrap();
    }).unwrap();
    barrier
}

#[test]
fn test_infra_connect() {
    unittestlogger();

    // this is the main event loop, powered by tokio core
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let bind_socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 0);

    let listener = net2::TcpBuilder::new_v4().unwrap()
        // .reuse_address(true).unwrap()
        .bind(bind_socket_addr).unwrap()
        // 2 = allow two connection requests in the backlog
        .listen(2).unwrap();

    let listen_port = listener.local_addr().unwrap();
    let contextid = listen_port.port();
    warn!("Listening on {} in context {}", listen_port, contextid);

    let sock = TcpListener::from_listener(listener, &bind_socket_addr, &handle).unwrap();

    let (tx, signal) = oneshot::channel::<i64>();
    let barrier = stopper(tx);

    let result = sock.incoming().for_each(move |(socket, addr)| {
        //protocol.bind_connection(&handle, socket, addr, AlphaBravo::new(&path));
        warn!("connection from {} in context {}", addr, contextid);
        barrier.wait();
        Ok(())
    });

    // register the acceptor in the reactor core
    // the map_err is a hack to satisfy connections.for_each above
    handle.spawn(result.map_err(|_|()));

    let fut = Timeout::new(std::time::Duration::from_secs(TIMEOUT), &handle).into_future();
    let timeout = fut.flatten();

    let timeout_expired = timeout.and_then(|_| -> Result<i64, std::io::Error> {
        panic!("test timeout expired: test failed!")
    });

    match core.run(timeout_expired.select2(signal)) {
        Err(_) => { panic!("oh no!"); },
        _ => { },
    };

    //drop(result);
}

#[test]
fn test_two_times() {
    test_infra_connect();
    test_infra_connect();
}
<|endoftext|>


<commit_before>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//

extern mod extra;

use std::{io, run, os, str};
use std::io::buffered::BufferedReader;
use std::path::posix::Path;
use std::io::fs::File;
use std::io::stdin;
use std::io::signal::{Listener, Interrupt};
use extra::getopts;

struct Shell {
    cmd_prompt : ~str,
    cmd_history : ~[~str],
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
            cmd_history: ~[],
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        // let (port_interrupt, chan_interrupt) : (Port<~str>, Chan<~str>) = Chan::new();
        let (port_exit, chan_exit) : (Port<int>, Chan<int>) = Chan::new();
        let (port_PID, chan_PID) : (Port<i32>, Chan<i32>) = Chan::new();
        // 99 is kill signal!
        spawn(proc() {
            let mut listener = Listener::new();
            listener.register(Interrupt);
            let mut last_pid : i32 = -1;
            loop {
                match port_PID.try_recv() {
                    Some(pid) => { last_pid = pid }
                    None    => {}
                }
                match port_exit.try_recv() {
                    Some(99)    => { listener.unregister(Interrupt);
                                     return }
                    _   => {}
                }
                match listener.port.try_recv() {
                    Some(Interrupt) => {
                        println!("Attempting to kill process with PID: {:d}", last_pid);
                        unsafe {
                            let result : i32 = std::libc::funcs::posix88::signal::kill(last_pid, 0);
                            println!("Result of kill is: {:d}", result);
                        }
                        // KILL LAST_PID
                       // std::libc::funcs::posix88::signal::kill();
                    }
                    _ => {}
                }
            }
        });

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let mut line : ~str = stdin.read_line().unwrap().to_owned();
            let mut cmd_line: ~str = line.trim().to_owned();
            let mut background: bool = false;
            let mut i : uint = 0;

            // This block handles if there are no spaces around pipe.
            let lineClone = line.clone();
            for character in lineClone.chars() {
                if character == '<' {
                    line = line.slice(0, i).to_owned() + " < " + line.slice(i+1, line.char_len()).to_owned();
                    i = i + 2;
                } else if character == '>' {
                    line = line.slice(0, i).to_owned() + " > " + line.slice(i+1, line.char_len()).to_owned();
                    i = i + 2;
                } else if character == '|' {
                    line = line.slice(0, i).to_owned() + " | " + line.slice(i+1, line.char_len()).to_owned();
                    i = i + 2;
                }
                i = i + 1;
            }

            if cmd_line.char_len() > 0 {
                background = cmd_line.char_at(cmd_line.char_len() - 1) == '&';
                if background {
                    cmd_line = cmd_line.slice(0, cmd_line.char_len() - 1).trim().to_owned();
                }
            }

            let params = cmd_line.clone().to_owned();
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");

            match program {
                ""          =>  { continue; }
                "exit"      =>  { chan_exit.send(99);   // Sends kill signal to listener for ^C.
                                  return; }
                "cd"        =>  { Shell::run_check_mode(background, Shell::run_cd(params), &chan_PID); }
                "history"   =>  { Shell::run_check_mode(background, Shell::run_history(params, self.cmd_history), &chan_PID); }
                _           =>  { Shell::run_check_mode(background, Shell::run_cmdline(params), &chan_PID); }
            }

            self.cmd_history.push(program.to_owned());
        }
    }

    fn run_check_mode(background: bool, f: proc(), chan_PID : &Chan<i32>) {
        if background {
            spawn(proc() { f(); });
        } else {
            let (port_temp, chan_temp) : (Port<i32>, Chan<i32>) = Chan::new();
            spawn(proc() {
                unsafe { chan_temp.send(std::libc::getpid()); }
                f();
            });
            chan_PID.send(port_temp.recv());
        }
    }

    fn run_cmdline_single(cmd_line: &str) {
        (Shell::run_cmdline(cmd_line))();
    }

    fn run_cmdline(cmd_line: &str) -> proc() {
        let params = cmd_line.to_owned();
        return proc() {
            if params.trim() != "" {
                let output = Shell::handle_pipes(params, false);
                // write output to file (if necessary and exists)
                match output {
                    Some(outString) => {
                        match Shell::get_output_file(params) {
                            Some(fileName) => {
                                let mut f = File::create(&Path::new(fileName));
                                f.write(outString.into_bytes());
                            }
                            None => { /* Shouldn't happen... */ }
                        }
                    }
                    None => { /*Do nothing*/ }
                }
            }
        };
    }

    fn handle_pipes(cmd_line: &str, out_pipe: bool) -> Option<~str> {
        let pipeSplit = Shell::split_on_last_pipe(cmd_line);
        let mut argv = Shell::get_args_no_redirects(pipeSplit[0]);
        let program = argv.remove(0);
        let hasOutRedirect = match Shell::get_output_file(cmd_line) {
            Some(_) => { true }
            None => {
                if out_pipe {
                    true
                } else {
                    false
                }
            }
        };

        if pipeSplit.len() == 2 {
            return Shell::run_cmd(program, argv, Shell::handle_pipes(pipeSplit[1], true), hasOutRedirect);
        } else {
            return Shell::run_cmd(program, argv, Shell::get_input_file_contents(cmd_line), hasOutRedirect);
        }
    }

    fn run_cmd(program: &str, argv: &[~str], inputStr: Option<~str>, hasOutRedirect: bool) -> Option<~str> {
        if Shell::cmd_exists(program) {
            let mut options = run::ProcessOptions::new();
            options.in_fd = match inputStr {
                Some(_) => { None }
                None => { Some(0) }
            };

            options.out_fd = if hasOutRedirect {
                None
            } else {
                Some(1)
            };

            let mut process = run::Process::new(program, argv, options).unwrap();
            match inputStr {
                Some(string) => {
                    let buf = string.into_bytes();
                    process.input().write(buf);
                }
                None => {}
            }

            process.close_input();

            if hasOutRedirect {
                let processOutput = process.finish_with_output();
                return Some(str::from_utf8(processOutput.output).to_owned());
            } else {
                process.finish();
                return None;
            };
        } else {
            println!("{:s}: command not found", program);
            return None;
        }
    }

    fn cmd_exists(cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }

    fn run_cd(cmd_line: &str) -> proc() {
        let params = cmd_line.to_owned();
        return proc() {
            let argv: ~[~str] = Shell::get_args(params);
            let pathOpt: Option<Path> = match argv.len() {
                1   =>  { os::homedir() }
                0   =>  { os::homedir() }
                _   =>  { Some(Path::new(argv[1])) }
            };

            match pathOpt {
                Some(path)   =>  {
                    if path.is_dir() {
                        os::change_dir(&path);
                    } else {
                        println!("Error: {:s} is not a directory", path.as_str().unwrap());
                    }
                }
                None        =>  {
                    println!("Error: Invalid path");
                }
            };
        };
    }

    fn run_history(cmd_line: &str, cmd_history: &[~str]) -> proc() {
        let history = cmd_history.to_owned();
        let params = cmd_line.to_owned();
        return proc() {
            let argv: ~[~str] = Shell::get_args(params);
            if (argv.len() > 1) {
                println!("Error: history does not take options (sadly).");
            }
            else {
                let mut i = 1;
                for entry in history.iter() {
                    println!("{:d} \t{:s}", i, entry.to_owned());
                    i = i + 1;
                }
            }
        };
    }

    fn split_on_last_pipe(cmd_line: &str) -> ~[~str] {
        return cmd_line.rsplitn('|', 1).filter_map(|x| Some(x.trim().to_owned())).to_owned_vec();
    }

    fn get_input_file_contents(cmd_line: &str) -> Option<~str> {
        return match cmd_line.splitn('<', 1).nth(1) {
            Some(inputFileCandidate) => {
                match inputFileCandidate.trim().splitn(' ', 1).nth(0) {
                    Some(inputFile) => {
                        match File::open(&Path::new(inputFile)) {
                            Some(mut file) => {
                                Some(file.read_to_str())
                            }
                            None => {
                                println!("File {:s} does not exist", inputFile);
                                None
                            }
                        }
                    }
                    None => { None }
                }
            }
            None => { None }
        };
    }

    fn get_output_file(cmd_line: &str) -> Option<~str> {
        return match cmd_line.splitn('>', 1).nth(1) {
            Some(inputFileCandidate) => {
                match inputFileCandidate.trim().splitn(' ', 1).nth(0) {
                    Some(inputFile) => { Some(inputFile.to_owned()) }
                    None => { None }
                }
            }
            None => { None }
        };
    }

    fn get_args_no_redirects(cmd_line: &str) -> ~[~str] {
        let mut activeRedirect = false;
        return cmd_line.split(' ').filter_map(|x| if x == ">" || x == "<" {
            activeRedirect = true;
            None
        } else if x == "" {
            None
        } else if activeRedirect {
            activeRedirect = false;
            None
        } else {
            Some(x.to_owned())
        }).to_owned_vec();
    }

    fn get_args(cmd_line: &str) -> ~[~str] {
        return cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::run_cmdline_single(cmd_line),
        None           => Shell::new("gash > ").run()
    }
}
<commit_msg>Sort of working. not really. eh<commit_after>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//

extern mod extra;

use std::{io, run, os, str};
use std::io::buffered::BufferedReader;
use std::path::posix::Path;
use std::io::fs::File;
use std::io::stdin;
use std::io::signal::{Listener, Interrupt};
use extra::getopts;

struct Shell {
    cmd_prompt : ~str,
    cmd_history : ~[~str],
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
            cmd_history: ~[],
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        // let (port_interrupt, chan_interrupt) : (Port<~str>, Chan<~str>) = Chan::new();
        let (port_PID, chan_PID) : (Port<i32>, Chan<i32>) = Chan::new();
        let (port_temp, chan_temp) : (Port<i32>, Chan<i32>) = Chan::new();
            // -99 is "exit" signal
            // -1 is "continue" signal
        chan_temp.send(-1);
        spawn(proc() {
            let mut listener = Listener::new();
            listener.register(Interrupt);

            let mut last_pid : i32 = 1;
            loop {
                match port_PID.try_recv() {
                    Some(-99) => {
                        listener.unregister(Interrupt);
                        chan_temp.send(-99);    // Exit code.
                        return;
                    }
                    Some(-1) => {
                        port_PID.recv();     // Burn nop
                        chan_temp.send(-1);    // To complete process
                    }
                    Some(pid) => {
                        println!("got one")
                        let mut my_pid : i32;
                        unsafe { my_pid = std::libc::getpid(); }
                        if (pid != my_pid) {
                            last_pid = pid;
                            println!("Changed PID to {:d}", last_pid);
                        }
                            port_PID.recv();    // Burn nop
                            chan_temp.send(-1);   // To complete process
                    }
                    None    => {}
                }
                match listener.port.try_recv() {
                    Some(Interrupt) => {
                        // chan_temp.send(port_PID.recv());
                        println!("Killing {:d}", last_pid);
                        unsafe {
                            let result : i32 = std::libc::funcs::posix88::signal::kill(last_pid, 0);
                        }
                    }
                    _ => {}
                }
            }
        });

        loop {
            let status : i32 = port_temp.recv();   // Wait for op to finish.
            if (status == -99) { return; }
            print(self.cmd_prompt); // Prints "gash >"
            io::stdio::flush();

            let mut line : ~str = stdin.read_line().unwrap().to_owned();
            let mut cmd_line: ~str = line.trim().to_owned();
            let mut background: bool = false;
            let mut i : uint = 0;

            // This block handles if there are no spaces around pipe.
            let lineClone = line.clone();
            for character in lineClone.chars() {
                if character == '<' {
                    line = line.slice(0, i).to_owned() + " < " + line.slice(i+1, line.char_len()).to_owned();
                    i = i + 2;
                } else if character == '>' {
                    line = line.slice(0, i).to_owned() + " > " + line.slice(i+1, line.char_len()).to_owned();
                    i = i + 2;
                } else if character == '|' {
                    line = line.slice(0, i).to_owned() + " | " + line.slice(i+1, line.char_len()).to_owned();
                    i = i + 2;
                }
                i = i + 1;
            }

            if cmd_line.char_len() > 0 {
                background = cmd_line.char_at(cmd_line.char_len() - 1) == '&';
                if background {
                    cmd_line = cmd_line.slice(0, cmd_line.char_len() - 1).trim().to_owned();
                }
            }

            let params = cmd_line.clone().to_owned();
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");

            match program {
                ""          =>  { chan_PID.send(-1);    // nop
                                  chan_PID.send(-1);   // nop
                                  continue; }
                "exit"      =>  { chan_PID.send(-99); }  // Exit
                "cd"        =>  { /*chan_temp.send(-1);*/
                                  Shell::run_check_mode(background, Shell::run_cd(params), &chan_PID); }
                "history"   =>  { /*chan_temp.send(-1);*/
                                  Shell::run_check_mode(background, Shell::run_history(params, self.cmd_history), &chan_PID); }
                _           =>  { /*chan_temp.send(-1);*/
                                  Shell::run_check_mode(background, Shell::run_cmdline(params), &chan_PID); }
            }

            self.cmd_history.push(program.to_owned());
        }
    }

    fn run_check_mode(background: bool, f: proc(), chan_PID : &Chan<i32>) {
        let (port_temp, chan_temp) : (Port<i32>, Chan<i32>) = Chan::new();
        if background {
            spawn(proc() { f(); });
            chan_PID.send(-1);
            chan_PID.send(-1);
        } else {
            spawn(proc() {
                unsafe { chan_temp.send(std::libc::getpid());
                    println!("PID is {:d}", std::libc::getpid());
                }
                f();
                chan_temp.send(-1);
            });
            chan_PID.send(port_temp.recv());
            chan_PID.send(port_temp.recv());
        }
    }

    fn run_cmdline_single(cmd_line: &str) {
        (Shell::run_cmdline(cmd_line))();
    }

    fn run_cmdline(cmd_line: &str) -> proc() {
        let params = cmd_line.to_owned();
        return proc() {
            if params.trim() != "" {
                let output = Shell::handle_pipes(params, false);
                // write output to file (if necessary and exists)
                match output {
                    Some(outString) => {
                        match Shell::get_output_file(params) {
                            Some(fileName) => {
                                let mut f = File::create(&Path::new(fileName));
                                f.write(outString.into_bytes());
                            }
                            None => { /* Shouldn't happen... */ }
                        }
                    }
                    None => { /*Do nothing*/ }
                }
            }
        };
    }

    fn handle_pipes(cmd_line: &str, out_pipe: bool) -> Option<~str> {
        let pipeSplit = Shell::split_on_last_pipe(cmd_line);
        let mut argv = Shell::get_args_no_redirects(pipeSplit[0]);
        let program = argv.remove(0);
        let hasOutRedirect = match Shell::get_output_file(cmd_line) {
            Some(_) => { true }
            None => {
                if out_pipe {
                    true
                } else {
                    false
                }
            }
        };

        if pipeSplit.len() == 2 {
            return Shell::run_cmd(program, argv, Shell::handle_pipes(pipeSplit[1], true), hasOutRedirect);
        } else {
            return Shell::run_cmd(program, argv, Shell::get_input_file_contents(cmd_line), hasOutRedirect);
        }
    }

    fn run_cmd(program: &str, argv: &[~str], inputStr: Option<~str>, hasOutRedirect: bool) -> Option<~str> {
        if Shell::cmd_exists(program) {
            let mut options = run::ProcessOptions::new();
            options.in_fd = match inputStr {
                Some(_) => { None }
                None => { Some(0) }
            };

            options.out_fd = if hasOutRedirect {
                None
            } else {
                Some(1)
            };

            let mut process = run::Process::new(program, argv, options).unwrap();
            match inputStr {
                Some(string) => {
                    let buf = string.into_bytes();
                    process.input().write(buf);
                }
                None => {}
            }

            process.close_input();

            if hasOutRedirect {
                let processOutput = process.finish_with_output();
                return Some(str::from_utf8(processOutput.output).to_owned());
            } else {
                process.finish();
                return None;
            };
        } else {
            println!("{:s}: command not found", program);
            return None;
        }
    }

    fn cmd_exists(cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }

    fn run_cd(cmd_line: &str) -> proc() {
        let params = cmd_line.to_owned();
        return proc() {
            let argv: ~[~str] = Shell::get_args(params);
            let pathOpt: Option<Path> = match argv.len() {
                1   =>  { os::homedir() }
                0   =>  { os::homedir() }
                _   =>  { Some(Path::new(argv[1])) }
            };

            match pathOpt {
                Some(path)   =>  {
                    if path.is_dir() {
                        os::change_dir(&path);
                    } else {
                        println!("Error: {:s} is not a directory", path.as_str().unwrap());
                    }
                }
                None        =>  {
                    println!("Error: Invalid path");
                }
            };
        };
    }

    fn run_history(cmd_line: &str, cmd_history: &[~str]) -> proc() {
        let history = cmd_history.to_owned();
        let params = cmd_line.to_owned();
        return proc() {
            let argv: ~[~str] = Shell::get_args(params);
            if (argv.len() > 1) {
                println!("Error: history does not take options (sadly).");
            }
            else {
                let mut i = 1;
                for entry in history.iter() {
                    println!("{:d} \t{:s}", i, entry.to_owned());
                    i = i + 1;
                }
            }
        };
    }

    fn split_on_last_pipe(cmd_line: &str) -> ~[~str] {
        return cmd_line.rsplitn('|', 1).filter_map(|x| Some(x.trim().to_owned())).to_owned_vec();
    }

    fn get_input_file_contents(cmd_line: &str) -> Option<~str> {
        return match cmd_line.splitn('<', 1).nth(1) {
            Some(inputFileCandidate) => {
                match inputFileCandidate.trim().splitn(' ', 1).nth(0) {
                    Some(inputFile) => {
                        match File::open(&Path::new(inputFile)) {
                            Some(mut file) => {
                                Some(file.read_to_str())
                            }
                            None => {
                                println!("File {:s} does not exist", inputFile);
                                None
                            }
                        }
                    }
                    None => { None }
                }
            }
            None => { None }
        };
    }

    fn get_output_file(cmd_line: &str) -> Option<~str> {
        return match cmd_line.splitn('>', 1).nth(1) {
            Some(inputFileCandidate) => {
                match inputFileCandidate.trim().splitn(' ', 1).nth(0) {
                    Some(inputFile) => { Some(inputFile.to_owned()) }
                    None => { None }
                }
            }
            None => { None }
        };
    }

    fn get_args_no_redirects(cmd_line: &str) -> ~[~str] {
        let mut activeRedirect = false;
        return cmd_line.split(' ').filter_map(|x| if x == ">" || x == "<" {
            activeRedirect = true;
            None
        } else if x == "" {
            None
        } else if activeRedirect {
            activeRedirect = false;
            None
        } else {
            Some(x.to_owned())
        }).to_owned_vec();
    }

    fn get_args(cmd_line: &str) -> ~[~str] {
        return cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::run_cmdline_single(cmd_line),
        None           => Shell::new("gash > ").run()
    }
}
<|endoftext|>


<commit_before>use ethereum_types::H512;
use hex_literal::hex;
use libsecp256k1::SecretKey;
use rand::rngs::OsRng;
use rlpx::ecies::ECIESStream;
use tokio::net::TcpStream;

// const REMOTE_ID: H512 = H512(hex!("589e7485b1d29a06c86827aa9e8c3d4a5f7c6dce25aca3202a46f5a038be0cfdc1b7aa1c172656bc1f3d82e49b1e2ac73276ba9953a232651f69c593c83315da"));
const REMOTE_ID: H512 = H512(hex!("bf05c3987d3bfcbb5c24cc389a7dcf31798d35e826a4147d9e49d2f8b056fcb17ff05d6fe32739b8552985e2c41c2324911007ddb5a0c487b7dca3b44aa5a7ae"));

#[tokio::main]
async fn main() {
    let _ = env_logger::init();

    ECIESStream::connect(
        TcpStream::connect("127.0.0.1:30303").await.unwrap(),
        SecretKey::random(&mut OsRng),
        REMOTE_ID,
    )
    .await
    .unwrap();
}
<commit_msg>handshake: real bootnode<commit_after>use ethereum_types::H512;
use hex_literal::hex;
use libsecp256k1::SecretKey;
use rand::rngs::OsRng;
use rlpx::ecies::ECIESStream;
use tokio::net::TcpStream;

const REMOTE_ID: H512 = H512(hex!("d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666 "));

#[tokio::main]
async fn main() {
    let _ = env_logger::init();

    ECIESStream::connect(
        TcpStream::connect("18.138.108.67:30303").await.unwrap(),
        SecretKey::random(&mut OsRng),
        REMOTE_ID,
    )
    .await
    .unwrap();
}
<|endoftext|>


<commit_before>extern crate docopt;
extern crate flac;
extern crate hound;
extern crate nom;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::Stream;

use std::env;
use std::error::Error;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

const USAGE: &'static str = "
Usage: decode <input> <output>
       decode <input>... <dir>
       decode --help

Options:
  -h, --help   Show this message.
";

#[derive(RustcDecodable)]
struct Arguments {
  arg_input: Vec<String>,
  arg_output: Option<String>,
  arg_dir: Option<String>,
}

fn decode_file(input_file: &str, output_file: &str)
               -> Result<(), hound::Error> {
  let mut stream = try! {
    Stream::from_file(input_file).map_err(hound::Error::IoError)
  };

  let info = stream.info();
  let spec = hound::WavSpec {
    channels: info.channels as u16,
    sample_rate: info.sample_rate,
    bits_per_sample: info.bits_per_sample as u16,
  };

  let mut output = try!(hound::WavWriter::create(output_file, spec));

  for sample in stream.iter() {
    try!(output.write_sample(sample));
  }

  output.finalize()
}

fn to_output_file(buffer: &mut PathBuf, path: &Path, directory: &str)
                  -> Result<(), hound::Error> {
  buffer.push(directory);

  path.file_name().map(|name| {
    buffer.push(name);
    buffer.set_extension("wav");
  }).ok_or_else(|| {
    let kind    = io::ErrorKind::NotFound;
    let message = "no file name found";
    let error   = io::Error::new(kind, message);

    hound::Error::IoError(error)
  })
}

fn decode_all_files(input_files: &Vec<String>, directory: &str)
                    -> Result<(), hound::Error> {
  let dir_path = Path::new(directory);

  if !dir_path.exists() {
    try!(fs::create_dir(dir_path).map_err(hound::Error::IoError))
  }

  for ref input_file in input_files {
    let mut buffer = PathBuf::new();
    let path       = Path::new(input_file);

    try!(to_output_file(&mut buffer, path, directory));

    let output_file = try! {
      buffer.to_str().ok_or_else(|| {
        let kind    = io::ErrorKind::InvalidInput;
        let message = "invalid unicode with file path";
        let error   = io::Error::new(kind, message);

        hound::Error::IoError(error)
      })
    };

    let result = decode_file(input_file, output_file);

    if result.is_ok() {
      println!("decoded: {} -> {}", input_file, output_file);
    } else {
      return result;
    }
  }

  Ok(())
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.argv(env::args()).decode())
    .unwrap_or_else(|e| e.exit());

  if let Some(ref output_file) = args.arg_output {
    let input_file = &args.arg_input[0];

    if let Err(e) = decode_file(input_file, output_file) {
      println!("{:?}", e);
    } else {
      println!("decoded: {} -> {}", input_file, output_file);
    }
  } else if let Some(ref directory) = args.arg_dir {
    if let Err(e) = decode_all_files(&args.arg_input, directory) {
      println!("{:?}", e);
    }
  }
}
<commit_msg>Implicitly convert to Iterator in for loop<commit_after>extern crate docopt;
extern crate flac;
extern crate hound;
extern crate nom;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::Stream;

use std::env;
use std::error::Error;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

const USAGE: &'static str = "
Usage: decode <input> <output>
       decode <input>... <dir>
       decode --help

Options:
  -h, --help   Show this message.
";

#[derive(RustcDecodable)]
struct Arguments {
  arg_input: Vec<String>,
  arg_output: Option<String>,
  arg_dir: Option<String>,
}

fn decode_file(input_file: &str, output_file: &str)
               -> Result<(), hound::Error> {
  let mut stream = try! {
    Stream::from_file(input_file).map_err(hound::Error::IoError)
  };

  let info = stream.info();
  let spec = hound::WavSpec {
    channels: info.channels as u16,
    sample_rate: info.sample_rate,
    bits_per_sample: info.bits_per_sample as u16,
  };

  let mut output = try!(hound::WavWriter::create(output_file, spec));

  for sample in &mut stream {
    try!(output.write_sample(sample));
  }

  output.finalize()
}

fn to_output_file(buffer: &mut PathBuf, path: &Path, directory: &str)
                  -> Result<(), hound::Error> {
  buffer.push(directory);

  path.file_name().map(|name| {
    buffer.push(name);
    buffer.set_extension("wav");
  }).ok_or_else(|| {
    let kind    = io::ErrorKind::NotFound;
    let message = "no file name found";
    let error   = io::Error::new(kind, message);

    hound::Error::IoError(error)
  })
}

fn decode_all_files(input_files: &Vec<String>, directory: &str)
                    -> Result<(), hound::Error> {
  let dir_path = Path::new(directory);

  if !dir_path.exists() {
    try!(fs::create_dir(dir_path).map_err(hound::Error::IoError))
  }

  for ref input_file in input_files {
    let mut buffer = PathBuf::new();
    let path       = Path::new(input_file);

    try!(to_output_file(&mut buffer, path, directory));

    let output_file = try! {
      buffer.to_str().ok_or_else(|| {
        let kind    = io::ErrorKind::InvalidInput;
        let message = "invalid unicode with file path";
        let error   = io::Error::new(kind, message);

        hound::Error::IoError(error)
      })
    };

    let result = decode_file(input_file, output_file);

    if result.is_ok() {
      println!("decoded: {} -> {}", input_file, output_file);
    } else {
      return result;
    }
  }

  Ok(())
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.argv(env::args()).decode())
    .unwrap_or_else(|e| e.exit());

  if let Some(ref output_file) = args.arg_output {
    let input_file = &args.arg_input[0];

    if let Err(e) = decode_file(input_file, output_file) {
      println!("{:?}", e);
    } else {
      println!("decoded: {} -> {}", input_file, output_file);
    }
  } else if let Some(ref directory) = args.arg_dir {
    if let Err(e) = decode_all_files(&args.arg_input, directory) {
      println!("{:?}", e);
    }
  }
}
<|endoftext|>