<commit_before>//! API to invoke `protoc` command.
//!
//! `protoc` command must be in `$PATH`, along with `protoc-gen-LANG` command.
//!
//! Note that to generate `rust` code from `.proto` files, `protoc-rust` crate
//! can be used, which does not require `protoc-gen-rust` present in `$PATH`.

#![deny(missing_docs)]

use std::ffi::{OsStr, OsString};
use std::fmt;
use std::path::{Path, PathBuf};
use std::process;
use std::{env, io};

#[macro_use]
extern crate log;
extern crate which;

/// Alias for io::Error
pub type Error = io::Error;
/// Alias for io::Result
pub type Result<T> = io::Result<T>;

fn err_other(s: impl AsRef<str>) -> Error {
    Error::new(io::ErrorKind::Other, s.as_ref().to_owned())
}

/// `Protoc --lang_out...` args
#[derive(Default)]
pub struct Args {
    protoc: Option<Protoc>,
    /// `LANG` part in `--LANG_out=...`
    lang: Option<String>,
    /// `--LANG_out=...` param
    out_dir: Option<PathBuf>,
    /// `--plugin` param. Not needed if plugin is in `$PATH`
    plugin: Option<OsString>,
    /// `-I` args
    includes: Vec<PathBuf>,
    /// List of `.proto` files to compile
    inputs: Vec<PathBuf>,
}

impl Args {
    /// Arguments to the `protoc` found in `$PATH`
    pub fn new() -> Self {
        Self::default()
    }

    /// Set `LANG` part in `--LANG_out=...`
    pub fn lang(&mut self, lang: &str) -> &mut Self {
        self.lang = Some(lang.to_owned());
        self
    }

    /// Set `--LANG_out=...` param
    pub fn out_dir(&mut self, out_dir: impl AsRef<Path>) -> &mut Self {
        self.out_dir = Some(out_dir.as_ref().to_owned());
        self
    }

    /// Set `--plugin` param. Not needed if plugin is in `$PATH`
    pub fn plugin(&mut self, plugin: impl AsRef<OsStr>) -> &mut Self {
        self.plugin = Some(plugin.as_ref().to_owned());
        self
    }

    /// Append a path to `-I` args
    pub fn include(&mut self, include: impl AsRef<Path>) -> &mut Self {
        self.includes.push(include.as_ref().to_owned());
        self
    }

    /// Append multiple paths to `-I` args
    pub fn includes(&mut self, includes: impl IntoIterator<Item = impl AsRef<Path>>) -> &mut Self {
        for include in includes {
            self.include(include);
        }
        self
    }

    /// Append a `.proto` file path to compile
    pub fn input(&mut self, input: impl AsRef<Path>) -> &mut Self {
        self.inputs.push(input.as_ref().to_owned());
        self
    }

    /// Append multiple `.proto` file paths to compile
    pub fn inputs(&mut self, inputs: impl IntoIterator<Item = impl AsRef<Path>>) -> &mut Self {
        for input in inputs {
            self.input(input);
        }
        self
    }

    /// Execute `protoc` with given args
    pub fn run(&self) -> Result<()> {
        let protoc = match &self.protoc {
            Some(protoc) => protoc.clone(),
            None => {
                let protoc = Protoc::from_env_path();
                // Check with have good `protoc`
                protoc.check()?;
                protoc
            }
        };

        if self.inputs.is_empty() {
            return Err(err_other("input is empty"));
        }

        let out_dir = self
            .out_dir
            .as_ref()
            .ok_or_else(|| err_other("out_dir is empty"))?;
        let lang = self
            .lang
            .as_ref()
            .ok_or_else(|| err_other("lang is empty"))?;

        // --{lang}_out={out_dir}
        let mut lang_out_flag = OsString::from("--");
        lang_out_flag.push(lang);
        lang_out_flag.push("_out=");
        lang_out_flag.push(out_dir);

        // --plugin={plugin}
        let plugin_flag = self.plugin.as_ref().map(|plugin| {
            let mut flag = OsString::from("--plugin=");
            flag.push(plugin);
            flag
        });

        // -I{include}
        let include_flags = self.includes.iter().map(|include| {
            let mut flag = OsString::from("-I");
            flag.push(include);
            flag
        });

        let mut cmd_args = Vec::new();
        cmd_args.push(lang_out_flag);
        cmd_args.extend(self.inputs.iter().map(|path| path.as_os_str().to_owned()));
        cmd_args.extend(plugin_flag);
        cmd_args.extend(include_flags);
        protoc.run_with_args(cmd_args)
    }
}

/// `Protoc --descriptor_set_out...` args
#[derive(Debug)]
pub struct DescriptorSetOutArgs {
    protoc: Protoc,
    /// `--file_descriptor_out=...` param
    out: Option<PathBuf>,
    /// `-I` args
    includes: Vec<PathBuf>,
    /// List of `.proto` files to compile
    inputs: Vec<PathBuf>,
    /// `--include_imports`
    include_imports: bool,
}

impl DescriptorSetOutArgs {
    /// Set `--file_descriptor_out=...` param
    pub fn out(&mut self, out: impl AsRef<Path>) -> &mut Self {
        self.out = Some(out.as_ref().to_owned());
        self
    }

    /// Append a path to `-I` args
    pub fn include(&mut self, include: impl AsRef<Path>) -> &mut Self {
        self.includes.push(include.as_ref().to_owned());
        self
    }

    /// Append multiple paths to `-I` args
    pub fn includes(&mut self, includes: impl IntoIterator<Item = impl AsRef<Path>>) -> &mut Self {
        for include in includes {
            self.include(include);
        }
        self
    }

    /// Append a `.proto` file path to compile
    pub fn input(&mut self, input: impl AsRef<Path>) -> &mut Self {
        self.inputs.push(input.as_ref().to_owned());
        self
    }

    /// Append multiple `.proto` file paths to compile
    pub fn inputs(&mut self, inputs: impl IntoIterator<Item = impl AsRef<Path>>) -> &mut Self {
        for input in inputs {
            self.input(input);
        }
        self
    }

    /// Set `--include_imports`
    pub fn include_imports(&mut self, include_imports: bool) -> &mut Self {
        self.include_imports = include_imports;
        self
    }

    /// Execute `protoc --descriptor_set_out=`
    pub fn write_descriptor_set(&self) -> Result<()> {
        if self.inputs.is_empty() {
            return Err(err_other("input is empty"));
        }

        let out = self.out.as_ref().ok_or_else(|| err_other("out is empty"))?;

        // -I{include}
        let include_flags = self.includes.iter().map(|include| {
            let mut flag = OsString::from("-I");
            flag.push(include);
            flag
        });

        // --descriptor_set_out={out}
        let mut descriptor_set_out_flag = OsString::from("--descriptor_set_out=");
        descriptor_set_out_flag.push(out);

        // --include_imports
        let include_imports_flag = match self.include_imports {
            false => None,
            true => Some("--include_imports".into()),
        };

        let mut cmd_args = Vec::new();
        cmd_args.extend(include_flags);
        cmd_args.push(descriptor_set_out_flag);
        cmd_args.extend(include_imports_flag);
        cmd_args.extend(self.inputs.iter().map(|path| path.as_os_str().to_owned()));
        self.protoc.run_with_args(cmd_args)
    }
}

/// Protoc command.
#[derive(Clone, Debug)]
pub struct Protoc {
    exec: OsString,
}

impl Protoc {
    /// New `protoc` command from `$PATH`
    pub fn from_env_path() -> Protoc {
        if let Ok(path) = which::which("protoc") {
            Protoc {
                exec: path.into_os_string(),
            }
        } else {
            let protoc_bin_name = match (env::consts::OS, env::consts::ARCH) {
                ("linux", "x86") => "protoc-linux-x86_32",
                ("linux", "x86_64") => "protoc-linux-x86_64",
                ("linux", "aarch64") => "protoc-linux-aarch_64",
                ("linux", "powerpc64") => "protoc-linux-ppcle_64",
                ("macos", "x86_64") => "protoc-osx-x86_64",
                ("windows", _) => "protoc-win32.exe",
                (os, arch) => panic!("protoc can't be found for your platform {}-{}", os, arch),
            };
            let bin_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
                .join("bin")
                .join(protoc_bin_name);
            assert!(bin_path.exists(), "internal: protoc not found {}", protoc_bin_name);
            Protoc {
                exec: bin_path.into_os_string(),
            }
        }
    }

    /// New `protoc` command from specified path
    pub fn from_path(path: impl AsRef<OsStr>) -> Protoc {
        Protoc {
            exec: path.as_ref().to_owned(),
        }
    }

    /// Check `protoc` command found and valid
    pub fn check(&self) -> Result<()> {
        self.version().map(|_| ())
    }

    fn spawn(&self, cmd: &mut process::Command) -> io::Result<process::Child> {
        info!("spawning command {:?}", cmd);

        cmd.spawn()
            .map_err(|e| Error::new(e.kind(), format!("failed to spawn `{:?}`: {}", cmd, e)))
    }

    /// Obtain `protoc` version
    pub fn version(&self) -> Result<Version> {
        let child = self.spawn(
            process::Command::new(&self.exec)
                .stdin(process::Stdio::null())
                .stdout(process::Stdio::piped())
                .stderr(process::Stdio::piped())
                .args(&["--version"]),
        )?;

        let output = child.wait_with_output()?;
        if !output.status.success() {
            return Err(err_other("protoc failed with error"));
        }
        let output =
            String::from_utf8(output.stdout).map_err(|e| Error::new(io::ErrorKind::Other, e))?;
        let output = match output.lines().next() {
            None => return Err(err_other("output is empty")),
            Some(line) => line,
        };
        let prefix = "libprotoc ";
        if !output.starts_with(prefix) {
            return Err(err_other("output does not start with prefix"));
        }
        let output = &output[prefix.len()..];
        if output.is_empty() {
            return Err(err_other("version is empty"));
        }
        let first = output.chars().next().unwrap();
        if !first.is_digit(10) {
            return Err(err_other("version does not start with digit"));
        }
        Ok(Version {
            version: output.to_owned(),
        })
    }

    /// Execute `protoc` command with given args, check it completed correctly.
    fn run_with_args(&self, args: Vec<OsString>) -> Result<()> {
        let mut cmd = process::Command::new(&self.exec);
        cmd.stdin(process::Stdio::null());
        cmd.args(args);

        let mut child = self.spawn(&mut cmd)?;

        if !child.wait()?.success() {
            return Err(err_other(format!(
                "protoc ({:?}) exited with non-zero exit code",
                cmd
            )));
        }

        Ok(())
    }

    /// Get default Args for this command.
    pub fn args(&self) -> Args {
        Args {
            protoc: Some(self.clone()),
            ..Args::new()
        }
    }

    /// Get default DescriptorSetOutArgs for this command.
    pub fn descriptor_set_out_args(&self) -> DescriptorSetOutArgs {
        DescriptorSetOutArgs {
            protoc: self.clone(),
            out: None,
            includes: Vec::new(),
            inputs: Vec::new(),
            include_imports: false,
        }
    }
}

/// Protobuf (protoc) version.
pub struct Version {
    version: String,
}

impl Version {
    /// `true` if the protoc major version is 3.
    pub fn is_3(&self) -> bool {
        self.version.starts_with("3")
    }
}

impl fmt::Display for Version {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.version, f)
    }
}

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

    #[test]
    fn version() {
        Protoc::from_env_path().version().expect("version");
    }
}
<commit_msg>Minor cleanup; preparation to implement issue #481<commit_after>//! API to invoke `protoc` command.
//!
//! `protoc` command must be in `$PATH`, along with `protoc-gen-LANG` command.
//!
//! Note that to generate `rust` code from `.proto` files, `protoc-rust` crate
//! can be used, which does not require `protoc-gen-rust` present in `$PATH`.

#![deny(missing_docs)]

use std::ffi::{OsStr, OsString};
use std::fmt;
use std::path::{Path, PathBuf};
use std::process;
use std::{env, io};

#[macro_use]
extern crate log;
extern crate which;

/// Alias for io::Error
pub type Error = io::Error;
/// Alias for io::Result
pub type Result<T> = io::Result<T>;

fn err_other(s: impl AsRef<str>) -> Error {
    Error::new(io::ErrorKind::Other, s.as_ref().to_owned())
}

/// `Protoc --lang_out...` args
#[derive(Default)]
pub struct Args {
    protoc: Option<Protoc>,
    /// `LANG` part in `--LANG_out=...`
    lang: Option<String>,
    /// `--LANG_out=...` param
    out_dir: Option<PathBuf>,
    /// `--plugin` param. Not needed if plugin is in `$PATH`
    plugin: Option<OsString>,
    /// `-I` args
    includes: Vec<PathBuf>,
    /// List of `.proto` files to compile
    inputs: Vec<PathBuf>,
}

impl Args {
    /// Arguments to the `protoc` found in `$PATH`
    pub fn new() -> Self {
        Self::default()
    }

    /// Set `LANG` part in `--LANG_out=...`
    pub fn lang(&mut self, lang: &str) -> &mut Self {
        self.lang = Some(lang.to_owned());
        self
    }

    /// Set `--LANG_out=...` param
    pub fn out_dir(&mut self, out_dir: impl AsRef<Path>) -> &mut Self {
        self.out_dir = Some(out_dir.as_ref().to_owned());
        self
    }

    /// Set `--plugin` param. Not needed if plugin is in `$PATH`
    pub fn plugin(&mut self, plugin: impl AsRef<OsStr>) -> &mut Self {
        self.plugin = Some(plugin.as_ref().to_owned());
        self
    }

    /// Append a path to `-I` args
    pub fn include(&mut self, include: impl AsRef<Path>) -> &mut Self {
        self.includes.push(include.as_ref().to_owned());
        self
    }

    /// Append multiple paths to `-I` args
    pub fn includes(&mut self, includes: impl IntoIterator<Item = impl AsRef<Path>>) -> &mut Self {
        for include in includes {
            self.include(include);
        }
        self
    }

    /// Append a `.proto` file path to compile
    pub fn input(&mut self, input: impl AsRef<Path>) -> &mut Self {
        self.inputs.push(input.as_ref().to_owned());
        self
    }

    /// Append multiple `.proto` file paths to compile
    pub fn inputs(&mut self, inputs: impl IntoIterator<Item = impl AsRef<Path>>) -> &mut Self {
        for input in inputs {
            self.input(input);
        }
        self
    }

    /// Execute `protoc` with given args
    pub fn run(&self) -> Result<()> {
        let protoc = match &self.protoc {
            Some(protoc) => protoc.clone(),
            None => {
                let protoc = Protoc::from_env_path();
                // Check with have good `protoc`
                protoc.check()?;
                protoc
            }
        };

        if self.inputs.is_empty() {
            return Err(err_other("input is empty"));
        }

        let out_dir = self
            .out_dir
            .as_ref()
            .ok_or_else(|| err_other("out_dir is empty"))?;
        let lang = self
            .lang
            .as_ref()
            .ok_or_else(|| err_other("lang is empty"))?;

        // --{lang}_out={out_dir}
        let mut lang_out_flag = OsString::from("--");
        lang_out_flag.push(lang);
        lang_out_flag.push("_out=");
        lang_out_flag.push(out_dir);

        // --plugin={plugin}
        let plugin_flag = self.plugin.as_ref().map(|plugin| {
            let mut flag = OsString::from("--plugin=");
            flag.push(plugin);
            flag
        });

        // -I{include}
        let include_flags = self.includes.iter().map(|include| {
            let mut flag = OsString::from("-I");
            flag.push(include);
            flag
        });

        let mut cmd_args = Vec::new();
        cmd_args.push(lang_out_flag);
        cmd_args.extend(self.inputs.iter().map(|path| path.as_os_str().to_owned()));
        cmd_args.extend(plugin_flag);
        cmd_args.extend(include_flags);
        protoc.run_with_args(cmd_args)
    }
}

/// `Protoc --descriptor_set_out...` args
#[derive(Debug)]
pub struct DescriptorSetOutArgs {
    protoc: Protoc,
    /// `--file_descriptor_out=...` param
    out: Option<PathBuf>,
    /// `-I` args
    includes: Vec<PathBuf>,
    /// List of `.proto` files to compile
    inputs: Vec<PathBuf>,
    /// `--include_imports`
    include_imports: bool,
}

impl DescriptorSetOutArgs {
    /// Set `--file_descriptor_out=...` param
    pub fn out(&mut self, out: impl AsRef<Path>) -> &mut Self {
        self.out = Some(out.as_ref().to_owned());
        self
    }

    /// Append a path to `-I` args
    pub fn include(&mut self, include: impl AsRef<Path>) -> &mut Self {
        self.includes.push(include.as_ref().to_owned());
        self
    }

    /// Append multiple paths to `-I` args
    pub fn includes(&mut self, includes: impl IntoIterator<Item = impl AsRef<Path>>) -> &mut Self {
        for include in includes {
            self.include(include);
        }
        self
    }

    /// Append a `.proto` file path to compile
    pub fn input(&mut self, input: impl AsRef<Path>) -> &mut Self {
        self.inputs.push(input.as_ref().to_owned());
        self
    }

    /// Append multiple `.proto` file paths to compile
    pub fn inputs(&mut self, inputs: impl IntoIterator<Item = impl AsRef<Path>>) -> &mut Self {
        for input in inputs {
            self.input(input);
        }
        self
    }

    /// Set `--include_imports`
    pub fn include_imports(&mut self, include_imports: bool) -> &mut Self {
        self.include_imports = include_imports;
        self
    }

    /// Execute `protoc --descriptor_set_out=`
    pub fn write_descriptor_set(&self) -> Result<()> {
        if self.inputs.is_empty() {
            return Err(err_other("input is empty"));
        }

        let out = self.out.as_ref().ok_or_else(|| err_other("out is empty"))?;

        // -I{include}
        let include_flags = self.includes.iter().map(|include| {
            let mut flag = OsString::from("-I");
            flag.push(include);
            flag
        });

        // --descriptor_set_out={out}
        let mut descriptor_set_out_flag = OsString::from("--descriptor_set_out=");
        descriptor_set_out_flag.push(out);

        // --include_imports
        let include_imports_flag = match self.include_imports {
            false => None,
            true => Some("--include_imports".into()),
        };

        let mut cmd_args = Vec::new();
        cmd_args.extend(include_flags);
        cmd_args.push(descriptor_set_out_flag);
        cmd_args.extend(include_imports_flag);
        cmd_args.extend(self.inputs.iter().map(|path| path.as_os_str().to_owned()));
        self.protoc.run_with_args(cmd_args)
    }
}

/// Protoc command.
#[derive(Clone, Debug)]
pub struct Protoc {
    exec: OsString,
}

impl Protoc {
    /// New `protoc` command from `$PATH`
    pub fn from_env_path() -> Protoc {
        if let Ok(path) = which::which("protoc") {
            Protoc {
                exec: path.into_os_string(),
            }
        } else {
            Protoc {
                exec: protoc_binary_vendored().into_os_string(),
            }
        }
    }

    /// New `protoc` command from specified path
    pub fn from_path(path: impl AsRef<OsStr>) -> Protoc {
        Protoc {
            exec: path.as_ref().to_owned(),
        }
    }

    /// Check `protoc` command found and valid
    pub fn check(&self) -> Result<()> {
        self.version().map(|_| ())
    }

    fn spawn(&self, cmd: &mut process::Command) -> io::Result<process::Child> {
        info!("spawning command {:?}", cmd);

        cmd.spawn()
            .map_err(|e| Error::new(e.kind(), format!("failed to spawn `{:?}`: {}", cmd, e)))
    }

    /// Obtain `protoc` version
    pub fn version(&self) -> Result<Version> {
        let child = self.spawn(
            process::Command::new(&self.exec)
                .stdin(process::Stdio::null())
                .stdout(process::Stdio::piped())
                .stderr(process::Stdio::piped())
                .args(&["--version"]),
        )?;

        let output = child.wait_with_output()?;
        if !output.status.success() {
            return Err(err_other("protoc failed with error"));
        }
        let output =
            String::from_utf8(output.stdout).map_err(|e| Error::new(io::ErrorKind::Other, e))?;
        let output = match output.lines().next() {
            None => return Err(err_other("output is empty")),
            Some(line) => line,
        };
        let prefix = "libprotoc ";
        if !output.starts_with(prefix) {
            return Err(err_other("output does not start with prefix"));
        }
        let output = &output[prefix.len()..];
        if output.is_empty() {
            return Err(err_other("version is empty"));
        }
        let first = output.chars().next().unwrap();
        if !first.is_digit(10) {
            return Err(err_other("version does not start with digit"));
        }
        Ok(Version {
            version: output.to_owned(),
        })
    }

    /// Execute `protoc` command with given args, check it completed correctly.
    fn run_with_args(&self, args: Vec<OsString>) -> Result<()> {
        let mut cmd = process::Command::new(&self.exec);
        cmd.stdin(process::Stdio::null());
        cmd.args(args);

        let mut child = self.spawn(&mut cmd)?;

        if !child.wait()?.success() {
            return Err(err_other(format!(
                "protoc ({:?}) exited with non-zero exit code",
                cmd
            )));
        }

        Ok(())
    }

    /// Get default Args for this command.
    pub fn args(&self) -> Args {
        Args {
            protoc: Some(self.clone()),
            ..Args::new()
        }
    }

    /// Get default DescriptorSetOutArgs for this command.
    pub fn descriptor_set_out_args(&self) -> DescriptorSetOutArgs {
        DescriptorSetOutArgs {
            protoc: self.clone(),
            out: None,
            includes: Vec::new(),
            inputs: Vec::new(),
            include_imports: false,
        }
    }
}

fn protoc_binary_vendored() -> PathBuf {
    let protoc_bin_name = match (env::consts::OS, env::consts::ARCH) {
        ("linux", "x86") => "protoc-linux-x86_32",
        ("linux", "x86_64") => "protoc-linux-x86_64",
        ("linux", "aarch64") => "protoc-linux-aarch_64",
        ("linux", "powerpc64") => "protoc-linux-ppcle_64",
        ("macos", "x86_64") => "protoc-osx-x86_64",
        ("windows", _) => "protoc-win32.exe",
        (os, arch) => panic!("protoc can't be found for your platform {}-{}", os, arch),
    };
    let protoc_bin_path = Path::new(env!("CARGO_MANIFEST_DIR"))
        .join("bin")
        .join(protoc_bin_name);
    assert!(
        protoc_bin_path.exists(),
        "internal: protoc not found {}",
        protoc_bin_name
    );
    protoc_bin_path
}

/// Protobuf (protoc) version.
pub struct Version {
    version: String,
}

impl Version {
    /// `true` if the protoc major version is 3.
    pub fn is_3(&self) -> bool {
        self.version.starts_with("3")
    }
}

impl fmt::Display for Version {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.version, f)
    }
}

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

    #[test]
    fn version() {
        Protoc::from_env_path().version().expect("version");
    }
}
<|endoftext|>


<commit_before>//
// zhtta.rs
//
// Running on Rust 0.8
//
// Starting code for PS3
//
// Note: it would be very unwise to run this server on a machine that is
// on the Internet and contains any sensitive files!
//
// University of Virginia - cs4414 Fall 2013
// Weilin Xu and David Evans
// Version 0.3

extern mod extra;

use std::rt::io::*;
use std::rt::io::net::ip::SocketAddr;
use std::io::println;
use std::cell::Cell;
use std::{os, str, io};
use extra::arc;
use extra::time;
use std::comm::*;
use std::hashmap::HashMap;

use std::rt::io::net::tcp::TcpStream;
use std::cmp::Ord;

use extra::priority_queue::*;

static PORT: int = 4414;
static IP: &'static str = "127.0.0.1";

struct sched_msg {
    stream: Option<std::rt::io::net::tcp::TcpStream>,
    filepath: ~std::path::PosixPath,
    priority: uint  // @@@@@@@@@@@@@@@
}

impl std::cmp::Ord for sched_msg
{
	fn lt(&self, other: &sched_msg) -> bool { (*self).priority < (*other).priority }
	fn le(&self, other: &sched_msg) -> bool { (*self).priority <= (*other).priority }
	fn ge(&self, other: &sched_msg) -> bool { (*self).priority >= (*other).priority }
	fn gt(&self, other: &sched_msg) -> bool { (*self).priority > (*other).priority }
}

// determine if the request is from a Charlottesville client

fn is_Wahoo_Client(peer_addr: ~str) ->bool
{
        let WahooIPs: ~[~str] = ~[~"128.143.", ~"137.54."]; // probably add some more ip addresses on the way
        let mut isWahoo = false;
        let mut index = 0;

        while index < WahooIPs.len()
        {
                if peer_addr.starts_with(WahooIPs[index])
                {
                        isWahoo = true;
                        break;
                }
                index += 1;
        }
        //println( fmt!("is wahoo? : %?\n", isWahoo) );
        return isWahoo;
}

// get the size of a file

fn get_fileSize(file_path: &Path) -> int
{
        let mut filestream = std::rt::io::file::open(file_path, Open, Read);
        let mut size:int = 0;

        // find the File size
        match filestream{
                Some(ref mut reader) =>
                {
                        reader.seek(0,SeekEnd);
                        size = reader.tell() as int;
                        reader.seek(0, SeekSet); // rewind the file back

                        println(fmt!("\nfile size: %? bytes \n", size ));
                },
                None => { fail!("\nCannot read the storage file \n");},
        }
        return size;
}

fn main() {

    let visitor_count: uint = 0; // @@@@@@@

    let mut isWahoo: bool = false;

/*
    let req_vec: ~[sched_msg] = ~[];
    let shared_req_vec = arc::RWArc::new(req_vec);
    let add_vec = shared_req_vec.clone();
    let take_vec = shared_req_vec.clone();
*/

    /* replace data structure to priority queue (this is not the only region changed though) */

    let req_pq: PriorityQueue<sched_msg> = PriorityQueue::new();
    let shared_req_pq = arc::RWArc::new(req_pq);
    let add_pq = shared_req_pq.clone();
    let take_pq = shared_req_pq.clone();

    let (port, chan) = stream();
    let chan = SharedChan::new(chan);

    // dequeue file requests, and send responses.
    // FIFO
    do spawn {
        	let (sm_port, sm_chan) = stream();
        	let (sm_port2, sm_chan2) = stream();

        	// a task for sending responses.
        	do spawn {
         		let mut cache: HashMap<~str, ~[u8]> = std::hashmap::HashMap::new();
         		let mut cacheTimes: HashMap<~str, ~i64> = std::hashmap::HashMap::new();

            		loop {
                		sm_chan2.send(1);
               			let mut tf: sched_msg = sm_port.recv(); // wait for the dequeued request to handle

                		let modifiedTime = match file::stat(tf.filepath)
				{
                        		Some(s) => {s.modified}
                        		None 	=> {-1}
				};

                		if cache.contains_key_equiv(&tf.filepath.to_str()) &&
                           		*cacheTimes.get_copy(&tf.filepath.to_str()) as u64 > modifiedTime
				{
					println(fmt!("begin serving file [%?]", tf.filepath));
                        		// A web server should always reply a HTTP header for any legal HTTP request.
                        		tf.stream.write("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n".as_bytes());
                        		let data = cache.get_copy(&tf.filepath.to_str());
                        		tf.stream.write(data);
                        		println(fmt!("finish file [%?]", tf.filepath));
                		}
                		else {
                 			let file = io::read_whole_file(tf.filepath);

            	 			match file { // killed if file size is larger than memory size.

                         			Ok(file_data) =>
						{
                          				println(fmt!("begin serving file [%?]", tf.filepath));
                          				// A web server should always reply a HTTP header for any legal HTTP request.
                          				tf.stream.write("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n".as_bytes());
                                			tf.stream.write(file_data);
                                			println(fmt!("finish file [%?]", tf.filepath));
                                			cache.insert(tf.filepath.to_str(), file_data);
                                			cacheTimes.insert(tf.filepath.to_str(), ~time::get_time().sec);
                             			}
                             			Err(err) =>
						{	println(err);
						}
                    			}
                		} // else
           		} // loop
        	} // spawn (inner)

        loop {
	    sm_port2.recv();
            port.recv(); // wait for arrving notification
            do take_pq.write |priority_Q| {
                if ((*priority_Q).len() > 0) {
                    // LIFO didn't make sense in service scheduling, so we modify it as FIFO by using shift_opt() rather than pop().

		    //let tf_opt: Option<sched_msg> = (*priority_Q).pop();
                    let tf = (*priority_Q).pop();
                    println(fmt!("shift from queue, size: %ud", (*priority_Q).len()));    // ^^^^^^^^^^^^^^^^^^^ probably need to change it later
                    sm_chan.send(tf); // send the request to send-response-task to serve.
                }
            }
        }
    } // spawn (outer)

    let ip = match FromStr::from_str(IP) { Some(ip) => ip,
                                           None     => {println(fmt!("Error: Invalid IP address <%s>", IP));
                                                    	return;}
                                         };

    let socket = net::tcp::TcpListener::bind(SocketAddr {ip: ip, port: PORT as u16});

    println(fmt!("Listening on %s:%d ...", ip.to_str(), PORT));
    let mut acceptor = socket.listen().unwrap();

    let shared_count = arc::RWArc::new( visitor_count ); // @@@@@@

    for stream in acceptor.incoming() {
        let mut stream = stream; // @@@@@@
        let mut peer_addr: ~str = ~"";

        match stream {
                Some(ref mut s) =>
                {
                        match s.peer_name() {
                                Some(pn) =>
                                {   peer_addr = pn.to_str();
                                    println( fmt!("\nPeer address: %s", peer_addr ));
                                },
                                None     => ()
                        }
                }
                None => ()
        }

        isWahoo = is_Wahoo_Client(peer_addr);
        println( fmt!("is wahoo? : %?\n", isWahoo) );

        let stream = Cell::new(stream);

        let (count_port, count_chan): (Port< extra::arc::RWArc<uint> >, Chan< extra::arc::RWArc<uint> >) = std::comm::stream(); // @@@@@@
        let count_chan = SharedChan::new(count_chan); // @@@@@@
        count_chan.send(shared_count.clone() ); // @@@@@@

        // Start a new task to handle the connection
        let child_chan = chan.clone();
        let child_add_pq = add_pq.clone();

        do spawn {

         let shared_count_copy = count_port.recv(); // @@@@@@

         /* Get Write Access */
         do shared_count_copy.write |count|{
                        *count = *count + 1;
                        println( fmt!("count: %? \n", *count as int) );
         }

            let mut stream = stream.take();
            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);

            let req_group : ~[&str]= request_str.splitn_iter(' ', 3).collect();
            if req_group.len() > 2 {
                let path = req_group[1];
                println(fmt!("Request for path: \n%?", path));

                let file_path = ~os::getcwd().push(path.replace("/../", ""));

                if !os::path_exists(file_path) || os::path_is_dir(file_path)
                {
                    println(fmt!("Request received:\n%s", request_str));

                 	/* Get Read Access */
                	 do shared_count_copy.read |count|
                 	{
                           	let response: ~str = fmt!(
                        	"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                        	<doctype !html>
                        	<title>Hello, Rust!</title>

Greetings, Krusty!

Visitor count: %u

                        	\r\n", *count);
                        	stream.write(response.as_bytes());
                     	 }

                }
                else {
                    // Requests scheduling

                    let size:int = get_fileSize(file_path); // @@@@@@@@@@@

		    // ************ NOTE: Priority of the below message should be changed to take the lg() and multiply it by (-1),
                    // ************       but for now I keep it simple and just store the file size

                    let msg: sched_msg = sched_msg{stream: stream, filepath: file_path.clone(), priority: size as uint}; // NOTE

                    let (sm_port, sm_chan) = std::comm::stream();
                    sm_chan.send(msg);

                    do child_add_pq.write |priority_Q| {
                        let msg = sm_port.recv();
                        (*priority_Q).push(msg); // enqueue new request.
                        println("add to queue");
                    }
                    child_chan.send(""); //notify the new arriving request.

                    println(fmt!("get file request: %?", file_path));
                }
            }
            println!("connection terminates\n")
        }
    }
}

<commit_msg>implemented Shortest-Processing-Time-First scheduling and WahooFirst scheduling. But not tested with httperf yet<commit_after>//
// zhtta.rs
//
// Running on Rust 0.8
//
// Starting code for PS3
//
// Note: it would be very unwise to run this server on a machine that is
// on the Internet and contains any sensitive files!
//
// University of Virginia - cs4414 Fall 2013
// Weilin Xu and David Evans
// Version 0.3

extern mod extra;

use std::rt::io::*;
use std::rt::io::net::ip::SocketAddr;
use std::io::println;
use std::cell::Cell;
use std::{os, str, io};
use extra::arc;
use extra::time;
use std::comm::*;
use std::hashmap::HashMap;

use std::rt::io::net::tcp::TcpStream;
use std::cmp::Ord;
use std::num::log2;

use extra::priority_queue::*;

static PORT: int = 4414;
static IP: &'static str = "127.0.0.1";

struct sched_msg {
    stream: Option<std::rt::io::net::tcp::TcpStream>,
    filepath: ~std::path::PosixPath,
    priority: int  // @@@@@@@@@@@@@@@
}

impl std::cmp::Ord for sched_msg
{
	fn lt(&self, other: &sched_msg) -> bool { (*self).priority < (*other).priority }
	fn le(&self, other: &sched_msg) -> bool { (*self).priority <= (*other).priority }
	fn ge(&self, other: &sched_msg) -> bool { (*self).priority >= (*other).priority }
	fn gt(&self, other: &sched_msg) -> bool { (*self).priority > (*other).priority }
}

// determine if the request is from a Charlottesville client

fn is_Wahoo_Client(peer_addr: ~str) ->bool
{
        let WahooIPs: ~[~str] = ~[~"128.143.", ~"137.54."]; // probably add some more ip addresses on the way
        let mut isWahoo = false;
        let mut index = 0;

        while index < WahooIPs.len()
        {
                if peer_addr.starts_with(WahooIPs[index])
                {
                        isWahoo = true;
                        break;
                }
                index += 1;
        }
        //println( fmt!("is wahoo? : %?\n", isWahoo) );
        return isWahoo;
}

// get the size of a file

fn get_fileSize(file_path: &Path) -> int
{
        let mut filestream = std::rt::io::file::open(file_path, Open, Read);
        let mut size:int = 0;

        // find the File size
        match filestream{
                Some(ref mut reader) =>
                {
                        reader.seek(0,SeekEnd);
                        size = reader.tell() as int;
                        reader.seek(0, SeekSet); // rewind the file back

                        println(fmt!("\nfile size: %? bytes \n", size ));
                },
                None => { fail!("\nCannot read the storage file \n");},
        }
        return size;
}

fn main() {

    let visitor_count: uint = 0; // @@@@@@@

/*
    let req_vec: ~[sched_msg] = ~[];
    let shared_req_vec = arc::RWArc::new(req_vec);
    let add_vec = shared_req_vec.clone();
    let take_vec = shared_req_vec.clone();
*/

    /* replace data structure to priority queue (this is not the only region changed though) */

    let req_pq: PriorityQueue<sched_msg> = PriorityQueue::new();
    let shared_req_pq = arc::RWArc::new(req_pq);
    let add_pq = shared_req_pq.clone();
    let take_pq = shared_req_pq.clone();

    let (port, chan) = stream();
    let chan = SharedChan::new(chan);

    // dequeue file requests, and send responses.
    // FIFO
    do spawn {
        	let (sm_port, sm_chan) = stream();
        	let (sm_port2, sm_chan2) = stream();

        	// a task for sending responses.
        	do spawn {
         		let mut cache: HashMap<~str, ~[u8]> = std::hashmap::HashMap::new();
         		let mut cacheTimes: HashMap<~str, ~i64> = std::hashmap::HashMap::new();

            		loop {
                		sm_chan2.send(1);
               			let mut tf: sched_msg = sm_port.recv(); // wait for the dequeued request to handle

                		let modifiedTime = match file::stat(tf.filepath)
				{
                        		Some(s) => {s.modified}
                        		None 	=> {-1}
				};

                		if cache.contains_key_equiv(&tf.filepath.to_str()) &&
                           		*cacheTimes.get_copy(&tf.filepath.to_str()) as u64 > modifiedTime
				{
					println(fmt!("begin serving file [%?]", tf.filepath));
                        		// A web server should always reply a HTTP header for any legal HTTP request.
                        		tf.stream.write("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n".as_bytes());
                        		let data = cache.get_copy(&tf.filepath.to_str());
                        		tf.stream.write(data);
                        		println(fmt!("finish file [%?]", tf.filepath));
                		}
                		else {
                 			let file = io::read_whole_file(tf.filepath);

            	 			match file { // killed if file size is larger than memory size.

                         			Ok(file_data) =>
						{
                          				println(fmt!("begin serving file [%?]", tf.filepath));
                          				// A web server should always reply a HTTP header for any legal HTTP request.
                          				tf.stream.write("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n".as_bytes());
                                			tf.stream.write(file_data);
                                			println(fmt!("finish file [%?]", tf.filepath));
                                			cache.insert(tf.filepath.to_str(), file_data);
                                			cacheTimes.insert(tf.filepath.to_str(), ~time::get_time().sec);
                             			}
                             			Err(err) =>
						{	println(err);
						}
                    			}
                		} // else
           		} // loop
        	} // spawn (inner)

        loop {
	    sm_port2.recv();
            port.recv(); // wait for arrving notification
            do take_pq.write |priority_Q| {
                if ((*priority_Q).len() > 0) {
                    // LIFO didn't make sense in service scheduling, so we modify it as FIFO by using shift_opt() rather than pop().

		    //let tf_opt: Option<sched_msg> = (*priority_Q).pop();
                    let tf = (*priority_Q).pop();
                    println(fmt!("shift from queue, size: %ud", (*priority_Q).len()));    // ^^^^^^^^^^^^^^^^^^^ probably need to change it later
                    sm_chan.send(tf); // send the request to send-response-task to serve.
                }
            }
        }
    } // spawn (outer)

    let ip = match FromStr::from_str(IP) { Some(ip) => ip,
                                           None     => {println(fmt!("Error: Invalid IP address <%s>", IP));
                                                    	return;}
                                         };

    let socket = net::tcp::TcpListener::bind(SocketAddr {ip: ip, port: PORT as u16});

    println(fmt!("Listening on %s:%d ...", ip.to_str(), PORT));
    let mut acceptor = socket.listen().unwrap();

    let shared_count = arc::RWArc::new( visitor_count ); // @@@@@@

    for stream in acceptor.incoming() {
        let mut stream = stream; // @@@@@@
        let mut peer_addr: ~str = ~"";

        match stream {
                Some(ref mut s) =>
                {
                        match s.peer_name() {
                                Some(pn) =>
                                {   peer_addr = pn.to_str();
                                    println( fmt!("\nPeer address: %s", peer_addr ));
                                },
                                None     => ()
                        }
                }
                None => ()
        }

        let isWahoo: bool = is_Wahoo_Client(peer_addr);
        println( fmt!("is wahoo? : %?\n", isWahoo) );

        let stream = Cell::new(stream);

        let (count_port, count_chan): (Port< extra::arc::RWArc<uint> >, Chan< extra::arc::RWArc<uint> >) = std::comm::stream(); // @@@@@@
        let count_chan = SharedChan::new(count_chan); // @@@@@@
        count_chan.send(shared_count.clone() ); // @@@@@@

        // Start a new task to handle the connection
        let child_chan = chan.clone();
        let child_add_pq = add_pq.clone();

        do spawn {

         let shared_count_copy = count_port.recv(); // @@@@@@

         /* Get Write Access */
         do shared_count_copy.write |count|{
                        *count = *count + 1;
                        println( fmt!("count: %? \n", *count as int) );
         }

            let mut stream = stream.take();
            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);

            let req_group : ~[&str]= request_str.splitn_iter(' ', 3).collect();
            if req_group.len() > 2 {
                let path = req_group[1];
                println(fmt!("Request for path: \n%?", path));

                let file_path = ~os::getcwd().push(path.replace("/../", ""));

                if !os::path_exists(file_path) || os::path_is_dir(file_path)
                {
                    println(fmt!("Request received:\n%s", request_str));

                 	/* Get Read Access */
                	 do shared_count_copy.read |count|
                 	{
                           	let response: ~str = fmt!(
                        	"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                        	<doctype !html>
                        	<title>Hello, Rust!</title>

Greetings, Krusty!

Visitor count: %u

                        	\r\n", *count);
                        	stream.write(response.as_bytes());
                     	 }

                }
                else {
                    // Requests scheduling

                    let file_size:int = get_fileSize(file_path); // @@@@@@@@@@@

		    // Rust 0.8 only provides a maximum priority queue
		    let mut adjusted_priority: int = (-1) * (log2( file_size as float) as int); // multiply priority by (-1) to use it as minimum priority queue

		    // Implement 'Wahoo-First' scheduling
		    if(isWahoo) { adjusted_priority += 3;}

                    let msg: sched_msg = sched_msg{stream: stream, filepath: file_path.clone(), priority: adjusted_priority };

                    let (sm_port, sm_chan) = std::comm::stream();
                    sm_chan.send(msg);

		    // Implement 'Shortest-Processing-Time-First' scheduling
                    do child_add_pq.write |priority_Q| {
                        let msg = sm_port.recv();
                        (*priority_Q).push(msg); // enqueue new request.
                        println("add to queue");
                    }
                    child_chan.send(""); //notify the new arriving request.

                    println(fmt!("get file request: %?", file_path));
                }
            }
            println!("connection terminates\n")
        }
    }
}

<|endoftext|>


<commit_before>use std::env;
use std::rc::Rc;
use std::cell::RefCell;
use sfml::graphics::{RenderWindow, RenderTarget, Font};
use sfml::window::{ContextSettings, VideoMode, Close};
use sfml::window::event;
use sfml::window::keyboard::Key;
use sfml::window::mouse::MouseButton;
use sfml::graphics::Color;
use sfml::system::vector2::Vector2i;
use na::{Pnt2, Pnt3, Iso2};
use na;
use nphysics::world::World;
use nphysics::object::RigidBody;
use nphysics::detection::joint::{Fixed, Anchor};
use camera::Camera;
use fps::Fps;
use engine::GraphicsManager;
use draw_helper;

fn usage(exe_name: &str) {
    println!("Usage: {} [OPTION] ", exe_name);
    println!("");
    println!("Options:");
    println!("    --help  - prints this help message and exits.");
    println!("    --pause - do not start the simulation right away.");
    println!("");
    println!("The following keyboard commands are supported:");
    println!("    t     - pause/continue the simulation.");
    println!("    s     - pause then execute only one simulation step.");
    println!("    space - display/hide contacts.");
}

#[derive(PartialEq)]
enum RunMode {
    Running,
    Stop,
    Step
}

pub struct Testbed<'a> {
    world:    World,
    window:   RenderWindow,
    graphics: GraphicsManager<'a>
}

impl<'a> Testbed<'a> {
    pub fn new_empty() -> Testbed<'a> {
        let mode    = VideoMode::new_init(800, 600, 32);
        let setting = ContextSettings {
            depth_bits:         10,
            stencil_bits:       10,
            antialiasing_level: 2,
            major_version:      0,
            minor_version:      1
        };
        let window =
            match RenderWindow::new(mode, "nphysics 2d demo", Close, &setting) {
                Some(rwindow) => rwindow,
                None          => panic!("Error on creating the sfml window.")
            };
        let graphics = GraphicsManager::new();

        Testbed {
            world:    World::new(),
            window:   window,
            graphics: graphics
        }
    }

    pub fn new(world: World) -> Testbed<'a> {
        let mut res = Testbed::new_empty();

        res.set_world(world);

        res
    }

    pub fn set_world(&mut self, world: World) {
        self.world = world;
        self.graphics.clear();

        for rb in self.world.bodies() {
            self.graphics.add(rb.clone());
        }
    }

    pub fn set_color(&mut self, body: &Rc<RefCell<RigidBody>>, color: Pnt3<f32>) {
        let color = Pnt3::new(
            (color.x * 255.0) as u8,
            (color.y * 255.0) as u8,
            (color.z * 255.0) as u8
        );

        self.graphics.set_color(body, color);
    }

    pub fn run(&mut self) {
        let mut args    = env::args();
        let mut running = RunMode::Running;

        if args.len() > 1 {
            let exname = args.next().unwrap();
            for arg in args {
                if &arg[..] == "--help" || &arg[..] == "-h" {
                    usage(&exname[..]);
                    return;
                }
                else if &arg[..] == "--pause" {
                    running = RunMode::Stop;
                }
            }
        }

        let mut draw_colls = false;

        let mut camera = Camera::new();

        self.window.set_framerate_limit(60);

        let font_mem = include_bytes!("Inconsolata.otf");
        let     fnt  = Font::new_from_memory(font_mem).unwrap();
        let mut fps  = Fps::new(&fnt);
        let mut grabbed_object: Option<Rc<RefCell<RigidBody>>> = None;
        let mut grabbed_object_joint: Option<Rc<RefCell<Fixed>>> = None;

        while self.window.is_open() {
            loop {
                match self.window.poll_event() {
                    event::KeyPressed{code, ..} => {
                        match code {
                            Key::Escape => self.window.close(),
                            Key::S      => running = RunMode::Step,
                            Key::Space  => draw_colls = !draw_colls,
                            Key::T      => {
                                if running == RunMode::Stop {
                                    running = RunMode::Running;
                                }
                                else {
                                    running = RunMode::Stop;
                                }
                            },
                            _                => { }
                        }
                    },
                    event::MouseButtonPressed{button, x, y} => {
                        match button {
                            MouseButton::MouseLeft => {
                                let mapped_coords = camera.map_pixel_to_coords(Vector2i::new(x, y));
                                let mapped_point = Pnt2::new(mapped_coords.x, mapped_coords.y);
                                self.world.interferences_with_point(&mapped_point, |b| {
                                    if b.borrow().can_move() {
                                        grabbed_object = Some(b.clone())
                                    }
                                });

                                match grabbed_object {
                                    Some(ref b) => {
                                        for node in self.graphics.body_to_scene_node(b).unwrap().iter_mut() {
                                            match grabbed_object_joint {
                                                Some(ref j) => self.world.remove_fixed(j),
                                                None        => { }
                                            }

                                            let _1: Iso2<f32> = na::one();
                                            let attach2 = na::append_translation(&_1, mapped_point.as_vec());
                                            let attach1 = na::inv(&na::transformation(b.borrow().position())).unwrap() * attach2;
                                            let anchor1 = Anchor::new(Some(grabbed_object.as_ref().unwrap().clone()), attach1);
                                            let anchor2 = Anchor::new(None, attach2);
                                            let joint = Fixed::new(anchor1, anchor2);
                                            grabbed_object_joint = Some(self.world.add_fixed(joint));
                                            node.select()
                                        }
                                    },
                                    None => { }
                                }
                            },
                            _ => {
                                camera.handle_event(&event::MouseButtonPressed{ button: button, x: x, y: y })
                            }
                        }
                    },
                    event::MouseButtonReleased{button, x, y} => {
                        match button {
                            MouseButton::MouseLeft => {
                                match grabbed_object {
                                    Some(ref b) => {
                                        for node in self.graphics.body_to_scene_node(b).unwrap().iter_mut() {
                                            node.unselect()
                                        }
                                    },
                                    None => { }
                                }

                                match grabbed_object_joint {
                                    Some(ref j) => self.world.remove_fixed(j),
                                    None => { }
                                }

                                grabbed_object = None;
                                grabbed_object_joint = None;
                            },
                            _ => {
                                camera.handle_event(&event::MouseButtonReleased{ button: button, x: x, y: y })
                            }
                        }
                    }
                    event::MouseMoved{x, y} => {
                        let mapped_coords = camera.map_pixel_to_coords(Vector2i::new(x, y));
                        let mapped_point = Pnt2::new(mapped_coords.x, mapped_coords.y);
                        let _1: Iso2<f32> = na::one();
                        let attach2 = na::append_translation(&_1, (mapped_point).as_vec());
                        match grabbed_object {
                            Some(_) => {
                                let joint = grabbed_object_joint.as_ref().unwrap();
                                joint.borrow_mut().set_local2(attach2);
                            },
                            None => camera.handle_event(&event::MouseMoved{x: x, y: y})
                        };
                    },
                    event::Closed  => self.window.close(),
                    event::NoEvent => break,
                    e              => camera.handle_event(&e)
                }
            }

            self.window.clear(&Color::black());

            fps.reset();

            if running != RunMode::Stop {
                self.world.step(0.016);
            }

            if running == RunMode::Step {
                running = RunMode::Stop;
            }
            fps.register_delta();
            self.graphics.draw(&mut self.window, &camera);

            camera.activate_scene(&mut self.window);
            if draw_colls {
                draw_helper::draw_colls(&mut self.window, &mut self.world);
            }

            camera.activate_ui(&mut self.window);
            fps.draw_registered(&mut self.window);

            self.window.display();
        }

        self.window.close();
    }
}
<commit_msg>First refactor of testbed<commit_after>use std::env;
use std::rc::Rc;
use std::cell::RefCell;
use sfml::graphics::{RenderWindow, RenderTarget, Font};
use sfml::window::{ContextSettings, VideoMode, Close};
use sfml::window::event;
use sfml::window::keyboard::Key;
use sfml::window::mouse::MouseButton;
use sfml::graphics::Color;
use sfml::system::vector2::Vector2i;
use na::{Pnt2, Pnt3, Iso2};
use na;
use nphysics::world::World;
use nphysics::object::RigidBody;
use nphysics::detection::joint::{Fixed, Anchor};
use camera::Camera;
use fps::Fps;
use engine::GraphicsManager;
use draw_helper;

fn usage(exe_name: &str) {
    println!("Usage: {} [OPTION] ", exe_name);
    println!("");
    println!("Options:");
    println!("    --help  - prints this help message and exits.");
    println!("    --pause - do not start the simulation right away.");
    println!("");
    println!("The following keyboard commands are supported:");
    println!("    t     - pause/continue the simulation.");
    println!("    s     - pause then execute only one simulation step.");
    println!("    space - display/hide contacts.");
}

#[derive(PartialEq)]
enum RunMode {
    Running,
    Stop,
    Step
}

pub struct Testbed<'a> {
    world:    World,
    window:   RenderWindow,
    graphics: GraphicsManager<'a>
}

struct TestbedState<'a> {
    running: RunMode,
    draw_colls: bool,
    camera: Camera,
    fps: Fps<'a>,
    grabbed_object: Option<Rc<RefCell<RigidBody>>>,
    grabbed_object_joint: Option<Rc<RefCell<Fixed>>>,
}

impl<'a> TestbedState<'a> {
    fn new(fnt: &'a Font) -> TestbedState<'a> {
        TestbedState{
            running: RunMode::Running,
            draw_colls: false,
            camera: Camera::new(),
            fps: Fps::new(&fnt),
            grabbed_object: None,
            grabbed_object_joint: None,
        }
    }
}

impl<'a> Testbed<'a> {
    pub fn new_empty() -> Testbed<'a> {
        let mode    = VideoMode::new_init(800, 600, 32);
        let setting = ContextSettings {
            depth_bits:         10,
            stencil_bits:       10,
            antialiasing_level: 2,
            major_version:      0,
            minor_version:      1
        };
        let window =
            match RenderWindow::new(mode, "nphysics 2d demo", Close, &setting) {
                Some(rwindow) => rwindow,
                None          => panic!("Error on creating the sfml window.")
            };
        let graphics = GraphicsManager::new();

        Testbed {
            world:    World::new(),
            window:   window,
            graphics: graphics
        }
    }

    pub fn new(world: World) -> Testbed<'a> {
        let mut res = Testbed::new_empty();

        res.set_world(world);

        res
    }

    pub fn set_world(&mut self, world: World) {
        self.world = world;
        self.graphics.clear();

        for rb in self.world.bodies() {
            self.graphics.add(rb.clone());
        }
    }

    pub fn set_color(&mut self, body: &Rc<RefCell<RigidBody>>, color: Pnt3<f32>) {
        let color = Pnt3::new(
            (color.x * 255.0) as u8,
            (color.y * 255.0) as u8,
            (color.z * 255.0) as u8
        );

        self.graphics.set_color(body, color);
    }

    pub fn run(&mut self) {
        let font_mem = include_bytes!("Inconsolata.otf");
        let     fnt  = Font::new_from_memory(font_mem).unwrap();

        let mut state = TestbedState::new(&fnt);

        let mut args    = env::args();

        if args.len() > 1 {
            let exname = args.next().unwrap();
            for arg in args {
                if &arg[..] == "--help" || &arg[..] == "-h" {
                    usage(&exname[..]);
                    return;
                }
                else if &arg[..] == "--pause" {
                    state.running = RunMode::Stop;
                }
            }
        }

        self.window.set_framerate_limit(60);

        self.foo(state);

        self.window.close();
    }

    fn foo(&mut self, mut state: TestbedState) {
        while self.window.is_open() {
            loop {
                match self.window.poll_event() {
                    event::KeyPressed{code, ..} => {
                        match code {
                            Key::Escape => self.window.close(),
                            Key::S      => state.running = RunMode::Step,
                            Key::Space  => state.draw_colls = !state.draw_colls,
                            Key::T      => {
                                if state.running == RunMode::Stop {
                                    state.running = RunMode::Running;
                                }
                                else {
                                    state.running = RunMode::Stop;
                                }
                            },
                            _                => { }
                        }
                    },
                    event::MouseButtonPressed{button, x, y} => {
                        match button {
                            MouseButton::MouseLeft => {
                                let mapped_coords = state.camera.map_pixel_to_coords(Vector2i::new(x, y));
                                let mapped_point = Pnt2::new(mapped_coords.x, mapped_coords.y);
                                self.world.interferences_with_point(&mapped_point, |b| {
                                    if b.borrow().can_move() {
                                        state.grabbed_object = Some(b.clone())
                                    }
                                });

                                match state.grabbed_object {
                                    Some(ref b) => {
                                        for node in self.graphics.body_to_scene_node(b).unwrap().iter_mut() {
                                            match state.grabbed_object_joint {
                                                Some(ref j) => self.world.remove_fixed(j),
                                                None        => { }
                                            }

                                            let _1: Iso2<f32> = na::one();
                                            let attach2 = na::append_translation(&_1, mapped_point.as_vec());
                                            let attach1 = na::inv(&na::transformation(b.borrow().position())).unwrap() * attach2;
                                            let anchor1 = Anchor::new(Some(state.grabbed_object.as_ref().unwrap().clone()), attach1);
                                            let anchor2 = Anchor::new(None, attach2);
                                            let joint = Fixed::new(anchor1, anchor2);
                                            state.grabbed_object_joint = Some(self.world.add_fixed(joint));
                                            node.select()
                                        }
                                    },
                                    None => { }
                                }
                            },
                            _ => {
                                state.camera.handle_event(&event::MouseButtonPressed{ button: button, x: x, y: y })
                            }
                        }
                    },
                    event::MouseButtonReleased{button, x, y} => {
                        match button {
                            MouseButton::MouseLeft => {
                                match state.grabbed_object {
                                    Some(ref b) => {
                                        for node in self.graphics.body_to_scene_node(b).unwrap().iter_mut() {
                                            node.unselect()
                                        }
                                    },
                                    None => { }
                                }

                                match state.grabbed_object_joint {
                                    Some(ref j) => self.world.remove_fixed(j),
                                    None => { }
                                }

                                state.grabbed_object = None;
                                state.grabbed_object_joint = None;
                            },
                            _ => {
                                state.camera.handle_event(&event::MouseButtonReleased{ button: button, x: x, y: y })
                            }
                        }
                    }
                    event::MouseMoved{x, y} => {
                        let mapped_coords = state.camera.map_pixel_to_coords(Vector2i::new(x, y));
                        let mapped_point = Pnt2::new(mapped_coords.x, mapped_coords.y);
                        let _1: Iso2<f32> = na::one();
                        let attach2 = na::append_translation(&_1, (mapped_point).as_vec());
                        match state.grabbed_object {
                            Some(_) => {
                                let joint = state.grabbed_object_joint.as_ref().unwrap();
                                joint.borrow_mut().set_local2(attach2);
                            },
                            None => state.camera.handle_event(&event::MouseMoved{x: x, y: y})
                        };
                    },
                    event::Closed  => self.window.close(),
                    event::NoEvent => break,
                    e              => state.camera.handle_event(&e)
                }
            }

            self.window.clear(&Color::black());

            state.fps.reset();

            if state.running != RunMode::Stop {
                self.world.step(0.016);
            }

            if state.running == RunMode::Step {
                state.running = RunMode::Stop;
            }
            state.fps.register_delta();
            self.graphics.draw(&mut self.window, &state.camera);

            state.camera.activate_scene(&mut self.window);
            if state.draw_colls {
                draw_helper::draw_colls(&mut self.window, &mut self.world);
            }

            state.camera.activate_ui(&mut self.window);
            state.fps.draw_registered(&mut self.window);

            self.window.display();
        }
    }
}
<|endoftext|>


<commit_before>//! WASI-specific extensions to general I/O primitives

#![deny(unsafe_op_in_unsafe_fn)]
#![unstable(feature = "wasi_ext", issue = "none")]

use crate::fs;
use crate::io;
use crate::net;
use crate::sys;
use crate::sys_common::{AsInner, FromInner, IntoInner};

/// Raw file descriptors.
pub type RawFd = u32;

/// A trait to extract the raw WASI file descriptor from an underlying
/// object.
pub trait AsRawFd {
    /// Extracts the raw file descriptor.
    ///
    /// This method does **not** pass ownership of the raw file descriptor
    /// to the caller. The descriptor is only guaranteed to be valid while
    /// the original object has not yet been destroyed.
    fn as_raw_fd(&self) -> RawFd;
}

/// A trait to express the ability to construct an object from a raw file
/// descriptor.
pub trait FromRawFd {
    /// Constructs a new instance of `Self` from the given raw file
    /// descriptor.
    ///
    /// This function **consumes ownership** of the specified file
    /// descriptor. The returned object will take responsibility for closing
    /// it when the object goes out of scope.
    ///
    /// This function is also unsafe as the primitives currently returned
    /// have the contract that they are the sole owner of the file
    /// descriptor they are wrapping. Usage of this function could
    /// accidentally allow violating this contract which can cause memory
    /// unsafety in code that relies on it being true.
    unsafe fn from_raw_fd(fd: RawFd) -> Self;
}

/// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor.
pub trait IntoRawFd {
    /// Consumes this object, returning the raw underlying file descriptor.
    ///
    /// This function **transfers ownership** of the underlying file descriptor
    /// to the caller. Callers are then the unique owners of the file descriptor
    /// and must close the descriptor once it's no longer needed.
    fn into_raw_fd(self) -> RawFd;
}

#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")]
impl AsRawFd for RawFd {
    fn as_raw_fd(&self) -> RawFd {
        *self
    }
}
#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")]
impl IntoRawFd for RawFd {
    fn into_raw_fd(self) -> RawFd {
        self
    }
}
#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")]
impl FromRawFd for RawFd {
    unsafe fn from_raw_fd(fd: RawFd) -> RawFd {
        fd
    }
}

impl AsRawFd for net::TcpStream {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().as_raw()
    }
}

impl FromRawFd for net::TcpStream {
    unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
        net::TcpStream::from_inner(sys::net::TcpStream::from_inner(fd))
    }
}

impl IntoRawFd for net::TcpStream {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

impl AsRawFd for net::TcpListener {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().as_raw()
    }
}

impl FromRawFd for net::TcpListener {
    unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
        net::TcpListener::from_inner(sys::net::TcpListener::from_inner(fd))
    }
}

impl IntoRawFd for net::TcpListener {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

impl AsRawFd for net::UdpSocket {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().as_raw()
    }
}

impl FromRawFd for net::UdpSocket {
    unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
        net::UdpSocket::from_inner(sys::net::UdpSocket::from_inner(fd))
    }
}

impl IntoRawFd for net::UdpSocket {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

impl AsRawFd for fs::File {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().as_raw()
    }
}

impl FromRawFd for fs::File {
    unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
        fs::File::from_inner(sys::fs::File::from_inner(fd))
    }
}

impl IntoRawFd for fs::File {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

impl AsRawFd for io::Stdin {
    fn as_raw_fd(&self) -> RawFd {
        sys::stdio::Stdin.as_raw_fd()
    }
}

impl AsRawFd for io::Stdout {
    fn as_raw_fd(&self) -> RawFd {
        sys::stdio::Stdout.as_raw_fd()
    }
}

impl AsRawFd for io::Stderr {
    fn as_raw_fd(&self) -> RawFd {
        sys::stdio::Stderr.as_raw_fd()
    }
}
<commit_msg>spend another CI build to delete a double newline<commit_after>//! WASI-specific extensions to general I/O primitives

#![deny(unsafe_op_in_unsafe_fn)]
#![unstable(feature = "wasi_ext", issue = "none")]

use crate::fs;
use crate::io;
use crate::net;
use crate::sys;
use crate::sys_common::{AsInner, FromInner, IntoInner};

/// Raw file descriptors.
pub type RawFd = u32;

/// A trait to extract the raw WASI file descriptor from an underlying
/// object.
pub trait AsRawFd {
    /// Extracts the raw file descriptor.
    ///
    /// This method does **not** pass ownership of the raw file descriptor
    /// to the caller. The descriptor is only guaranteed to be valid while
    /// the original object has not yet been destroyed.
    fn as_raw_fd(&self) -> RawFd;
}

/// A trait to express the ability to construct an object from a raw file
/// descriptor.
pub trait FromRawFd {
    /// Constructs a new instance of `Self` from the given raw file
    /// descriptor.
    ///
    /// This function **consumes ownership** of the specified file
    /// descriptor. The returned object will take responsibility for closing
    /// it when the object goes out of scope.
    ///
    /// This function is also unsafe as the primitives currently returned
    /// have the contract that they are the sole owner of the file
    /// descriptor they are wrapping. Usage of this function could
    /// accidentally allow violating this contract which can cause memory
    /// unsafety in code that relies on it being true.
    unsafe fn from_raw_fd(fd: RawFd) -> Self;
}

/// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor.
pub trait IntoRawFd {
    /// Consumes this object, returning the raw underlying file descriptor.
    ///
    /// This function **transfers ownership** of the underlying file descriptor
    /// to the caller. Callers are then the unique owners of the file descriptor
    /// and must close the descriptor once it's no longer needed.
    fn into_raw_fd(self) -> RawFd;
}

#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")]
impl AsRawFd for RawFd {
    fn as_raw_fd(&self) -> RawFd {
        *self
    }
}
#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")]
impl IntoRawFd for RawFd {
    fn into_raw_fd(self) -> RawFd {
        self
    }
}
#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")]
impl FromRawFd for RawFd {
    unsafe fn from_raw_fd(fd: RawFd) -> RawFd {
        fd
    }
}

impl AsRawFd for net::TcpStream {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().as_raw()
    }
}

impl FromRawFd for net::TcpStream {
    unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
        net::TcpStream::from_inner(sys::net::TcpStream::from_inner(fd))
    }
}

impl IntoRawFd for net::TcpStream {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

impl AsRawFd for net::TcpListener {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().as_raw()
    }
}

impl FromRawFd for net::TcpListener {
    unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
        net::TcpListener::from_inner(sys::net::TcpListener::from_inner(fd))
    }
}

impl IntoRawFd for net::TcpListener {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

impl AsRawFd for net::UdpSocket {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().as_raw()
    }
}

impl FromRawFd for net::UdpSocket {
    unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
        net::UdpSocket::from_inner(sys::net::UdpSocket::from_inner(fd))
    }
}

impl IntoRawFd for net::UdpSocket {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

impl AsRawFd for fs::File {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().as_raw()
    }
}

impl FromRawFd for fs::File {
    unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
        fs::File::from_inner(sys::fs::File::from_inner(fd))
    }
}

impl IntoRawFd for fs::File {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

impl AsRawFd for io::Stdin {
    fn as_raw_fd(&self) -> RawFd {
        sys::stdio::Stdin.as_raw_fd()
    }
}

impl AsRawFd for io::Stdout {
    fn as_raw_fd(&self) -> RawFd {
        sys::stdio::Stdout.as_raw_fd()
    }
}

impl AsRawFd for io::Stderr {
    fn as_raw_fd(&self) -> RawFd {
        sys::stdio::Stderr.as_raw_fd()
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use hyper::client::Pool;
use hyper::net::{HttpStream, HttpsConnector, SslClient};
use openssl::ssl::{SSL_OP_NO_SSLV2, SSL_OP_NO_SSLV3, SSL_VERIFY_PEER};
use openssl::ssl::{Ssl, SslContext, SslMethod, SslStream};
use std::sync::Arc;
use util::resource_files::resources_dir_path;

pub type Connector = HttpsConnector<ServoSslClient>;

// The basic logic here is to prefer ciphers with ECDSA certificates, Forward
// Secrecy, AES GCM ciphers, AES ciphers, and finally 3DES ciphers.
// A complete discussion of the issues involved in TLS configuration can be found here:
// https://wiki.mozilla.org/Security/Server_Side_TLS
const DEFAULT_CIPHERS: &'static str = concat!(
    "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:",
    "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:",
    "DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:",
    "ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:",
    "ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:",
    "ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:",
    "DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:",
    "ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:",
    "AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA"
);

pub fn create_http_connector() -> Arc<Pool<Connector>> {
    let mut context = SslContext::new(SslMethod::Sslv23).unwrap();
    context.set_CA_file(&resources_dir_path().join("certs")).unwrap();
    context.set_cipher_list(DEFAULT_CIPHERS).unwrap();
    context.set_options(SSL_OP_NO_SSLV2 | SSL_OP_NO_SSLV3);
    let connector = HttpsConnector::new(ServoSslClient {
        context: Arc::new(context)
    });

    Arc::new(Pool::with_connector(Default::default(), connector))
}

pub struct ServoSslClient {
    context: Arc<SslContext>,
}

impl SslClient for ServoSslClient {
    type Stream = SslStream<HttpStream>;

    fn wrap_client(&self, stream: HttpStream, host: &str) -> Result<Self::Stream, ::hyper::Error> {
        let mut ssl = try!(Ssl::new(&self.context));
        try!(ssl.set_hostname(host));
        let host = host.to_owned();
        ssl.set_verify_callback(SSL_VERIFY_PEER, move |p, x| {
            ::openssl_verify::verify_callback(&host, p, x)
        });
        SslStream::connect(ssl, stream).map_err(From::from)
    }
}
<commit_msg>Disable TLS compression<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use hyper::client::Pool;
use hyper::net::{HttpStream, HttpsConnector, SslClient};
use openssl::ssl::{SSL_OP_NO_COMPRESSION, SSL_OP_NO_SSLV2, SSL_OP_NO_SSLV3, SSL_VERIFY_PEER};
use openssl::ssl::{Ssl, SslContext, SslMethod, SslStream};
use std::sync::Arc;
use util::resource_files::resources_dir_path;

pub type Connector = HttpsConnector<ServoSslClient>;

// The basic logic here is to prefer ciphers with ECDSA certificates, Forward
// Secrecy, AES GCM ciphers, AES ciphers, and finally 3DES ciphers.
// A complete discussion of the issues involved in TLS configuration can be found here:
// https://wiki.mozilla.org/Security/Server_Side_TLS
const DEFAULT_CIPHERS: &'static str = concat!(
    "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:",
    "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:",
    "DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:",
    "ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:",
    "ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:",
    "ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:",
    "DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:",
    "ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:",
    "AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA"
);

pub fn create_http_connector() -> Arc<Pool<Connector>> {
    let mut context = SslContext::new(SslMethod::Sslv23).unwrap();
    context.set_CA_file(&resources_dir_path().join("certs")).unwrap();
    context.set_cipher_list(DEFAULT_CIPHERS).unwrap();
    context.set_options(SSL_OP_NO_SSLV2 | SSL_OP_NO_SSLV3 | SSL_OP_NO_COMPRESSION);
    let connector = HttpsConnector::new(ServoSslClient {
        context: Arc::new(context)
    });

    Arc::new(Pool::with_connector(Default::default(), connector))
}

pub struct ServoSslClient {
    context: Arc<SslContext>,
}

impl SslClient for ServoSslClient {
    type Stream = SslStream<HttpStream>;

    fn wrap_client(&self, stream: HttpStream, host: &str) -> Result<Self::Stream, ::hyper::Error> {
        let mut ssl = try!(Ssl::new(&self.context));
        try!(ssl.set_hostname(host));
        let host = host.to_owned();
        ssl.set_verify_callback(SSL_VERIFY_PEER, move |p, x| {
            ::openssl_verify::verify_callback(&host, p, x)
        });
        SslStream::connect(ssl, stream).map_err(From::from)
    }
}
<|endoftext|>


<commit_before>extern crate time;

pub struct KissRng {
    x: usize,
    y: usize,
    z: usize,
    c: usize,
}

impl KissRng {
    pub fn new() -> KissRng {
        let now = time::precise_time_ns() as usize;
        return KissRng {
            x: 123456789usize.wrapping_add(now),
            y: 987654321usize.wrapping_add(now),
            z: 43219876usize.wrapping_add(now),
            c: 6543217usize.wrapping_add(now)
        };
    }

    pub fn next(&mut self) -> usize {
        self.x = 314527869usize.wrapping_mul(self.x).wrapping_add(1234567);
        self.y ^= self.y.rotate_left(5);
        self.y ^= self.y.rotate_right(7);
        self.y ^= self.y.rotate_left(22);
        self.z = 4294584393usize.wrapping_mul(self.z).wrapping_add(self.c);
        self.c = self.z.rotate_right(32);
        return self.x.wrapping_add(self.y).wrapping_add(self.z);
    }
}

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

    #[test]
    fn kissrng_test_for_overflow() {
        let mut rng = KissRng::new();
        for _ in 0..1000000 {
            rng.next();
        }
    }
}
<commit_msg>Changed to xors for init and shifts<commit_after>extern crate time;

pub struct KissRng {
    x: usize,
    y: usize,
    z: usize,
    c: usize,
}

impl KissRng {
    pub fn new() -> KissRng {
        let now = time::precise_time_ns() as usize;
        return KissRng {
            x: 123456789usize ^ now,
            y: 987654321usize ^ now,
            z: 43219876usize ^now,
            c: 6543217usize ^ now
        };
    }

    pub fn next(&mut self) -> usize {
        self.x = 314527869usize.wrapping_mul(self.x).wrapping_add(1234567);
        self.y ^= self.y.wrapping_shl(5);
        self.y ^= self.y.wrapping_shr(7);
        self.y ^= self.y.wrapping_shl(22);
        self.z = 4294584393usize.wrapping_mul(self.z).wrapping_add(self.c);
        self.c = self.z.wrapping_shr(32);
        return self.x.wrapping_add(self.y).wrapping_add(self.z);
    }
}

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

    #[test]
    fn kissrng_test_for_overflow() {
        let mut rng = KissRng::new();
        for _ in 0..1000000 {
            rng.next();
        }
    }
}
<|endoftext|>


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

use common::{Result, Id, Op2, Const};
use explicit;
use implicit;
use env;
use hindley_milner;

#[derive(PartialEq, Eq, Clone, Debug)]
pub enum Imm {
    Bool(bool),
    Int(i64),
    Var(Id),
    //    Fun(Id, Box<Expr>),
    //    Fix(Id, Box<Expr>),
    //    Star,
    //    V,
}

#[derive(PartialEq, Eq, Clone, Debug)]
pub enum Op {
    Op2(Op2, Box<Imm>, Box<Imm>),
    //    MkArray(Box<Imm>, Box<Imm>),
    //    GetArray(Box<Imm>, Box<Imm>),
    //    SetArray(Box<Imm>, Box<Imm>, Box<Imm>),
    Imm(Imm),
}
//    WellFormed(Imm), // Var-only

#[derive(PartialEq, Eq, Clone, Debug)]
pub enum Expr {
    //    If(Box<Imm>, Box<Imm>, Box<Imm>),
    //    App(Box<Imm>, Box<Imm>),
    Let(Id, Box<Expr>, Box<Expr>),
    Op(Op),
}

#[derive(PartialEq, Eq, Clone, Debug)]
struct ConvEnv {
    //env: HashMap<Id, explicit::Type>,
    next_id: i32,
}

impl ConvEnv {
    fn new() -> ConvEnv {
        ConvEnv {
            //env: HashMap::new(),
            next_id: 0,
        }
    }

    fn tmp(&self) -> (ConvEnv, Id) {
        let id = self.next_id;
        let c = ConvEnv{
            //env: self.env.clone(),
            next_id: self.next_id+1,
        };

        (c, format!("!tmp!{}", id))
    }
}

fn op(cenv: ConvEnv, e: &explicit::Expr) -> (ConvEnv, Op) {
    use typed::Expr as E;
    match *e {
        E::Const(Const::Bool(c)) => (cenv, Op::Imm(Imm::Bool(c))),
        E::Const(Const::Int(c)) => (cenv, Op::Imm(Imm::Int(c))),
        _ => {
            panic!("TODO: implement term for {:?}", e);
        }
    }
}

fn identity(cenv: ConvEnv, e: Expr) -> (ConvEnv, Expr) {
    (cenv, e)
}

// 1:1 translation -- can't fail
fn expr<F>(cenv: ConvEnv, e: &explicit::Expr, k: F) -> (ConvEnv, Expr)
    where F: FnOnce(ConvEnv, Expr) -> (ConvEnv, Expr) {

    use self::Imm as I;
    use typed::Expr as E;

    match *e {
        E::Const(_) => {
            let (cenv, eop) = op(cenv, e);
            (cenv, Expr::Op(eop))
        }
        E::Op2(op, ref l, ref r) => {
            expr(cenv, l, |cenv: ConvEnv, ll: Expr| -> (ConvEnv, Expr) {
                expr(cenv, r, |cenv: ConvEnv, rr: Expr| -> (ConvEnv, Expr) {
                    // allocate vars
                    let (cenv, l_tmp) = cenv.tmp();
                    let (cenv, r_tmp) = cenv.tmp();

                    // value to pass to the continuation
                    let val = Expr::Op(Op::Op2(op,
                                               box I::Var(l_tmp.clone()),
                                               box I::Var(r_tmp.clone())));

                    // our inner expression is whatever the
                    // continuation says it is.
                    let (cenv, inner_expr) = k(cenv, val);

                    let result = Expr::Let(l_tmp.clone(), box ll.clone(),
                                           box Expr::Let(r_tmp.clone(), box rr,
                                                         box inner_expr));

                    (cenv, result)
                })
            })
        }
        _ => {
            panic!("TODO: implement expr for {:?}", e);
        }
    }
    // E::Op2(op, ref e1, ref e2) => {
    //     let (n, e1, _) = convert(n, env, renamed, e1);
    //     let (n, e2, _) = convert(n, env, renamed, e2);
    //     (n, I::Op2(op, box e1, box e2), explicit::opty(op))
    // }
    // E::If(ref e1, ref e2, ref e3) => {
    //     let (n, e1, _) = convert(n, env, renamed, e1);
    //     let (n, e2, t) = convert(n, env, renamed, e2);
    //     let (n, e3, _) = convert(n, env, renamed, e3);
    //     (n, I::If(box e1, box e2, box e3), t)
    // }
    // E::Var(ref x) => {
    //     let αx = renamed.get(x).unwrap();
    //     (n, I::Var(αx.clone()), env.get(αx).unwrap().clone())
    // }
    // E::Let(ref id, ref e1, ref e2) => {
    //     let mut renamed = renamed.clone();
    //     let (n, αid) = (n+1, format!("{}!a{}", id, n));

    //     let (n, e1, t1) = convert(n, env, &renamed, e1);

    //     renamed.insert(id.clone(), αid.clone());
    //     env.insert(αid.clone(), t1);

    //     let (n, e2, t2) = convert(n, env, &renamed, e2);
    //     (n, I::Let(αid, box e1, box e2), t2)
    // }
    // E::Fun(ref id, ref t1, ref e) => {
    //     let mut renamed = renamed.clone();
    //     let (n, αid) = (n+1, format!("{}!a{}", id, n));

    //     renamed.insert(id.clone(), αid.clone());
    //     env.insert(αid.clone(), t1.clone());

    //     let (n, e, t2) = convert(n, env, &renamed, e);

    //     (n, I::Fun(αid, box e), Type::TFun(box t1.clone(), box t2))
    // }
    // E::Fix(ref id, ref t1, ref e) => {
    //     let mut renamed = renamed.clone();
    //     let (n, αid) = (n+1, format!("{}!a{}", id, n));

    //     renamed.insert(id.clone(), αid.clone());
    //     env.insert(αid.clone(), t1.clone());

    //     let (n, e, t2) = convert(n, env, &renamed, e);

    //     (n, I::Fix(αid, box e), t2)
    // }
    // E::App(ref e1, ref e2) => {
    //     let (n, e1, t1) = convert(n, env, renamed, e1);
    //     let (n, e2, _) = convert(n, env, renamed, e2);
    //     let t = match t1 {
    //         Type::TFun(_, t2) => *t2,
    //         _ => panic!("expected TFun, not {:?}", t1),
    //     };
    //     (n, I::App(box e1, box e2), t)
    // }
    // E::MkArray(ref sz, ref val) => {
    //     let (n, sz, _) = convert(n, env, renamed, sz);
    //     let (n, val, _) = convert(n, env, renamed, val);
    //     (n, I::MkArray(box sz, box val), Type::TIntArray)
    // }
    // E::GetArray(ref id, ref idx) => {
    //     let (n, id, _) = convert(n, env, renamed, id);
    //     let (n, idx, _) = convert(n, env, renamed, idx);
    //     (n, I::GetArray(box id, box idx), Type::TInt)
    // }
    // E::SetArray(ref id, ref idx, ref v) => {
    //     let (n, id, _) = convert(n, env, renamed, id);
    //     let (n, idx, _) = convert(n, env, renamed, idx);
    //     let (n, v, _) = convert(n, env, renamed, v);
    //     (n, I::SetArray(box id, box idx, box v), Type::TIntArray)
    // }
}

pub fn anf(implicit_expr: &implicit::Expr) -> Result<(Expr, HashMap<Id, explicit::Type>)> {

    let explicit_expr = hindley_milner::infer(implicit_expr)?;
    // alpha-renaming
    let (alpha_expr, env) = env::extract(&explicit_expr);

    // println!("α-implicit: {:?}\n", α_expr);
    // println!("Γ         : {:?}\n", env);

    let cenv = ConvEnv::new();
    let (_, expr) = expr(cenv, &alpha_expr, identity);

    Ok((expr, env))
    // step 1 -- arithmatic + let bindings
    // step 2 -- conds + boolean vals
    // step 3 -- arrays
    // step 4 -- closures

    // (define (Value? M)
    //   (match M
    //     [`(quote ,_)         #t]
    //     [(? number?)         #t]
    //     [(? boolean?)        #t]
    //     [(? string?)         #t]
    //     [(? char?)           #t]
    //     [(? symbol?)         #t]
    //     [(or '+ '- '* '/ '=) #t]
    //     [else                #f]))

    // (define (normalize-term M) (normalize M (λ (x) x)))

    // (define (normalize M k)
    //   (match M
    //     [`(λ ,params ,body)
    //       (k `(λ ,params ,(normalize-term body)))]

    //     [`(let ([,x ,M1]) ,M2)
    //       (normalize M1 (λ (N1)
    //        `(let ([,x ,N1])
    //          ,(normalize M2 k))))]

    //     [`(if ,M1 ,M2 ,M3)
    //       (normalize-name M1 (λ (t)
    //        (k `(if ,t ,(normalize-term M2)
    //                   ,(normalize-term M3)))))]

    //     [`(,Fn . ,M*)
    //       (normalize-name Fn (λ (t)
    //        (normalize-name* M* (λ (t*)
    //         (k `(,t . ,t*))))))]

    //     [(? Value?)             (k M)]))

    // (define (normalize-name M k)
    //   (normalize M (λ (N)
    //     (if (Value? N) (k N)
    //         (let ([t (gensym)])
    //          `(let ([,t ,N]) ,(k t)))))))

    // (define (normalize-name* M* k)
    //   (if (null? M*)
    //       (k '())
    //       (normalize-name (car M*) (λ (t)
    //        (normalize-name* (cdr M*) (λ (t*)
    //         (k `(,t . ,t*))))))))

}

macro_rules! test_anf(
    ($s:expr, $ae:expr) => { {
        use implicit_parse;
        use tok::Tokenizer;
        use std;
        let s = $s;
        let tokenizer = Tokenizer::new(&s);
        let iexpr = match implicit_parse::parse_Program(&s, tokenizer) {
            Ok(iexpr) => iexpr,
            Err(e) => {
                die!("parse_Program({}): {:?}", $s, e);
            }
        };
        let anf_expr = match anf(&iexpr) {
            Ok((anf_expr, _)) => anf_expr,
            Err(e) => {
                die!("anf: {:?}", e);
            }
        };
        if anf_expr != $ae {
            die!("mismatch {:?} != {:?}", anf_expr, $ae);
        }
    } }
);

#[test]
fn anf_transforms() {
    use common::Op2 as O;
    use self::Imm as I;
    use self::Op::*;
    use self::Expr::*;

    test_anf!(
        "-22",
        Op(Imm(I::Int(-22))));
    test_anf!(
        "2+3",
        Let(String::from("!tmp!0"),
            box Op(Op2(O::Add, box I::Int(2), box I::Int(3))),
            box Op(Imm(I::Var(String::from("!tmp!0"))))));
}
<commit_msg>work around compilation issue by forcing dynamic dispatch<commit_after>use std::collections::HashMap;

use common::{Result, Id, Op2, Const};
use explicit;
use implicit;
use env;
use hindley_milner;

#[derive(PartialEq, Eq, Clone, Debug)]
pub enum Imm {
    Bool(bool),
    Int(i64),
    Var(Id),
    //    Fun(Id, Box<Expr>),
    //    Fix(Id, Box<Expr>),
    //    Star,
    //    V,
}

#[derive(PartialEq, Eq, Clone, Debug)]
pub enum Op {
    Op2(Op2, Box<Imm>, Box<Imm>),
    //    MkArray(Box<Imm>, Box<Imm>),
    //    GetArray(Box<Imm>, Box<Imm>),
    //    SetArray(Box<Imm>, Box<Imm>, Box<Imm>),
    Imm(Imm),
}
//    WellFormed(Imm), // Var-only

#[derive(PartialEq, Eq, Clone, Debug)]
pub enum Expr {
    //    If(Box<Imm>, Box<Imm>, Box<Imm>),
    //    App(Box<Imm>, Box<Imm>),
    Let(Id, Box<Expr>, Box<Expr>),
    Op(Op),
}

#[derive(PartialEq, Eq, Clone, Debug)]
struct ConvEnv {
    //env: HashMap<Id, explicit::Type>,
    next_id: i32,
}

impl ConvEnv {
    fn new() -> ConvEnv {
        ConvEnv {
            //env: HashMap::new(),
            next_id: 0,
        }
    }

    fn tmp(&self) -> (ConvEnv, Id) {
        let id = self.next_id;
        let c = ConvEnv{
            //env: self.env.clone(),
            next_id: self.next_id+1,
        };

        (c, format!("!tmp!{}", id))
    }
}

fn op(cenv: ConvEnv, e: &explicit::Expr) -> (ConvEnv, Op) {
    use typed::Expr as E;
    match *e {
        E::Const(Const::Bool(c)) => (cenv, Op::Imm(Imm::Bool(c))),
        E::Const(Const::Int(c)) => (cenv, Op::Imm(Imm::Int(c))),
        _ => {
            panic!("TODO: implement term for {:?}", e);
        }
    }
}

fn identity(cenv: ConvEnv, e: Expr) -> (ConvEnv, Expr) {
    (cenv, e)
}

// 1:1 translation -- can't fail
fn expr(cenv: ConvEnv, e: &explicit::Expr, k: &Fn(ConvEnv, Expr) -> (ConvEnv, Expr)) -> (ConvEnv, Expr) {

    use self::Imm as I;
    use typed::Expr as E;

    match *e {
        E::Const(_) => {
            let (cenv, eop) = op(cenv, e);
            k(cenv, Expr::Op(eop))
        }
        E::Op2(op, ref l, ref r) => {
            expr(cenv, l, &|cenv: ConvEnv, ll: Expr| -> (ConvEnv, Expr) {
                expr(cenv, r, &|cenv: ConvEnv, rr: Expr| -> (ConvEnv, Expr) {
                    // allocate vars
                    let (cenv, l_tmp) = cenv.tmp();
                    let (cenv, r_tmp) = cenv.tmp();

                    // value to pass to the continuation
                    let val = Expr::Op(Op::Op2(op,
                                               box I::Var(l_tmp.clone()),
                                               box I::Var(r_tmp.clone())));

                    // our inner expression is whatever the
                    // continuation says it is.
                    let (cenv, inner_expr) = k(cenv, val);

                    let result = Expr::Let(l_tmp.clone(), box ll.clone(),
                                           box Expr::Let(r_tmp.clone(), box rr,
                                                         box inner_expr));

                    (cenv, result)
                })
            })
        }
        _ => {
            panic!("TODO: implement expr for {:?}", e);
        }
    }
    // E::Op2(op, ref e1, ref e2) => {
    //     let (n, e1, _) = convert(n, env, renamed, e1);
    //     let (n, e2, _) = convert(n, env, renamed, e2);
    //     (n, I::Op2(op, box e1, box e2), explicit::opty(op))
    // }
    // E::If(ref e1, ref e2, ref e3) => {
    //     let (n, e1, _) = convert(n, env, renamed, e1);
    //     let (n, e2, t) = convert(n, env, renamed, e2);
    //     let (n, e3, _) = convert(n, env, renamed, e3);
    //     (n, I::If(box e1, box e2, box e3), t)
    // }
    // E::Var(ref x) => {
    //     let αx = renamed.get(x).unwrap();
    //     (n, I::Var(αx.clone()), env.get(αx).unwrap().clone())
    // }
    // E::Let(ref id, ref e1, ref e2) => {
    //     let mut renamed = renamed.clone();
    //     let (n, αid) = (n+1, format!("{}!a{}", id, n));

    //     let (n, e1, t1) = convert(n, env, &renamed, e1);

    //     renamed.insert(id.clone(), αid.clone());
    //     env.insert(αid.clone(), t1);

    //     let (n, e2, t2) = convert(n, env, &renamed, e2);
    //     (n, I::Let(αid, box e1, box e2), t2)
    // }
    // E::Fun(ref id, ref t1, ref e) => {
    //     let mut renamed = renamed.clone();
    //     let (n, αid) = (n+1, format!("{}!a{}", id, n));

    //     renamed.insert(id.clone(), αid.clone());
    //     env.insert(αid.clone(), t1.clone());

    //     let (n, e, t2) = convert(n, env, &renamed, e);

    //     (n, I::Fun(αid, box e), Type::TFun(box t1.clone(), box t2))
    // }
    // E::Fix(ref id, ref t1, ref e) => {
    //     let mut renamed = renamed.clone();
    //     let (n, αid) = (n+1, format!("{}!a{}", id, n));

    //     renamed.insert(id.clone(), αid.clone());
    //     env.insert(αid.clone(), t1.clone());

    //     let (n, e, t2) = convert(n, env, &renamed, e);

    //     (n, I::Fix(αid, box e), t2)
    // }
    // E::App(ref e1, ref e2) => {
    //     let (n, e1, t1) = convert(n, env, renamed, e1);
    //     let (n, e2, _) = convert(n, env, renamed, e2);
    //     let t = match t1 {
    //         Type::TFun(_, t2) => *t2,
    //         _ => panic!("expected TFun, not {:?}", t1),
    //     };
    //     (n, I::App(box e1, box e2), t)
    // }
    // E::MkArray(ref sz, ref val) => {
    //     let (n, sz, _) = convert(n, env, renamed, sz);
    //     let (n, val, _) = convert(n, env, renamed, val);
    //     (n, I::MkArray(box sz, box val), Type::TIntArray)
    // }
    // E::GetArray(ref id, ref idx) => {
    //     let (n, id, _) = convert(n, env, renamed, id);
    //     let (n, idx, _) = convert(n, env, renamed, idx);
    //     (n, I::GetArray(box id, box idx), Type::TInt)
    // }
    // E::SetArray(ref id, ref idx, ref v) => {
    //     let (n, id, _) = convert(n, env, renamed, id);
    //     let (n, idx, _) = convert(n, env, renamed, idx);
    //     let (n, v, _) = convert(n, env, renamed, v);
    //     (n, I::SetArray(box id, box idx, box v), Type::TIntArray)
    // }
}

pub fn anf(implicit_expr: &implicit::Expr) -> Result<(Expr, HashMap<Id, explicit::Type>)> {

    let explicit_expr = hindley_milner::infer(implicit_expr)?;
    // alpha-renaming
    let (alpha_expr, env) = env::extract(&explicit_expr);

    // println!("α-implicit: {:?}\n", α_expr);
    // println!("Γ         : {:?}\n", env);

    let cenv = ConvEnv::new();
    let (_, expr) = expr(cenv, &alpha_expr, &identity);

    Ok((expr, env))
    // step 1 -- arithmatic + let bindings
    // step 2 -- conds + boolean vals
    // step 3 -- arrays
    // step 4 -- closures

    // (define (Value? M)
    //   (match M
    //     [`(quote ,_)         #t]
    //     [(? number?)         #t]
    //     [(? boolean?)        #t]
    //     [(? string?)         #t]
    //     [(? char?)           #t]
    //     [(? symbol?)         #t]
    //     [(or '+ '- '* '/ '=) #t]
    //     [else                #f]))

    // (define (normalize-term M) (normalize M (λ (x) x)))

    // (define (normalize M k)
    //   (match M
    //     [`(λ ,params ,body)
    //       (k `(λ ,params ,(normalize-term body)))]

    //     [`(let ([,x ,M1]) ,M2)
    //       (normalize M1 (λ (N1)
    //        `(let ([,x ,N1])
    //          ,(normalize M2 k))))]

    //     [`(if ,M1 ,M2 ,M3)
    //       (normalize-name M1 (λ (t)
    //        (k `(if ,t ,(normalize-term M2)
    //                   ,(normalize-term M3)))))]

    //     [`(,Fn . ,M*)
    //       (normalize-name Fn (λ (t)
    //        (normalize-name* M* (λ (t*)
    //         (k `(,t . ,t*))))))]

    //     [(? Value?)             (k M)]))

    // (define (normalize-name M k)
    //   (normalize M (λ (N)
    //     (if (Value? N) (k N)
    //         (let ([t (gensym)])
    //          `(let ([,t ,N]) ,(k t)))))))

    // (define (normalize-name* M* k)
    //   (if (null? M*)
    //       (k '())
    //       (normalize-name (car M*) (λ (t)
    //        (normalize-name* (cdr M*) (λ (t*)
    //         (k `(,t . ,t*))))))))

}

macro_rules! test_anf(
    ($s:expr, $ae:expr) => { {
        use implicit_parse;
        use tok::Tokenizer;
        use std;
        let s = $s;
        let tokenizer = Tokenizer::new(&s);
        let iexpr = match implicit_parse::parse_Program(&s, tokenizer) {
            Ok(iexpr) => iexpr,
            Err(e) => {
                die!("parse_Program({}): {:?}", $s, e);
            }
        };
        let anf_expr = match anf(&iexpr) {
            Ok((anf_expr, _)) => anf_expr,
            Err(e) => {
                die!("anf: {:?}", e);
            }
        };
        if anf_expr != $ae {
            die!("mismatch {:?} != {:?}", anf_expr, $ae);
        }
    } }
);

#[test]
fn anf_transforms() {
    use common::Op2 as O;
    use self::Imm as I;
    use self::Op::*;
    use self::Expr::*;

    test_anf!(
        "-22",
        Op(Imm(I::Int(-22))));

    test_anf!(
        "2+3",
        Let(String::from("!tmp!0"),
            box Op(Op2(O::Add, box I::Int(2), box I::Int(3))),
            box Op(Imm(I::Var(String::from("!tmp!0"))))));
}
<|endoftext|>