<commit_before>#[link(name = "knob",
       vers = "1.0",
       uuid = "3299B6C2-99DE-44FD-8867-8EE7304959D7",
       url = "http://github.com/skade/knob")];

#[crate_type = "lib"];
#[comment = "A convenient Rust settings system"];
#[license = "MIT"];

//! A convenient structure to store and load settings.
//!
//! It is meant for items that are rarely read and stored, like command line flags or
//! application configuration.
//!
//! knob::Settings expects all values to implement ToStr + FromStr and stores them as
//! strings internally. This allows sideloading of settings through multiple means, e.g.
//! the command line or a simple config file. knob is not meant for structured data. If
//! you want to load such data, store the location of the data as a Knob setting and do
//! the loading parsing yourself.
//!
//! knob is typesafe in a sense that it will return you the type you wanted back if possible and
//! fails otherwise.
//!
//! knob allows you to decorate the Settings structure yourself for convenience (see examples).
//!
//! # Storing and fetching values
//!
//! The following example shows you how to store an ip in knob:
//!
//! ~~~{.rust}
//! extern mod knob;
//! use knob::*;
//! use std::rt::io::net::ip::IpAddr;
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set("ip", "0.0.0.0:4567");
//!   let socket: IpAddr = settings.socket();
//!   assert_eq!(socket.to_str(), ~"0.0.0.0:4567")
//! }
//! ~~~
//!
//! This works the same for IPv6 addresses:
//!
//! ~~~{.rust}
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set("ip", "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch("ip");
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! # Providing your own keys
//!
//! You can use enums as keys, as long as they implement ToStr:
//!
//! ~~~{.rust}
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch(Ip);
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! # Registering command line options
//!
//! Knob allows you to register command line options to read from the command line later.
//!
//! The options are getopts option groups.
//!
//! If the loading of the command line args fails, an error will be returned.
//!
//! ~~~{.rust}
//! use extra::getopts::groups::*;
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.opt(optopt("p", "port", "the port to bind to", "4000"))
//!   settings.opt(reqopt("e", "environment", "the environment to run in", ""));;
//!   let errors = settings.load_os_args();
//!   if errors.is_some() {
//!     println(settings.usage("Try one of these:"))
//!   }
//! }
//! ~~~
//!
//! # Decorating the settings struct
//!
//! To make matters more convenient, you can implement a decorator
//! to implement your own loading behaviour.
//!
//! ~~~{.rust}
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! pub trait SocketSettings {
//!   fn socket(&self) -> SocketAddr;
//!   fn port(&self) -> u16;
//!   fn ip(&self) -> IpAddr;
//! }
//!
//! impl SocketSettings for Settings {
//!   fn socket(&self) -> SocketAddr {
//!     do self.fetch_with(Addr) |addr| {
//!       match addr {
//!         Some(socket_addr) => { socket_addr },
//!         None => {
//!           let port: u16 = self.port();
//!           let ip: IpAddr = self.ip();
//!           SocketAddr { ip: ip, port: port }
//!         }
//!       }
//!     }
//!   }
//!
//!   fn port(&self) -> u16 {
//!     self.fetch(Port).unwrap_or(8080)
//!   }
//!
//!   fn ip(&self) -> IpAddr {
//!     self.fetch(Ip).unwrap_or(Ipv4Addr(127,0,0,1))
//!   }
//! }
//! enum Keys {
//!   Port,
//!   Ip,
//! }
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.ip();
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! knob goes up to 11.

extern mod extra;

use std::hashmap::*;
use std::os;

use extra::getopts::groups::{OptGroup,getopts,usage};
use extra::getopts::Fail_;

/// The settings structure we save the options and settings in.
#[deriving(Clone)]
pub struct Settings {
  priv store: HashMap<~str,~str>,
  priv options: ~[OptGroup],
}

impl Settings {
  /// Create a new Settings struct.
  pub fn new() -> Settings {
    Settings { store: HashMap::new(), options: ~[] }
  }

  /// Set a settings key to a value. The value will be serialized.
  pub fn set<A: ToStr, T: ToStr>(&mut self, setting: A, value: T) {
    self.store.swap(setting.to_str(), value.to_str());
  }

  /// Set a value using an Option struct. The value will only be set if the
  /// Some value is given. This way, you can avoid unwrapping the result of a
  /// previous operation by yourself.
  pub fn set_opt<A: ToStr, T: ToStr>(&mut self, setting: A, value: Option<T>) {
    if !value.is_none() {
      self.store.swap(setting.to_str(), value.unwrap().to_str());
    }
  }

  /// Fetch a setting for a key. Fails if the setting is present but could not be
  /// parsed.
  pub fn fetch<A: ToStr, T: FromStr>(&self, setting: A) -> Option<T> {
    match self.store.find(&setting.to_str()) {
      Some(string) => {
        let value = from_str(string.to_owned());
        if value.is_none() {
          fail!("setting could not be parsed:" + setting.to_str())
        }
        value
      },
      None => { None }
    }
  }

  /// Fetch a setting for a key and pass it to given function. The result of the function
  /// will be returned.
  pub fn fetch_with<A: ToStr, T: FromStr>(&self, setting: A, f: &fn(Option<T>) -> T) -> T {
    let value = self.fetch(setting.to_str());
    f(value)
  }

  /// Register a commandline for laster use with load_args.
  ///
  /// Currently, only optopt and reqopt are properly supported.
  pub fn opt(&mut self, opt: OptGroup) {
    self.options.push(opt);
  }

  /// Load the command line argument given by the OS.
  ///
  /// Optionally returns failures.
  pub fn load_os_args(&mut self) -> Option<Fail_> {
    let args = os::args();
    self.load_args(args)
  }

  /// Load a list of command line arguments.
  ///
  /// Automatically sets "knob.progname" to the name of the program.
  ///
  /// Optionally returns failures.
  pub fn load_args(&mut self, args: ~[~str]) -> Option<Fail_> {
    let ref prog_name = args[0];

    self.set("knob.progname", prog_name.clone());

    let matches = match getopts(args.tail(), self.options) {
      Ok(m) => { m }
      Err(fail) => { return Some(fail) }
    };

    let given_options = self.options.clone();
    for opt in given_options.iter() {
      let opt_strings = &[opt.short_name.clone(), opt.long_name.clone()];
      self.set_opt(opt.long_name.clone(), matches.opts_str(opt_strings))
    };
    None
  }

  /// Returns the usage string for the stored OptGroups. Pass `brief`
  /// to have it included.
  pub fn usage(&self, brief: &str) -> ~str {
    usage(brief, self.options)
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use std::rt::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr};
  use extra::getopts::groups::*;

  #[deriving(ToStr)]
  enum Keys {
    Ip,
    Port,
    Addr
  }

  pub trait SocketSettings {
    fn socket(&self) -> SocketAddr;
    fn port(&self) -> u16;
    fn ip(&self) -> IpAddr;
  }

  impl SocketSettings for Settings {
    fn socket(&self) -> SocketAddr {
      do self.fetch_with(Addr) |addr| {
        match addr {
          Some(socket_addr) => { socket_addr },
          None => {
            let port: u16 = self.port();
            let ip: IpAddr = self.ip();
            SocketAddr { ip: ip, port: port }
          }
        }
      }
    }

    fn port(&self) -> u16 {
      self.fetch(Port).unwrap_or(8080)
    }

    fn ip(&self) -> IpAddr {
      self.fetch(Ip).unwrap_or(Ipv4Addr(127,0,0,1))
    }
  }

  #[test]
  fn test_simple_conversion() {
    let mut settings = Settings::new();
    settings.set("port", 12345);
    let settings = settings.fetch("port");
    assert_eq!(Some(12345), settings)
  }

  #[test]
  #[should_fail]
  fn test_should_fail_on_garbage() {
    let mut settings = Settings::new();
    settings.set("port", "foobar");
    let settings: Option<int> = settings.fetch("port");
    assert_eq!(Some(12345), settings)
  }

  #[test]
  fn test_enum() {
    let mut settings = Settings::new();
    settings.set(Port, 12345);
    let settings = settings.fetch(Port);
    assert_eq!(Some(12345), settings)
  }

  #[test]
  fn test_compound_socket_settings() {
    let mut settings = Settings::new();
    settings.set(Port, "12345");
    settings.set(Ip, "127.0.0.1");
    let socket = settings.socket();
    assert_eq!(socket.to_str(), ~"127.0.0.1:12345")
  }

  #[test]
  fn test_ipv6_addr() {
    let mut settings = Settings::new();
    settings.set(Ip, "::0.0.0.1");
    let ip = settings.ip();
    assert_eq!(ip.to_str(), ~"::0.0.0.1")
  }

  #[test]
  fn test_socket_overrides_port() {
    let mut settings = Settings::new();
    settings.set(Port, "12345");
    settings.set(Ip, "127.0.0.1");
    settings.set(Addr, "0.0.0.0:4567");
    let socket = settings.socket();
    assert_eq!(socket.to_str(), ~"0.0.0.0:4567")
  }

  #[test]
  fn test_opt_parse_optional() {
    let mut settings = Settings::new();
    settings.opt(optopt("p", "port", "The port to bind to", "eg: 4000"));

    let args = ~[~"myprog", ~"-p", ~"3000"];
    let error = settings.load_args(args);

    assert!(error.is_none());
    assert_eq!(settings.fetch("port"), Some(3000))
  }

  #[test]
  fn test_opt_parse_req_with_given() {
    let mut settings = Settings::new();
    settings.opt(reqopt("p", "port", "The port to bind to", "eg: 4000"));

    let args = ~[~"myprog", ~"-p", ~"3000"];
    let error = settings.load_args(args);

    assert!(error.is_none());
    assert_eq!(settings.fetch("port"), Some(3000))
  }

  #[test]
  fn test_opt_parse_req_without_given() {
    let mut settings = Settings::new();
    settings.opt(reqopt("p", "port", "The port to bind to", "eg: 4000"));

    let args = ~[~"myprog"];
    let error = settings.load_args(args);

    assert!(error.is_some());
    let port: Option<int> = settings.fetch("port");
    assert_eq!(port, None)
  }

  #[test]
  fn test_usage() {
    let mut settings = Settings::new();
    settings.opt(reqopt("p", "port", "The port to bind to", "eg: 4000"));
    let usage = settings.usage(&"this is how it works");

    assert!(usage.contains("this is how it works"))
    assert!(usage.contains("--port"))
  }

  #[test]
  fn test_goes_up_to_eleven() {
    let mut settings = Settings::new();
    settings.set("knob", 11);
    assert_eq!(settings.fetch("knob"), Some(11));
  }
}<commit_msg>Compatibility to current rust master<commit_after>#[link(name = "knob",
       vers = "1.0.1",
       package_id = "knob",
       uuid = "3299B6C2-99DE-44FD-8867-8EE7304959D7",
       url = "http://github.com/skade/knob")];

#[crate_type = "lib"];
#[comment = "A convenient Rust settings system"];
#[license = "MIT"];

//! A convenient structure to store and load settings.
//!
//! It is meant for items that are rarely read and stored, like command line flags or
//! application configuration.
//!
//! knob::Settings expects all values to implement ToStr + FromStr and stores them as
//! strings internally. This allows sideloading of settings through multiple means, e.g.
//! the command line or a simple config file. knob is not meant for structured data. If
//! you want to load such data, store the location of the data as a Knob setting and do
//! the loading parsing yourself.
//!
//! knob is typesafe in a sense that it will return you the type you wanted back if possible and
//! fails otherwise.
//!
//! knob allows you to decorate the Settings structure yourself for convenience (see examples).
//!
//! # Storing and fetching values
//!
//! The following example shows you how to store an ip in knob:
//!
//! ~~~{.rust}
//! extern mod knob;
//! use knob::*;
//! use std::rt::io::net::ip::IpAddr;
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set("ip", "0.0.0.0:4567");
//!   let socket: IpAddr = settings.socket();
//!   assert_eq!(socket.to_str(), ~"0.0.0.0:4567")
//! }
//! ~~~
//!
//! This works the same for IPv6 addresses:
//!
//! ~~~{.rust}
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set("ip", "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch("ip");
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! # Providing your own keys
//!
//! You can use enums as keys, as long as they implement ToStr:
//!
//! ~~~{.rust}
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch(Ip);
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! # Registering command line options
//!
//! Knob allows you to register command line options to read from the command line later.
//!
//! The options are getopts option groups.
//!
//! If the loading of the command line args fails, an error will be returned.
//!
//! ~~~{.rust}
//! use extra::getopts::groups::*;
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.opt(optopt("p", "port", "the port to bind to", "4000"))
//!   settings.opt(reqopt("e", "environment", "the environment to run in", ""));;
//!   let errors = settings.load_os_args();
//!   if errors.is_some() {
//!     println(settings.usage("Try one of these:"))
//!   }
//! }
//! ~~~
//!
//! # Decorating the settings struct
//!
//! To make matters more convenient, you can implement a decorator
//! to implement your own loading behaviour.
//!
//! ~~~{.rust}
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! pub trait SocketSettings {
//!   fn socket(&self) -> SocketAddr;
//!   fn port(&self) -> u16;
//!   fn ip(&self) -> IpAddr;
//! }
//!
//! impl SocketSettings for Settings {
//!   fn socket(&self) -> SocketAddr {
//!     do self.fetch_with(Addr) |addr| {
//!       match addr {
//!         Some(socket_addr) => { socket_addr },
//!         None => {
//!           let port: u16 = self.port();
//!           let ip: IpAddr = self.ip();
//!           SocketAddr { ip: ip, port: port }
//!         }
//!       }
//!     }
//!   }
//!
//!   fn port(&self) -> u16 {
//!     self.fetch(Port).unwrap_or(8080)
//!   }
//!
//!   fn ip(&self) -> IpAddr {
//!     self.fetch(Ip).unwrap_or(Ipv4Addr(127,0,0,1))
//!   }
//! }
//! enum Keys {
//!   Port,
//!   Ip,
//! }
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.ip();
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! knob goes up to 11.

extern mod extra;

use std::hashmap::HashMap;
use std::os;

use extra::getopts::groups::{OptGroup,getopts,usage};
use extra::getopts::Fail_;

/// The settings structure we save the options and settings in.
#[deriving(Clone)]
pub struct Settings {
  priv store: HashMap<~str,~str>,
  priv options: ~[OptGroup],
}

impl Settings {
  /// Create a new Settings struct.
  pub fn new() -> Settings {
    Settings { store: HashMap::new(), options: ~[] }
  }

  /// Set a settings key to a value. The value will be serialized.
  pub fn set<A: ToStr, T: ToStr>(&mut self, setting: A, value: T) {
    self.store.swap(setting.to_str(), value.to_str());
  }

  /// Set a value using an Option struct. The value will only be set if the
  /// Some value is given. This way, you can avoid unwrapping the result of a
  /// previous operation by yourself.
  pub fn set_opt<A: ToStr, T: ToStr>(&mut self, setting: A, value: Option<T>) {
    if !value.is_none() {
      self.store.swap(setting.to_str(), value.unwrap().to_str());
    }
  }

  /// Fetch a setting for a key. Fails if the setting is present but could not be
  /// parsed.
  pub fn fetch<A: ToStr, T: FromStr>(&self, setting: A) -> Option<T> {
    match self.store.find(&setting.to_str()) {
      Some(string) => {
        let value = from_str(string.to_owned());
        if value.is_none() {
          fail!("setting could not be parsed:" + setting.to_str())
        }
        value
      },
      None => { None }
    }
  }

  /// Fetch a setting for a key and pass it to given function. The result of the function
  /// will be returned.
  pub fn fetch_with<A: ToStr, T: FromStr>(&self, setting: A, f: |Option<T>| -> T) -> T {
    let value = self.fetch(setting.to_str());
    f(value)
  }

  /// Register a commandline for laster use with load_args.
  ///
  /// Currently, only optopt and reqopt are properly supported.
  pub fn opt(&mut self, opt: OptGroup) {
    self.options.push(opt);
  }

  /// Load the command line argument given by the OS.
  ///
  /// Optionally returns failures.
  pub fn load_os_args(&mut self) -> Option<Fail_> {
    let args = os::args();
    self.load_args(args)
  }

  /// Load a list of command line arguments.
  ///
  /// Automatically sets "knob.progname" to the name of the program.
  ///
  /// Optionally returns failures.
  pub fn load_args(&mut self, args: ~[~str]) -> Option<Fail_> {
    let ref prog_name = args[0];

    self.set("knob.progname", prog_name.clone());

    let matches = match getopts(args.tail(), self.options) {
      Ok(m) => { m }
      Err(fail) => { return Some(fail) }
    };

    let given_options = self.options.clone();
    for opt in given_options.iter() {
      let opt_strings = &[opt.short_name.clone(), opt.long_name.clone()];
      self.set_opt(opt.long_name.clone(), matches.opts_str(opt_strings))
    };
    None
  }

  /// Returns the usage string for the stored OptGroups. Pass `brief`
  /// to have it included.
  pub fn usage(&self, brief: &str) -> ~str {
    usage(brief, self.options)
  }
}

#[cfg(test)]
mod tests {
  use super::Settings;
  use std::rt::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr};
  use extra::getopts::groups::optopt;

  #[deriving(ToStr)]
  enum Keys {
    Ip,
    Port,
    Addr
  }

  pub trait SocketSettings {
    fn socket(&self) -> SocketAddr;
    fn port(&self) -> u16;
    fn ip(&self) -> IpAddr;
  }

  impl SocketSettings for Settings {
    fn socket(&self) -> SocketAddr {
      do self.fetch_with(Addr) |addr| {
        match addr {
          Some(socket_addr) => { socket_addr },
          None => {
            let port: u16 = self.port();
            let ip: IpAddr = self.ip();
            SocketAddr { ip: ip, port: port }
          }
        }
      }
    }

    fn port(&self) -> u16 {
      self.fetch(Port).unwrap_or(8080)
    }

    fn ip(&self) -> IpAddr {
      self.fetch(Ip).unwrap_or(Ipv4Addr(127,0,0,1))
    }
  }

  #[test]
  fn test_simple_conversion() {
    let mut settings = Settings::new();
    settings.set("port", 12345);
    let settings = settings.fetch("port");
    assert_eq!(Some(12345), settings)
  }

  #[test]
  #[should_fail]
  fn test_should_fail_on_garbage() {
    let mut settings = Settings::new();
    settings.set("port", "foobar");
    let settings: Option<int> = settings.fetch("port");
    assert_eq!(Some(12345), settings)
  }

  #[test]
  fn test_enum() {
    let mut settings = Settings::new();
    settings.set(Port, 12345);
    let settings = settings.fetch(Port);
    assert_eq!(Some(12345), settings)
  }

  #[test]
  fn test_compound_socket_settings() {
    let mut settings = Settings::new();
    settings.set(Port, "12345");
    settings.set(Ip, "127.0.0.1");
    let socket = settings.socket();
    assert_eq!(socket.to_str(), ~"127.0.0.1:12345")
  }

  #[test]
  fn test_ipv6_addr() {
    let mut settings = Settings::new();
    settings.set(Ip, "::0.0.0.1");
    let ip = settings.ip();
    assert_eq!(ip.to_str(), ~"::0.0.0.1")
  }

  #[test]
  fn test_socket_overrides_port() {
    let mut settings = Settings::new();
    settings.set(Port, "12345");
    settings.set(Ip, "127.0.0.1");
    settings.set(Addr, "0.0.0.0:4567");
    let socket = settings.socket();
    assert_eq!(socket.to_str(), ~"0.0.0.0:4567")
  }

  #[test]
  fn test_opt_parse_optional() {
    let mut settings = Settings::new();
    settings.opt(optopt("p", "port", "The port to bind to", "eg: 4000"));

    let args = ~[~"myprog", ~"-p", ~"3000"];
    let error = settings.load_args(args);

    assert!(error.is_none());
    assert_eq!(settings.fetch("port"), Some(3000))
  }

  #[test]
  fn test_opt_parse_req_with_given() {
    let mut settings = Settings::new();
    settings.opt(reqopt("p", "port", "The port to bind to", "eg: 4000"));

    let args = ~[~"myprog", ~"-p", ~"3000"];
    let error = settings.load_args(args);

    assert!(error.is_none());
    assert_eq!(settings.fetch("port"), Some(3000))
  }

  #[test]
  fn test_opt_parse_req_without_given() {
    let mut settings = Settings::new();
    settings.opt(reqopt("p", "port", "The port to bind to", "eg: 4000"));

    let args = ~[~"myprog"];
    let error = settings.load_args(args);

    assert!(error.is_some());
    let port: Option<int> = settings.fetch("port");
    assert_eq!(port, None)
  }

  #[test]
  fn test_usage() {
    let mut settings = Settings::new();
    settings.opt(reqopt("p", "port", "The port to bind to", "eg: 4000"));
    let usage = settings.usage(&"this is how it works");

    assert!(usage.contains("this is how it works"))
    assert!(usage.contains("--port"))
  }

  #[test]
  fn test_goes_up_to_eleven() {
    let mut settings = Settings::new();
    settings.set("knob", 11);
    assert_eq!(settings.fetch("knob"), Some(11));
  }
}<|endoftext|>


<commit_before>use std::sync::{atomic, Arc};
use std::{thread, time};

use jsonrpc_core::*;
use jsonrpc_pubsub::{PubSubHandler, Session, Subscriber, SubscriptionId};
use jsonrpc_tcp_server::{RequestContext, ServerBuilder};

/// To test the server:
///
/// ```bash
/// $ netcat localhost 3030 -
/// {"id":1,"jsonrpc":"2.0","method":"hello_subscribe","params":[10]}
///
/// ```
fn main() {
	let mut io = PubSubHandler::new(MetaIoHandler::default());
	io.add_sync_method("say_hello", |_params: Params| Ok(Value::String("hello".to_string())));

	let is_done = Arc::new(atomic::AtomicBool::default());
	let is_done2 = is_done.clone();
	io.add_subscription(
		"hello",
		("subscribe_hello", move |params: Params, _, subscriber: Subscriber| {
			if params != Params::None {
				subscriber
					.reject(Error {
						code: ErrorCode::ParseError,
						message: "Invalid parameters. Subscription rejected.".into(),
						data: None,
					})
					.unwrap();
				return;
			}

			let is_done = is_done.clone();
			thread::spawn(move || {
				let sink = subscriber.assign_id(SubscriptionId::Number(5)).unwrap();
				// or subscriber.reject(Error {} );
				// or drop(subscriber)

				loop {
					if is_done.load(atomic::Ordering::AcqRel) {
						return;
					}

					thread::sleep(time::Duration::from_millis(100));
					match sink.notify(Params::Array(vec![Value::Number(10.into())])) {
						Ok(_) => {}
						Err(_) => {
							println!("Subscription has ended, finishing.");
							break;
						}
					}
				}
			});
		}),
		("remove_hello", move |_id: SubscriptionId, _| {
			println!("Closing subscription");
			is_done2.store(true, atomic::Ordering::AcqRel);
			futures::future::ok(Value::Bool(true))
		}),
	);

	let server = ServerBuilder::new(io)
		.session_meta_extractor(|context: &RequestContext| Some(Arc::new(Session::new(context.sender.clone()))))
		.start(&"127.0.0.1:3030".parse().unwrap())
		.expect("Unable to start RPC server");

	server.wait();
}
<commit_msg>Fix typos (#587)<commit_after>use std::sync::{atomic, Arc};
use std::{thread, time};

use jsonrpc_core::*;
use jsonrpc_pubsub::{PubSubHandler, Session, Subscriber, SubscriptionId};
use jsonrpc_tcp_server::{RequestContext, ServerBuilder};

/// To test the server:
///
/// ```bash
/// $ netcat localhost 3030 -
/// {"id":1,"jsonrpc":"2.0","method":"hello_subscribe","params":[10]}
///
/// ```
fn main() {
	let mut io = PubSubHandler::new(MetaIoHandler::default());
	io.add_sync_method("say_hello", |_params: Params| Ok(Value::String("hello".to_string())));

	let is_done = Arc::new(atomic::AtomicBool::default());
	let is_done2 = is_done.clone();
	io.add_subscription(
		"hello",
		("subscribe_hello", move |params: Params, _, subscriber: Subscriber| {
			if params != Params::None {
				subscriber
					.reject(Error {
						code: ErrorCode::ParseError,
						message: "Invalid parameters. Subscription rejected.".into(),
						data: None,
					})
					.unwrap();
				return;
			}

			let is_done = is_done.clone();
			thread::spawn(move || {
				let sink = subscriber.assign_id(SubscriptionId::Number(5)).unwrap();
				// or subscriber.reject(Error {} );
				// or drop(subscriber)

				loop {
					if is_done.load(atomic::Ordering::SeqCst) {
						return;
					}

					thread::sleep(time::Duration::from_millis(100));
					match sink.notify(Params::Array(vec![Value::Number(10.into())])) {
						Ok(_) => {}
						Err(_) => {
							println!("Subscription has ended, finishing.");
							break;
						}
					}
				}
			});
		}),
		("remove_hello", move |_id: SubscriptionId, _| {
			println!("Closing subscription");
			is_done2.store(true, atomic::Ordering::SeqCst);
			futures::future::ok(Value::Bool(true))
		}),
	);

	let server = ServerBuilder::new(io)
		.session_meta_extractor(|context: &RequestContext| Some(Arc::new(Session::new(context.sender.clone()))))
		.start(&"127.0.0.1:3030".parse().unwrap())
		.expect("Unable to start RPC server");

	server.wait();
}
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::env;
use rustc_serialize::json::{ToJson, Json};
use uuid::Uuid;
use error::Error;
use super::conn;
use Track;

#[derive(Debug)]
pub struct Entry {
    pub id:      Uuid,
    pub url:     String,
    pub tracks:  Vec<Track>,
}

impl ToJson for Entry {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("id".to_string(),  self.id.to_string().to_json());
        d.insert("url".to_string(), self.url.to_json());
        let ref tracks = self.tracks;
        let mut t = Vec::new();
        for ref x in tracks.iter() {
            t.push(x.to_json());
        }
        d.insert("tracks".to_string(), Json::Array(t));
        Json::Object(d)
    }
}

impl Entry {
    pub fn find_by_id(id: String) -> Result<Entry, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, url FROM entries WHERE id = $1").unwrap();
        for row in stmt.query(&[&id]).unwrap().iter() {
            return Ok(Entry {
                    id: row.get(0),
                   url: row.get(1),
                tracks: Track::find_by_entry_id(row.get(0))
            });
        }
        return Err(Error::NotFound)
    }

    pub fn find_by_url(url: &str) -> Result<Entry, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, url FROM entries WHERE url = $1").unwrap();
        for row in stmt.query(&[&url]).unwrap().iter() {
            return Ok(Entry {
                    id: row.get(0),
                   url: row.get(1),
                tracks: Track::find_by_entry_id(row.get(0))
            });
        }
        return Err(Error::NotFound)
    }

    pub fn find_all() -> Vec<Entry> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, url FROM entries").unwrap();
        let mut entries = Vec::new();
        for row in stmt.query(&[]).unwrap().iter() {
            entries.push(Entry {
                    id: row.get(0),
                   url: row.get(1),
                tracks: Track::find_by_entry_id(row.get(0))
            })
        }
        return entries
    }

    pub fn find_or_create_by_url(url: String) -> Result<Entry, Error> {
        match Entry::find_by_url(&url) {
            Ok(entry) => Ok(entry),
            Err(_)    => Entry::create_by_url(url)
        }
    }

    pub fn create_by_url(url: String) -> Result<Entry, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("INSERT INTO entries (url) VALUES ($1) RETURNING id").unwrap();
        for row in stmt.query(&[&url]).unwrap().iter() {
            let entry = Entry {
                      id: row.get(0),
                     url: url,
                  tracks: Vec::new()
            };
            return Ok(entry);
        }
        Err(Error::Unexpected)
    }

    pub fn add_track(&mut self, track: Track) {
        let conn = conn().unwrap();
        let stmt = conn.prepare("INSERT INTO track_entries (track_id, entry_id)
                                 VALUES ($1, $2)").unwrap();
        stmt.query(&[&track.id, &self.id]).unwrap();
        self.tracks.push(track);
    }

    pub fn save(&self) -> bool {
        return true
    }
}
<commit_msg>Refactoring. Remove unnecessarily use statement<commit_after>use std::collections::BTreeMap;
use rustc_serialize::json::{ToJson, Json};
use uuid::Uuid;
use error::Error;
use super::conn;
use Track;

#[derive(Debug)]
pub struct Entry {
    pub id:      Uuid,
    pub url:     String,
    pub tracks:  Vec<Track>,
}

impl ToJson for Entry {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("id".to_string(),  self.id.to_string().to_json());
        d.insert("url".to_string(), self.url.to_json());
        let ref tracks = self.tracks;
        let mut t = Vec::new();
        for ref x in tracks.iter() {
            t.push(x.to_json());
        }
        d.insert("tracks".to_string(), Json::Array(t));
        Json::Object(d)
    }
}

impl Entry {
    pub fn find_by_id(id: String) -> Result<Entry, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, url FROM entries WHERE id = $1").unwrap();
        for row in stmt.query(&[&id]).unwrap().iter() {
            return Ok(Entry {
                    id: row.get(0),
                   url: row.get(1),
                tracks: Track::find_by_entry_id(row.get(0))
            });
        }
        return Err(Error::NotFound)
    }

    pub fn find_by_url(url: &str) -> Result<Entry, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, url FROM entries WHERE url = $1").unwrap();
        for row in stmt.query(&[&url]).unwrap().iter() {
            return Ok(Entry {
                    id: row.get(0),
                   url: row.get(1),
                tracks: Track::find_by_entry_id(row.get(0))
            });
        }
        return Err(Error::NotFound)
    }

    pub fn find_all() -> Vec<Entry> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, url FROM entries").unwrap();
        let mut entries = Vec::new();
        for row in stmt.query(&[]).unwrap().iter() {
            entries.push(Entry {
                    id: row.get(0),
                   url: row.get(1),
                tracks: Track::find_by_entry_id(row.get(0))
            })
        }
        return entries
    }

    pub fn find_or_create_by_url(url: String) -> Result<Entry, Error> {
        match Entry::find_by_url(&url) {
            Ok(entry) => Ok(entry),
            Err(_)    => Entry::create_by_url(url)
        }
    }

    pub fn create_by_url(url: String) -> Result<Entry, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("INSERT INTO entries (url) VALUES ($1) RETURNING id").unwrap();
        for row in stmt.query(&[&url]).unwrap().iter() {
            let entry = Entry {
                      id: row.get(0),
                     url: url,
                  tracks: Vec::new()
            };
            return Ok(entry);
        }
        Err(Error::Unexpected)
    }

    pub fn add_track(&mut self, track: Track) {
        let conn = conn().unwrap();
        let stmt = conn.prepare("INSERT INTO track_entries (track_id, entry_id)
                                 VALUES ($1, $2)").unwrap();
        stmt.query(&[&track.id, &self.id]).unwrap();
        self.tracks.push(track);
    }

    pub fn save(&self) -> bool {
        return true
    }
}
<|endoftext|>


<commit_before>use core::clone::Clone;
use core::mem::size_of;
use core::option::Option;

use alloc::boxed::*;

use common::debug::*;
use common::memory::*;
use common::random::*;
use common::string::*;
use common::vec::*;

use network::common::*;

#[derive(Copy, Clone)]
pub struct TCPHeader {
    pub src: n16,
    pub dst: n16,
    pub sequence: n32,
    pub ack_num: n32,
    pub flags: n16,
    pub window_size: n16,
    pub checksum: Checksum,
    pub urgent_pointer: n16
}

pub struct TCP {
    header: TCPHeader,
    options: Vec<u8>,
    data: Vec<u8>,
    src_ip: IPv4Addr,
    dst_ip: IPv4Addr
}

impl ToBytes for TCP {
    fn to_bytes(&self) -> Vec<u8> {
        unsafe{
            let header_ptr: *const TCPHeader = &self.header;
            let mut ret = Vec::from_raw_buf(header_ptr as *const u8, size_of::<TCPHeader>());
            ret.push_all(&self.options);
            ret.push_all(&self.data);
            return ret;
        }
    }
}

const TCP_FIN: u16 = 1;
const TCP_SYN: u16 = 1 << 1;
const TCP_RST: u16 = 1 << 2;
const TCP_PSH: u16 = 1 << 3;
const TCP_ACK: u16 = 1 << 4;

#[allow(trivial_casts)]
impl Response for TCP {
    fn respond(&self, callback: Box<FnBox(Vec<Vec<u8>>)>){
        if cfg!(debug_network){
            d("            ");
            self.d();
            dl();
        }

        let allow;
        match self.header.dst.get() {
            80 => allow = true,
            _ => allow = false
        }

        if allow {
            if self.header.flags.get() & TCP_SYN != 0 {
                if cfg!(debug_network){
                    d("            TCP SYN\n");
                }
                let mut response = TCP {
                    header: self.header,
                    options: self.options.clone(),
                    data: Vec::new(),
                    src_ip: IP_ADDR,
                    dst_ip: self.src_ip
                };

                response.header.src = self.header.dst;
                response.header.dst = self.header.src;
                response.header.flags.set(self.header.flags.get() | TCP_ACK);
                response.header.ack_num.set(self.header.sequence.get() + 1);
                response.header.sequence.set(rand() as u32);

                unsafe{
                    response.header.checksum.data = 0;

                    let proto = n16::new(0x06);
                    let segment_len = n16::new((size_of::<TCPHeader>() + response.options.len() + response.data.len()) as u16);
                    response.header.checksum.data = Checksum::compile(
                        Checksum::sum((&response.src_ip as *const IPv4Addr) as usize, size_of::<IPv4Addr>()) +
                        Checksum::sum((&response.dst_ip as *const IPv4Addr) as usize, size_of::<IPv4Addr>()) +
                        Checksum::sum((&proto as *const n16) as usize, size_of::<n16>()) +
                        Checksum::sum((&segment_len as *const n16) as usize, size_of::<n16>()) +
                        Checksum::sum((&response.header as *const TCPHeader) as usize, size_of::<TCPHeader>()) +
                        Checksum::sum(response.options.as_ptr() as usize, response.options.len()) +
                        Checksum::sum(response.data.as_ptr() as usize, response.data.len())
                    );
                }

                let mut ret: Vec<Vec<u8>> = Vec::new();
                ret.push(response.to_bytes());
                callback(ret);
            }else if self.header.flags.get() & TCP_PSH != 0{
                if cfg!(debug_network){
                    d("            TCP PSH\n");
                }
                //Send TCP_ACK_PSH_FIN in one statement
                {
                    let tcp_header = self.header;
                    let tcp_options = self.options.clone();
                    let tcp_dst_ip = self.src_ip;
                    let tcp_data = self.data.clone();
                    let tcp_callback = box move |data: String|{
                        let mut response = TCP {
                            header: tcp_header,
                            options: tcp_options.clone(),
                            data: Vec::new(),
                            src_ip: IP_ADDR,
                            dst_ip: tcp_dst_ip
                        };

                        response.header.src = tcp_header.dst;
                        response.header.dst = tcp_header.src;
                        response.header.flags.set(tcp_header.flags.get() | TCP_FIN);
                        response.header.ack_num.set(tcp_header.sequence.get() + tcp_data.len() as u32);
                        response.header.sequence.set(tcp_header.ack_num.get());

                        unsafe{
                            let data_ptr = data.to_c_str();
                            response.data = Vec::from_raw_buf(data_ptr, data.len());
                            unalloc(data_ptr as usize);
                        }

                        response.header.checksum.data = 0;

                        let proto = n16::new(0x06);
                        let segment_len = n16::new((size_of::<TCPHeader>() + response.options.len() + response.data.len()) as u16);
                        unsafe{
                            response.header.checksum.data = Checksum::compile(
                                Checksum::sum((&response.src_ip as *const IPv4Addr) as usize, size_of::<IPv4Addr>()) +
                                Checksum::sum((&response.dst_ip as *const IPv4Addr) as usize, size_of::<IPv4Addr>()) +
                                Checksum::sum((&proto as *const n16) as usize, size_of::<n16>()) +
                                Checksum::sum((&segment_len as *const n16) as usize, size_of::<n16>()) +
                                Checksum::sum((&response.header as *const TCPHeader) as usize, size_of::<TCPHeader>()) +
                                Checksum::sum(response.options.as_ptr() as usize, response.options.len()) +
                                Checksum::sum(response.data.as_ptr() as usize, response.data.len())
                            );
                        }

                        let mut ret: Vec<Vec<u8>> = Vec::new();
                        ret.push(response.to_bytes());
                        callback(ret);
                    };

                    match self.header.dst.get() {
                        80 => {
                            let request = String::from_c_slice(self.data.as_slice());

                            let mut path = "/".to_string();

                            for row in request.split("\r\n".to_string()) {
                                let mut i = 0;
                                for col in row.split(" ".to_string()) {
                                    match i {
                                        1 => path = col,
                                        _ => ()
                                    }
                                    i += 1;
                                }
                                break;
                            }

                            //session.request(&URL::from_string("http://".to_string() + path), tcp_callback);
                        },
                        _ => ()
                    }
                }
            }
        }else{
            d("            TCP RST TODO\n");
        }
    }
}

impl TCP {
    pub fn from_bytes_ipv4(bytes: Vec<u8>, src_ip: IPv4Addr, dst_ip: IPv4Addr) -> Option<TCP> {
        if bytes.len() >= size_of::<TCPHeader>() {
            unsafe {
                let header = *(bytes.as_ptr() as *const TCPHeader);
                let header_len = ((header.flags.get() & 0xF000) >> 10) as usize;

                return Option::Some(TCP {
                    header: header,
                    options: bytes.sub(size_of::<TCPHeader>(), header_len - size_of::<TCPHeader>()),
                    data: bytes.sub(header_len, bytes.len() - header_len),
                    src_ip: src_ip,
                    dst_ip: dst_ip
                });
            }
        }
        return Option::None;
    }

    pub fn d(&self){
        d("TCP from ");
        dd(self.header.src.get() as usize);
        d(" to ");
        dd(self.header.dst.get() as usize);
        d(" options ");
        dd(self.options.len());
        d(" data ");
        dd(self.data.len());
    }
}
<commit_msg>Allow HTTP response<commit_after>use core::clone::Clone;
use core::mem::size_of;
use core::option::Option;

use alloc::boxed::*;

use common::debug::*;
use common::memory::*;
use common::random::*;
use common::resource::*;
use common::string::*;
use common::vec::*;

use network::common::*;

#[derive(Copy, Clone)]
pub struct TCPHeader {
    pub src: n16,
    pub dst: n16,
    pub sequence: n32,
    pub ack_num: n32,
    pub flags: n16,
    pub window_size: n16,
    pub checksum: Checksum,
    pub urgent_pointer: n16
}

pub struct TCP {
    header: TCPHeader,
    options: Vec<u8>,
    data: Vec<u8>,
    src_ip: IPv4Addr,
    dst_ip: IPv4Addr
}

impl ToBytes for TCP {
    fn to_bytes(&self) -> Vec<u8> {
        unsafe{
            let header_ptr: *const TCPHeader = &self.header;
            let mut ret = Vec::from_raw_buf(header_ptr as *const u8, size_of::<TCPHeader>());
            ret.push_all(&self.options);
            ret.push_all(&self.data);
            return ret;
        }
    }
}

const TCP_FIN: u16 = 1;
const TCP_SYN: u16 = 1 << 1;
const TCP_RST: u16 = 1 << 2;
const TCP_PSH: u16 = 1 << 3;
const TCP_ACK: u16 = 1 << 4;

#[allow(trivial_casts)]
impl Response for TCP {
    fn respond(&self, callback: Box<FnBox(Vec<Vec<u8>>)>){
        if cfg!(debug_network){
            d("            ");
            self.d();
            dl();
        }

        let allow;
        match self.header.dst.get() {
            80 => allow = true,
            _ => allow = false
        }

        if allow {
            if self.header.flags.get() & TCP_SYN != 0 {
                if cfg!(debug_network){
                    d("            TCP SYN\n");
                }
                let mut response = TCP {
                    header: self.header,
                    options: self.options.clone(),
                    data: Vec::new(),
                    src_ip: IP_ADDR,
                    dst_ip: self.src_ip
                };

                response.header.src = self.header.dst;
                response.header.dst = self.header.src;
                response.header.flags.set(self.header.flags.get() | TCP_ACK);
                response.header.ack_num.set(self.header.sequence.get() + 1);
                response.header.sequence.set(rand() as u32);

                unsafe{
                    response.header.checksum.data = 0;

                    let proto = n16::new(0x06);
                    let segment_len = n16::new((size_of::<TCPHeader>() + response.options.len() + response.data.len()) as u16);
                    response.header.checksum.data = Checksum::compile(
                        Checksum::sum((&response.src_ip as *const IPv4Addr) as usize, size_of::<IPv4Addr>()) +
                        Checksum::sum((&response.dst_ip as *const IPv4Addr) as usize, size_of::<IPv4Addr>()) +
                        Checksum::sum((&proto as *const n16) as usize, size_of::<n16>()) +
                        Checksum::sum((&segment_len as *const n16) as usize, size_of::<n16>()) +
                        Checksum::sum((&response.header as *const TCPHeader) as usize, size_of::<TCPHeader>()) +
                        Checksum::sum(response.options.as_ptr() as usize, response.options.len()) +
                        Checksum::sum(response.data.as_ptr() as usize, response.data.len())
                    );
                }

                let mut ret: Vec<Vec<u8>> = Vec::new();
                ret.push(response.to_bytes());
                callback(ret);
            }else if self.header.flags.get() & TCP_PSH != 0{
                if cfg!(debug_network){
                    d("            TCP PSH\n");
                }
                //Send TCP_ACK_PSH_FIN in one statement
                {
                    match self.header.dst.get() {
                        80 => {
                            let request = String::from_c_slice(self.data.as_slice());

                            let mut path = "/".to_string();

                            for row in request.split("\r\n".to_string()) {
                                let mut i = 0;
                                for col in row.split(" ".to_string()) {
                                    match i {
                                        1 => path = col,
                                        _ => ()
                                    }
                                    i += 1;
                                }
                                break;
                            }

                            let tcp_header = self.header;
                            let tcp_options = self.options.clone();
                            let tcp_dst_ip = self.src_ip;
                            let tcp_data = self.data.clone();
                            URL::from_string("http://".to_string() + path).open_async(box move |mut resource: Box<Resource>|{
                                let mut vec: Vec<u8> = Vec::new();

                                match resource.read_to_end(&mut vec) {
                                    Option::Some(len) => (),
                                    Option::None => ()
                                }

                                let mut response = TCP {
                                    header: tcp_header,
                                    options: tcp_options.clone(),
                                    data: Vec::new(),
                                    src_ip: IP_ADDR,
                                    dst_ip: tcp_dst_ip
                                };

                                response.header.src = tcp_header.dst;
                                response.header.dst = tcp_header.src;
                                response.header.flags.set(tcp_header.flags.get() | TCP_FIN);
                                response.header.ack_num.set(tcp_header.sequence.get() + tcp_data.len() as u32);
                                response.header.sequence.set(tcp_header.ack_num.get());

                                response.data = vec;

                                response.header.checksum.data = 0;

                                let proto = n16::new(0x06);
                                let segment_len = n16::new((size_of::<TCPHeader>() + response.options.len() + response.data.len()) as u16);
                                unsafe{
                                    response.header.checksum.data = Checksum::compile(
                                        Checksum::sum((&response.src_ip as *const IPv4Addr) as usize, size_of::<IPv4Addr>()) +
                                        Checksum::sum((&response.dst_ip as *const IPv4Addr) as usize, size_of::<IPv4Addr>()) +
                                        Checksum::sum((&proto as *const n16) as usize, size_of::<n16>()) +
                                        Checksum::sum((&segment_len as *const n16) as usize, size_of::<n16>()) +
                                        Checksum::sum((&response.header as *const TCPHeader) as usize, size_of::<TCPHeader>()) +
                                        Checksum::sum(response.options.as_ptr() as usize, response.options.len()) +
                                        Checksum::sum(response.data.as_ptr() as usize, response.data.len())
                                    );
                                }

                                let mut ret: Vec<Vec<u8>> = Vec::new();
                                ret.push(response.to_bytes());
                                callback(ret);
                            });
                        },
                        _ => ()
                    }
                }
            }
        }else{
            d("            TCP RST TODO\n");
        }
    }
}

impl TCP {
    pub fn from_bytes_ipv4(bytes: Vec<u8>, src_ip: IPv4Addr, dst_ip: IPv4Addr) -> Option<TCP> {
        if bytes.len() >= size_of::<TCPHeader>() {
            unsafe {
                let header = *(bytes.as_ptr() as *const TCPHeader);
                let header_len = ((header.flags.get() & 0xF000) >> 10) as usize;

                return Option::Some(TCP {
                    header: header,
                    options: bytes.sub(size_of::<TCPHeader>(), header_len - size_of::<TCPHeader>()),
                    data: bytes.sub(header_len, bytes.len() - header_len),
                    src_ip: src_ip,
                    dst_ip: dst_ip
                });
            }
        }
        return Option::None;
    }

    pub fn d(&self){
        d("TCP from ");
        dd(self.header.src.get() as usize);
        d(" to ");
        dd(self.header.dst.get() as usize);
        d(" options ");
        dd(self.options.len());
        d(" data ");
        dd(self.data.len());
    }
}
<|endoftext|>


<commit_before><commit_msg>usb: fix deadlock in try_detach removal path<commit_after><|endoftext|>


<commit_before>// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::io;
use std::mem::{align_of, size_of};
use std::slice::{from_raw_parts, from_raw_parts_mut};

/// Types for which it is safe to initialize from raw data.
///
///
/// Implementing this trait guarantees that it is safe to instantiate the struct with random data.
///
/// # Safety
/// A type `T` is `DataInit` if it can be initialized by reading its contents from a byte array.
/// This is generally true for all plain-old-data structs.  It is notably not true for any type
/// that includes a reference.
///
/// It is unsafe for `T` to be `DataInit` if `T` contains implicit padding. (LLVM considers access
/// to implicit padding to be undefined behavior, which can cause UB when working with `T`.
/// For details on structure padding in Rust, see
/// https://doc.rust-lang.org/reference/type-layout.html#the-c-representation
pub unsafe trait DataInit: Copy + Send + Sync {
    /// Converts a slice of raw data into a reference of `Self`.
    ///
    /// The value of `data` is not copied. Instead a reference is made from the given slice. The
    /// value of `Self` will depend on the representation of the type in memory, and may change in
    /// an unstable fashion.
    ///
    /// This will return `None` if the length of data does not match the size of `Self`, or if the
    /// data is not aligned for the type of `Self`.
    fn from_slice(data: &[u8]) -> Option<&Self> {
        // Early out to avoid an unneeded `align_to` call.
        if data.len() != size_of::<Self>() {
            return None;
        }

        // Safe because the DataInit trait asserts any data is valid for this type, and we ensured
        // the size of the pointer's buffer is the correct size. The `align_to` method ensures that
        // we don't have any unaligned references. This aliases a pointer, but because the pointer
        // is from a const slice reference, there are no mutable aliases. Finally, the reference
        // returned can not outlive data because they have equal implicit lifetime constraints.
        match unsafe { data.align_to::<Self>() } {
            ([], [mid], []) => Some(mid),
            _ => None,
        }
    }

    /// Converts a mutable slice of raw data into a mutable reference of `Self`.
    ///
    /// Because `Self` is made from a reference to the mutable slice`, mutations to the returned
    /// reference are immediately reflected in `data`. The value of the returned `Self` will depend
    /// on the representation of the type in memory, and may change in an unstable fashion.
    ///
    /// This will return `None` if the length of data does not match the size of `Self`, or if the
    /// data is not aligned for the type of `Self`.
    fn from_mut_slice(data: &mut [u8]) -> Option<&mut Self> {
        // Early out to avoid an unneeded `align_to_mut` call.
        if data.len() != size_of::<Self>() {
            return None;
        }

        // Safe because the DataInit trait asserts any data is valid for this type, and we ensured
        // the size of the pointer's buffer is the correct size. The `align_to` method ensures that
        // we don't have any unaligned references. This aliases a pointer, but because the pointer
        // is from a mut slice reference, we borrow the passed in mutable reference. Finally, the
        // reference returned can not outlive data because they have equal implicit lifetime
        // constraints.
        match unsafe { data.align_to_mut::<Self>() } {
            ([], [mid], []) => Some(mid),
            _ => None,
        }
    }

    /// Creates an instance of `Self` by copying raw data from an io::Read stream.
    fn from_reader<R: io::Read>(mut read: R) -> io::Result<Self> {
        // Allocate a Vec<u8> with enough extra space for the worst-case alignment offset.
        let mut data = vec![0u8; size_of::<Self>() + align_of::<Self>()];

        // Get a u8 slice within data with sufficient alignment for Self.
        let align_offset = data.as_ptr().align_offset(align_of::<Self>());
        let mut aligned_data = &mut data[align_offset..align_offset + size_of::<Self>()];

        read.read_exact(&mut aligned_data)?;
        match Self::from_slice(&aligned_data) {
            Some(obj) => Ok(*obj),
            None => Err(io::Error::new(
                io::ErrorKind::InvalidData,
                "from_slice failed",
            )),
        }
    }

    /// Converts a reference to `self` into a slice of bytes.
    ///
    /// The value of `self` is not copied. Instead, the slice is made from a reference to `self`.
    /// The value of bytes in the returned slice will depend on the representation of the type in
    /// memory, and may change in an unstable fashion.
    fn as_slice(&self) -> &[u8] {
        // Safe because the entire size of self is accessible as bytes because the trait guarantees
        // it. The lifetime of the returned slice is the same as the passed reference, so that no
        // dangling pointers will result from this pointer alias.
        unsafe { from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
    }

    /// Converts a mutable reference to `self` into a mutable slice of bytes.
    ///
    /// Because the slice is made from a reference to `self`, mutations to the returned slice are
    /// immediately reflected in `self`. The value of bytes in the returned slice will depend on
    /// the representation of the type in memory, and may change in an unstable fashion.
    fn as_mut_slice(&mut self) -> &mut [u8] {
        // Safe because the entire size of self is accessible as bytes because the trait guarantees
        // it. The trait also guarantees that any combination of bytes is valid for this type, so
        // modifying them in the form of a byte slice is valid. The lifetime of the returned slice
        // is the same as the passed reference, so that no dangling pointers will result from this
        // pointer alias. Although this does alias a mutable pointer, we do so by exclusively
        // borrowing the given mutable reference.
        unsafe { from_raw_parts_mut(self as *mut Self as *mut u8, size_of::<Self>()) }
    }
}

// All intrinsic types and arays of intrinsic types are DataInit.  They are just numbers.
macro_rules! array_data_init {
    ($T:ty, $($N:expr)+) => {
        $(
            unsafe impl DataInit for [$T; $N] {}
        )+
    }
}
macro_rules! data_init_type {
    ($($T:ident),*) => {
        $(
            unsafe impl DataInit for $T {}
            array_data_init! {
                $T,
                0  1  2  3  4  5  6  7  8  9
                10 11 12 13 14 15 16 17 18 19
                20 21 22 23 24 25 26 27 28 29
                30 31 32
            }
        )*
        #[cfg(test)]
        mod data_init_tests {
            use std::mem::{size_of, align_of};
            use crate::DataInit;

            #[test]
            fn from_slice_alignment() {
                let mut v = [0u8; 32];
                $(
                    let (pre, _, _) = unsafe { v.align_to::<$T>() };
                    let pre_len = pre.len();

                    let aligned_v = &mut v[pre_len..pre_len + size_of::<$T>()];

                    let from_aligned = $T::from_slice(aligned_v);
                    assert_eq!(from_aligned, Some(&0));

                    let from_aligned_mut = $T::from_mut_slice(aligned_v);
                    assert_eq!(from_aligned_mut, Some(&mut 0));

                    for i in 1..size_of::<$T>() {
                        let begin = pre_len + i;
                        let end = begin + size_of::<$T>();
                        let unaligned_v = &mut v[begin..end];

                        let from_unaligned = $T::from_slice(unaligned_v);
                        if align_of::<$T>() != 1 {
                            assert_eq!(from_unaligned, None);
                        }

                        let from_unaligned_mut = $T::from_mut_slice(unaligned_v);
                        if align_of::<$T>() != 1 {
                            assert_eq!(from_unaligned_mut, None);
                        }
                    }
                )*

            }
        }
    };
}
data_init_type!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);

pub mod endian;
pub use crate::endian::*;

pub mod volatile_memory;
pub use crate::volatile_memory::*;

mod flexible_array;
pub use flexible_array::{vec_with_array_field, FlexibleArray, FlexibleArrayWrapper};

mod sys;
<commit_msg>data_model: Export IoSliceMut as a public type<commit_after>// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::io;
use std::mem::{align_of, size_of};
use std::slice::{from_raw_parts, from_raw_parts_mut};

/// Types for which it is safe to initialize from raw data.
///
///
/// Implementing this trait guarantees that it is safe to instantiate the struct with random data.
///
/// # Safety
/// A type `T` is `DataInit` if it can be initialized by reading its contents from a byte array.
/// This is generally true for all plain-old-data structs.  It is notably not true for any type
/// that includes a reference.
///
/// It is unsafe for `T` to be `DataInit` if `T` contains implicit padding. (LLVM considers access
/// to implicit padding to be undefined behavior, which can cause UB when working with `T`.
/// For details on structure padding in Rust, see
/// https://doc.rust-lang.org/reference/type-layout.html#the-c-representation
pub unsafe trait DataInit: Copy + Send + Sync {
    /// Converts a slice of raw data into a reference of `Self`.
    ///
    /// The value of `data` is not copied. Instead a reference is made from the given slice. The
    /// value of `Self` will depend on the representation of the type in memory, and may change in
    /// an unstable fashion.
    ///
    /// This will return `None` if the length of data does not match the size of `Self`, or if the
    /// data is not aligned for the type of `Self`.
    fn from_slice(data: &[u8]) -> Option<&Self> {
        // Early out to avoid an unneeded `align_to` call.
        if data.len() != size_of::<Self>() {
            return None;
        }

        // Safe because the DataInit trait asserts any data is valid for this type, and we ensured
        // the size of the pointer's buffer is the correct size. The `align_to` method ensures that
        // we don't have any unaligned references. This aliases a pointer, but because the pointer
        // is from a const slice reference, there are no mutable aliases. Finally, the reference
        // returned can not outlive data because they have equal implicit lifetime constraints.
        match unsafe { data.align_to::<Self>() } {
            ([], [mid], []) => Some(mid),
            _ => None,
        }
    }

    /// Converts a mutable slice of raw data into a mutable reference of `Self`.
    ///
    /// Because `Self` is made from a reference to the mutable slice`, mutations to the returned
    /// reference are immediately reflected in `data`. The value of the returned `Self` will depend
    /// on the representation of the type in memory, and may change in an unstable fashion.
    ///
    /// This will return `None` if the length of data does not match the size of `Self`, or if the
    /// data is not aligned for the type of `Self`.
    fn from_mut_slice(data: &mut [u8]) -> Option<&mut Self> {
        // Early out to avoid an unneeded `align_to_mut` call.
        if data.len() != size_of::<Self>() {
            return None;
        }

        // Safe because the DataInit trait asserts any data is valid for this type, and we ensured
        // the size of the pointer's buffer is the correct size. The `align_to` method ensures that
        // we don't have any unaligned references. This aliases a pointer, but because the pointer
        // is from a mut slice reference, we borrow the passed in mutable reference. Finally, the
        // reference returned can not outlive data because they have equal implicit lifetime
        // constraints.
        match unsafe { data.align_to_mut::<Self>() } {
            ([], [mid], []) => Some(mid),
            _ => None,
        }
    }

    /// Creates an instance of `Self` by copying raw data from an io::Read stream.
    fn from_reader<R: io::Read>(mut read: R) -> io::Result<Self> {
        // Allocate a Vec<u8> with enough extra space for the worst-case alignment offset.
        let mut data = vec![0u8; size_of::<Self>() + align_of::<Self>()];

        // Get a u8 slice within data with sufficient alignment for Self.
        let align_offset = data.as_ptr().align_offset(align_of::<Self>());
        let mut aligned_data = &mut data[align_offset..align_offset + size_of::<Self>()];

        read.read_exact(&mut aligned_data)?;
        match Self::from_slice(&aligned_data) {
            Some(obj) => Ok(*obj),
            None => Err(io::Error::new(
                io::ErrorKind::InvalidData,
                "from_slice failed",
            )),
        }
    }

    /// Converts a reference to `self` into a slice of bytes.
    ///
    /// The value of `self` is not copied. Instead, the slice is made from a reference to `self`.
    /// The value of bytes in the returned slice will depend on the representation of the type in
    /// memory, and may change in an unstable fashion.
    fn as_slice(&self) -> &[u8] {
        // Safe because the entire size of self is accessible as bytes because the trait guarantees
        // it. The lifetime of the returned slice is the same as the passed reference, so that no
        // dangling pointers will result from this pointer alias.
        unsafe { from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) }
    }

    /// Converts a mutable reference to `self` into a mutable slice of bytes.
    ///
    /// Because the slice is made from a reference to `self`, mutations to the returned slice are
    /// immediately reflected in `self`. The value of bytes in the returned slice will depend on
    /// the representation of the type in memory, and may change in an unstable fashion.
    fn as_mut_slice(&mut self) -> &mut [u8] {
        // Safe because the entire size of self is accessible as bytes because the trait guarantees
        // it. The trait also guarantees that any combination of bytes is valid for this type, so
        // modifying them in the form of a byte slice is valid. The lifetime of the returned slice
        // is the same as the passed reference, so that no dangling pointers will result from this
        // pointer alias. Although this does alias a mutable pointer, we do so by exclusively
        // borrowing the given mutable reference.
        unsafe { from_raw_parts_mut(self as *mut Self as *mut u8, size_of::<Self>()) }
    }
}

// All intrinsic types and arays of intrinsic types are DataInit.  They are just numbers.
macro_rules! array_data_init {
    ($T:ty, $($N:expr)+) => {
        $(
            unsafe impl DataInit for [$T; $N] {}
        )+
    }
}
macro_rules! data_init_type {
    ($($T:ident),*) => {
        $(
            unsafe impl DataInit for $T {}
            array_data_init! {
                $T,
                0  1  2  3  4  5  6  7  8  9
                10 11 12 13 14 15 16 17 18 19
                20 21 22 23 24 25 26 27 28 29
                30 31 32
            }
        )*
        #[cfg(test)]
        mod data_init_tests {
            use std::mem::{size_of, align_of};
            use crate::DataInit;

            #[test]
            fn from_slice_alignment() {
                let mut v = [0u8; 32];
                $(
                    let (pre, _, _) = unsafe { v.align_to::<$T>() };
                    let pre_len = pre.len();

                    let aligned_v = &mut v[pre_len..pre_len + size_of::<$T>()];

                    let from_aligned = $T::from_slice(aligned_v);
                    assert_eq!(from_aligned, Some(&0));

                    let from_aligned_mut = $T::from_mut_slice(aligned_v);
                    assert_eq!(from_aligned_mut, Some(&mut 0));

                    for i in 1..size_of::<$T>() {
                        let begin = pre_len + i;
                        let end = begin + size_of::<$T>();
                        let unaligned_v = &mut v[begin..end];

                        let from_unaligned = $T::from_slice(unaligned_v);
                        if align_of::<$T>() != 1 {
                            assert_eq!(from_unaligned, None);
                        }

                        let from_unaligned_mut = $T::from_mut_slice(unaligned_v);
                        if align_of::<$T>() != 1 {
                            assert_eq!(from_unaligned_mut, None);
                        }
                    }
                )*

            }
        }
    };
}
data_init_type!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);

pub mod endian;
pub use crate::endian::*;

pub mod volatile_memory;
pub use crate::volatile_memory::*;

mod flexible_array;
pub use flexible_array::{vec_with_array_field, FlexibleArray, FlexibleArrayWrapper};

mod sys;
pub use sys::IoSliceMut;
<|endoftext|>


<commit_before>use rustc_serialize::json;

use common::{Nullable, Date};

#[derive(Debug)]
pub enum WebDriverResponse {
    NewSession(NewSessionResponse),
    DeleteSession,
    WindowSize(WindowSizeResponse),
    ElementRect(ElementRectResponse),
    Cookie(CookieResponse),
    Generic(ValueResponse),
    Void
}

impl WebDriverResponse {
    pub fn to_json_string(self) -> String {
        (match self {
            WebDriverResponse::NewSession(x) => json::encode(&x),
            WebDriverResponse::DeleteSession => Ok("{}".to_string()),
            WebDriverResponse::WindowSize(x) => json::encode(&x),
            WebDriverResponse::ElementRect(x) => json::encode(&x),
            WebDriverResponse::Cookie(x) => json::encode(&x),
            WebDriverResponse::Generic(x) => json::encode(&x),
            WebDriverResponse::Void => Ok("{}".to_string())
        }).unwrap()
    }
}

#[derive(RustcEncodable, Debug)]
pub struct NewSessionResponse {
    pub sessionId: String,
    pub value: json::Json
}

impl NewSessionResponse {
    pub fn new(session_id: String, value: json::Json) -> NewSessionResponse {
        NewSessionResponse {
            value: value,
            sessionId: session_id
        }
    }
}

#[derive(RustcEncodable, Debug)]
pub struct ValueResponse {
    value: json::Json
}

impl ValueResponse {
    pub fn new(value: json::Json) -> ValueResponse {
        ValueResponse {
            value: value
        }
    }
}

#[derive(RustcEncodable, Debug)]
pub struct WindowSizeResponse {
    width: u64,
    height: u64
}

impl WindowSizeResponse {
    pub fn new(width: u64, height: u64) -> WindowSizeResponse {
        WindowSizeResponse {
            width: width,
            height: height
        }
    }
}

#[derive(RustcEncodable, Debug)]
pub struct ElementRectResponse {
    x: u64,
    y: u64,
    width: u64,
    height: u64
}

impl ElementRectResponse {
    pub fn new(x: u64, y: u64, width: u64, height: u64) -> ElementRectResponse {
        ElementRectResponse {
            x: x,
            y: y,
            width: width,
            height: height
        }
    }
}

//TODO: some of these fields are probably supposed to be optional
#[derive(RustcEncodable, PartialEq, Debug)]
pub struct Cookie {
    name: String,
    value: String,
    path: Nullable<String>,
    domain: Nullable<String>,
    expiry: Nullable<Date>,
    maxAge: Date,
    secure: bool,
    httpOnly: bool
}

impl Cookie {
    pub fn new(name: String, value: String, path: Nullable<String>, domain: Nullable<String>,
               expiry: Nullable<Date>, max_age: Date, secure: bool, http_only: bool) -> Cookie {
        Cookie {
            name: name,
            value: value,
            path: path,
            domain: domain,
            expiry: expiry,
            maxAge: max_age,
            secure: secure,
            httpOnly: http_only
        }
    }
}

#[derive(RustcEncodable, Debug)]
pub struct CookieResponse {
    value: Vec<Cookie>
}

impl CookieResponse {
    pub fn new(value: Vec<Cookie>) -> CookieResponse {
        CookieResponse {
            value: value
        }
    }
}
<commit_msg>Update getElementRect to expect floats to be returned to it<commit_after>use rustc_serialize::json;

use common::{Nullable, Date};

#[derive(Debug)]
pub enum WebDriverResponse {
    NewSession(NewSessionResponse),
    DeleteSession,
    WindowSize(WindowSizeResponse),
    ElementRect(ElementRectResponse),
    Cookie(CookieResponse),
    Generic(ValueResponse),
    Void
}

impl WebDriverResponse {
    pub fn to_json_string(self) -> String {
        (match self {
            WebDriverResponse::NewSession(x) => json::encode(&x),
            WebDriverResponse::DeleteSession => Ok("{}".to_string()),
            WebDriverResponse::WindowSize(x) => json::encode(&x),
            WebDriverResponse::ElementRect(x) => json::encode(&x),
            WebDriverResponse::Cookie(x) => json::encode(&x),
            WebDriverResponse::Generic(x) => json::encode(&x),
            WebDriverResponse::Void => Ok("{}".to_string())
        }).unwrap()
    }
}

#[derive(RustcEncodable, Debug)]
pub struct NewSessionResponse {
    pub sessionId: String,
    pub value: json::Json
}

impl NewSessionResponse {
    pub fn new(session_id: String, value: json::Json) -> NewSessionResponse {
        NewSessionResponse {
            value: value,
            sessionId: session_id
        }
    }
}

#[derive(RustcEncodable, Debug)]
pub struct ValueResponse {
    value: json::Json
}

impl ValueResponse {
    pub fn new(value: json::Json) -> ValueResponse {
        ValueResponse {
            value: value
        }
    }
}

#[derive(RustcEncodable, Debug)]
pub struct WindowSizeResponse {
    width: u64,
    height: u64
}

impl WindowSizeResponse {
    pub fn new(width: u64, height: u64) -> WindowSizeResponse {
        WindowSizeResponse {
            width: width,
            height: height
        }
    }
}

#[derive(RustcEncodable, Debug)]
pub struct ElementRectResponse {
    x: f64,
    y: f64,
    width: f64,
    height: f64
}

impl ElementRectResponse {
    pub fn new(x: f64, y: f64, width: f64, height: f64) -> ElementRectResponse {
        ElementRectResponse {
            x: x,
            y: y,
            width: width,
            height: height
        }
    }
}

//TODO: some of these fields are probably supposed to be optional
#[derive(RustcEncodable, PartialEq, Debug)]
pub struct Cookie {
    name: String,
    value: String,
    path: Nullable<String>,
    domain: Nullable<String>,
    expiry: Nullable<Date>,
    maxAge: Date,
    secure: bool,
    httpOnly: bool
}

impl Cookie {
    pub fn new(name: String, value: String, path: Nullable<String>, domain: Nullable<String>,
               expiry: Nullable<Date>, max_age: Date, secure: bool, http_only: bool) -> Cookie {
        Cookie {
            name: name,
            value: value,
            path: path,
            domain: domain,
            expiry: expiry,
            maxAge: max_age,
            secure: secure,
            httpOnly: http_only
        }
    }
}

#[derive(RustcEncodable, Debug)]
pub struct CookieResponse {
    value: Vec<Cookie>
}

impl CookieResponse {
    pub fn new(value: Vec<Cookie>) -> CookieResponse {
        CookieResponse {
            value: value
        }
    }
}
<|endoftext|>


<commit_before>//! RustGit provides facilities for reading, manipulating and creating Git repositories.
//!
//! ### Finding a changeset
//! ```rust,no_run
//! fn get_message_by_commit_id(id: &ObjectId) -> Result<String, GitError> {
//!     let path = Path::new("/path/to/repo");
//!     let repo = Repository::open(&path);
//!     commit::find_one(&id, &repo).map(|commit| commit.message)
//! }
//! ```

#![doc(html_root_url="https://kaisellgren.github.io/doc")]
#![allow(dead_code, unused_imports)]

extern crate flate;

pub mod commit;
pub mod meta;
pub mod object_id;
pub mod object_header;
pub mod object_type;
mod eobject;
mod unit_tests;
mod serialization;
mod reader;
mod conversion;
pub mod error;
pub mod file_status;
pub mod repository;
pub mod branch;
pub mod tag_type;
pub mod tag;
pub mod reference;
mod pack_file;
mod pack_index;
pub mod blob;
pub mod object_database;
pub mod commit_sort_strategy;
pub mod commit_filter;
mod extensions;
mod file_util;
mod has_meta;
mod reference_collection;<commit_msg>Update documentation<commit_after>//! `rust_git` provides facilities for reading, manipulating and creating Git repositories.
//!
//! The project is still in its early stages.
//!
//! # Examples
//! ### Finding a changeset
//! The following example finds a changeset and returns its message.
//!
//! ```rust,no_run
//! fn get_message_by_commit_id(id: &ObjectId) -> Result<String, GitError> {
//!     let path = Path::new("/path/to/repo");
//!     let repo = Repository::open(&path);
//!     commit::find_one(&id, &repo).map(|commit| commit.message)
//! }
//! ```

#![doc(html_root_url="https://kaisellgren.github.io/doc")]
#![allow(dead_code, unused_imports)]

extern crate flate;

pub mod commit;
pub mod meta;
pub mod object_id;
pub mod object_header;
pub mod object_type;
mod eobject;
mod unit_tests;
mod serialization;
mod reader;
mod conversion;
pub mod error;
pub mod file_status;
pub mod repository;
pub mod branch;
pub mod tag_type;
pub mod tag;
pub mod reference;
mod pack_file;
mod pack_index;
pub mod blob;
pub mod object_database;
pub mod commit_sort_strategy;
pub mod commit_filter;
mod extensions;
mod file_util;
mod has_meta;
mod reference_collection;<|endoftext|>


<commit_before>#![feature(test)]

extern crate complex;
extern crate dft;
extern crate test;

use complex::c64;
use test::{Bencher, black_box};

#[bench] fn complex_forward_0004(bencher: &mut Bencher) { complex_forward(   4, bencher); }
#[bench] fn complex_forward_0016(bencher: &mut Bencher) { complex_forward(  16, bencher); }
#[bench] fn complex_forward_0064(bencher: &mut Bencher) { complex_forward(  64, bencher); }
#[bench] fn complex_forward_0256(bencher: &mut Bencher) { complex_forward( 256, bencher); }
#[bench] fn complex_forward_1024(bencher: &mut Bencher) { complex_forward(1024, bencher); }
#[bench] fn complex_forward_4096(bencher: &mut Bencher) { complex_forward(4096, bencher); }

#[bench] fn real_forward_0004(bencher: &mut Bencher) { real_forward(   4, bencher); }
#[bench] fn real_forward_0016(bencher: &mut Bencher) { real_forward(  16, bencher); }
#[bench] fn real_forward_0064(bencher: &mut Bencher) { real_forward(  64, bencher); }
#[bench] fn real_forward_0256(bencher: &mut Bencher) { real_forward( 256, bencher); }
#[bench] fn real_forward_1024(bencher: &mut Bencher) { real_forward(1024, bencher); }
#[bench] fn real_forward_4096(bencher: &mut Bencher) { real_forward(4096, bencher); }

fn complex_forward(size: usize, bencher: &mut Bencher) {
    let mut data = vec![c64(42.0, 69.0); size];
    bencher.iter(|| black_box(dft::complex::forward(&mut data)));
}

fn real_forward(size: usize, bencher: &mut Bencher) {
    let mut data = vec![42.0; 2 * size];
    bencher.iter(|| black_box(dft::real::forward(&mut data)));
}
<commit_msg>Fix the benchmarks<commit_after>#![feature(test)]

extern crate dft;
extern crate test;

use dft::c64;
use test::{Bencher, black_box};

#[bench] fn complex_forward_0004(bencher: &mut Bencher) { complex_forward(   4, bencher); }
#[bench] fn complex_forward_0016(bencher: &mut Bencher) { complex_forward(  16, bencher); }
#[bench] fn complex_forward_0064(bencher: &mut Bencher) { complex_forward(  64, bencher); }
#[bench] fn complex_forward_0256(bencher: &mut Bencher) { complex_forward( 256, bencher); }
#[bench] fn complex_forward_1024(bencher: &mut Bencher) { complex_forward(1024, bencher); }
#[bench] fn complex_forward_4096(bencher: &mut Bencher) { complex_forward(4096, bencher); }

#[bench] fn real_forward_0004(bencher: &mut Bencher) { real_forward(   4, bencher); }
#[bench] fn real_forward_0016(bencher: &mut Bencher) { real_forward(  16, bencher); }
#[bench] fn real_forward_0064(bencher: &mut Bencher) { real_forward(  64, bencher); }
#[bench] fn real_forward_0256(bencher: &mut Bencher) { real_forward( 256, bencher); }
#[bench] fn real_forward_1024(bencher: &mut Bencher) { real_forward(1024, bencher); }
#[bench] fn real_forward_4096(bencher: &mut Bencher) { real_forward(4096, bencher); }

fn complex_forward(size: usize, bencher: &mut Bencher) {
    let mut data = vec![c64::new(42.0, 69.0); size];
    bencher.iter(|| black_box(dft::complex::forward(&mut data)));
}

fn real_forward(size: usize, bencher: &mut Bencher) {
    let mut data = vec![42.0; 2 * size];
    bencher.iter(|| black_box(dft::real::forward(&mut data)));
}
<|endoftext|>


<commit_before>use crate::keys::Key;
use crate::errors::{Result, ErrorKind};

extern crate pem;
extern crate simple_asn1;

use simple_asn1::{OID, BigUint};

/// The return type of a successful PEM encoded key with `decode_pem`
///
/// This struct gives a way to parse a string to a key for use in jsonwebtoken.
/// A struct is necessary as it provides the lifetime of the key
///
/// PEM public private keys are encoded PKCS#1 or PKCS#8
/// You will find that with PKCS#8 RSA keys that the PKCS#1 content
/// is embedded inside. This is what is provided to ring via `Key::Der`
/// For EC keys, they are always PKCS#8 on the outside but like RSA keys
/// EC keys contain a section within that ultimately has the configuration
/// that ring uses.
/// Documentation about these formats is at
/// PKCS#1: https://tools.ietf.org/html/rfc8017
/// PKCS#8: https://tools.ietf.org/html/rfc5958
pub struct PemEncodedKey {
  content: Vec<u8>,
  asn1: Vec<simple_asn1::ASN1Block>,
  pem_type: PemType,
  encoded_with: PemEncodedWith,
}

impl PemEncodedKey {
  /// Read the PEM file for later key use
  pub fn read(input: &str) -> Result<PemEncodedKey> {
    match pem::parse(input) {
      Ok(content) => {
        let pem_contents = content.contents;
        let asn1_content = match simple_asn1::from_der(pem_contents.as_slice()) {
          Ok(asn1) => asn1,
          Err(_) => return Err(ErrorKind::InvalidKeyFormat)?,
        };

        match content.tag.as_ref() {
          // This handles a PKCS#1 RSA Private key
          "RSA PRIVATE KEY" => Ok(PemEncodedKey {
            content: pem_contents,
            asn1: asn1_content,
            pem_type: PemType::RSAPrivateKey,
            encoded_with: PemEncodedWith::PKCS1,
          }),
          "RSA PUBLIC KEY" => Ok(PemEncodedKey {
            content: pem_contents,
            asn1: asn1_content,
            pem_type: PemType::RSAPublicKey,
            encoded_with: PemEncodedWith::PKCS1,
          }),

          // No "EC PRIVATE KEY"
          // https://security.stackexchange.com/questions/84327/converting-ecc-private-key-to-pkcs1-format
          // "there is no such thing as a "PKCS#1 format" for elliptic curve (EC) keys"

          // This handles PKCS#8 private keys
          "PRIVATE KEY" => {
            match classify_pem(&asn1_content) {
              Option::Some(Classification::EC) => Ok(PemEncodedKey {
                content: pem_contents,
                asn1: asn1_content,
                pem_type: PemType::ECPrivateKey,
                encoded_with: PemEncodedWith::PKCS8,
              }),
              Option::Some(Classification::RSA) => Ok(PemEncodedKey {
                content: pem_contents,
                asn1: asn1_content,
                pem_type: PemType::RSAPrivateKey,
                encoded_with: PemEncodedWith::PKCS8,
              }),
              _ => return Err(ErrorKind::InvalidKeyFormat)?,
            }
          }

          // This handles PKCS#8 public keys
          "PUBLIC KEY" => {
            match classify_pem(&asn1_content) {
              Option::Some(Classification::EC) => Ok(PemEncodedKey {
                content: pem_contents,
                asn1: asn1_content,
                pem_type: PemType::ECPublicKey,
                encoded_with: PemEncodedWith::PKCS8,
              }),
              Option::Some(Classification::RSA) => Ok(PemEncodedKey {
                content: pem_contents,
                asn1: asn1_content,
                pem_type: PemType::RSAPublicKey,
                encoded_with: PemEncodedWith::PKCS8,
              }),
              _ => return Err(ErrorKind::InvalidKeyFormat)?,
            }
          }

          // Unknown type
          _ => return Err(ErrorKind::InvalidKeyFormat)?,
        }
      },
      Err(_) => return Err(ErrorKind::InvalidKeyFormat)?,
    }
  }

  /// This will do the initial parsing of a PEM file.
  /// Supported tagged pems include "RSA PRIVATE KEY", "RSA PUBLIC KEY",
  /// "PRIVATE KEY", "PUBLIC KEY"
  /// PEMs with multiple tagged portions are not supported
  pub fn as_key(&self) -> Result<Key<'_>> {
    match self.encoded_with {
      PemEncodedWith::PKCS1 => Ok(Key::Der(self.content.as_slice())),
      PemEncodedWith::PKCS8 => {
        match self.pem_type {
          PemType::RSAPrivateKey => Ok(Key::Der(extract_first_bitstring(&self.asn1)?)),
          PemType::RSAPublicKey => Ok(Key::Der(extract_first_bitstring(&self.asn1)?)),
          PemType::ECPrivateKey => Ok(Key::Pkcs8(self.content.as_slice())),
          PemType::ECPublicKey => Ok(Key::Pkcs8(extract_first_bitstring(&self.asn1)?)),
        }
      },
    }
  }
}

#[derive(Debug)]
#[derive(PartialEq)]
/// Supported PEM files for EC and RSA Public and Private Keys
enum PemType {
  ECPublicKey,
  ECPrivateKey,
  RSAPublicKey,
  RSAPrivateKey,
}

#[derive(Debug)]
#[derive(PartialEq)]
enum PemEncodedWith {
  PKCS1,
  PKCS8,
}

#[derive(Debug)]
#[derive(PartialEq)]
enum Classification {
  EC,
  RSA,
}

// This really just finds and returns the first bitstring or octet string
// Which is the x coordinate for EC public keys
// And the DER contents of an RSA key
// Though PKCS#11 keys shouldn't have anything else.
// It will get confusing with certificates.
fn extract_first_bitstring(asn1: &Vec<simple_asn1::ASN1Block>) -> Result<&[u8]> {
  for asn1_entry in asn1.iter() {
    match asn1_entry {
      simple_asn1::ASN1Block::Sequence(_, entries) => {
        if let Ok(result) = extract_first_bitstring(entries) {
          return Ok(result);
        }
      }
      simple_asn1::ASN1Block::BitString(_, _, value) => {
        return Ok(value.as_ref());
      }
      simple_asn1::ASN1Block::OctetString(_, value) => {
        return Ok(value.as_ref());
      }
      _ => ()
    }
  }
  return Err(ErrorKind::InvalidEcdsaKey)?
}

fn classify_pem(asn1: &Vec<simple_asn1::ASN1Block>) -> Option<Classification> {
  // These should be constant but the macro requires
  // #![feature(const_vec_new)]
  let ec_public_key_oid = simple_asn1::oid!(1,2,840,10045,2,1);
  let rsa_public_key_oid = simple_asn1::oid!(1,2,840,113549,1,1,1);

  for asn1_entry in asn1.iter() {
    match asn1_entry {
      simple_asn1::ASN1Block::Sequence(_, entries) => {
        if let Some(classification) = classify_pem(entries) {
          return Some(classification);
        }
      }
      simple_asn1::ASN1Block::ObjectIdentifier(_, oid) => {
        if oid == ec_public_key_oid {
          return Option::Some(Classification::EC);
        } else if oid == rsa_public_key_oid {
          return Option::Some(Classification::RSA);
        }
      }
      _ => {}
    }
  }
  return Option::default();
}<commit_msg>Fix Option handling<commit_after>use crate::keys::Key;
use crate::errors::{Result, ErrorKind};

extern crate pem;
extern crate simple_asn1;

use simple_asn1::{OID, BigUint};

/// Supported PEM files for EC and RSA Public and Private Keys
#[derive(Debug, PartialEq)]
enum PemType {
  ECPublicKey,
  ECPrivateKey,
  RSAPublicKey,
  RSAPrivateKey,
}

#[derive(Debug, PartialEq)]
enum PemEncodedWith {
  PKCS1,
  PKCS8,
}

#[derive(Debug, PartialEq)]
enum Classification {
  EC,
  RSA,
}

/// The return type of a successful PEM encoded key with `decode_pem`
///
/// This struct gives a way to parse a string to a key for use in jsonwebtoken.
/// A struct is necessary as it provides the lifetime of the key
///
/// PEM public private keys are encoded PKCS#1 or PKCS#8
/// You will find that with PKCS#8 RSA keys that the PKCS#1 content
/// is embedded inside. This is what is provided to ring via `Key::Der`
/// For EC keys, they are always PKCS#8 on the outside but like RSA keys
/// EC keys contain a section within that ultimately has the configuration
/// that ring uses.
/// Documentation about these formats is at
/// PKCS#1: https://tools.ietf.org/html/rfc8017
/// PKCS#8: https://tools.ietf.org/html/rfc5958
pub struct PemEncodedKey {
  content: Vec<u8>,
  asn1: Vec<simple_asn1::ASN1Block>,
  pem_type: PemType,
  encoded_with: PemEncodedWith,
}

impl PemEncodedKey {
  /// Read the PEM file for later key use
  pub fn read(input: &str) -> Result<PemEncodedKey> {
    match pem::parse(input) {
      Ok(content) => {
        let pem_contents = content.contents;
        let asn1_content = match simple_asn1::from_der(pem_contents.as_slice()) {
          Ok(asn1) => asn1,
          Err(_) => return Err(ErrorKind::InvalidKeyFormat)?,
        };

        match content.tag.as_ref() {
          // This handles a PKCS#1 RSA Private key
          "RSA PRIVATE KEY" => Ok(PemEncodedKey {
            content: pem_contents,
            asn1: asn1_content,
            pem_type: PemType::RSAPrivateKey,
            encoded_with: PemEncodedWith::PKCS1,
          }),
          "RSA PUBLIC KEY" => Ok(PemEncodedKey {
            content: pem_contents,
            asn1: asn1_content,
            pem_type: PemType::RSAPublicKey,
            encoded_with: PemEncodedWith::PKCS1,
          }),

          // No "EC PRIVATE KEY"
          // https://security.stackexchange.com/questions/84327/converting-ecc-private-key-to-pkcs1-format
          // "there is no such thing as a "PKCS#1 format" for elliptic curve (EC) keys"

          // This handles PKCS#8 private keys
          "PRIVATE KEY" => {
            match classify_pem(&asn1_content) {
              Some(Classification::EC) => Ok(PemEncodedKey {
                content: pem_contents,
                asn1: asn1_content,
                pem_type: PemType::ECPrivateKey,
                encoded_with: PemEncodedWith::PKCS8,
              }),
              Some(Classification::RSA) => Ok(PemEncodedKey {
                content: pem_contents,
                asn1: asn1_content,
                pem_type: PemType::RSAPrivateKey,
                encoded_with: PemEncodedWith::PKCS8,
              }),
              _ => return Err(ErrorKind::InvalidKeyFormat)?,
            }
          }

          // This handles PKCS#8 public keys
          "PUBLIC KEY" => {
            match classify_pem(&asn1_content) {
              Some(Classification::EC) => Ok(PemEncodedKey {
                content: pem_contents,
                asn1: asn1_content,
                pem_type: PemType::ECPublicKey,
                encoded_with: PemEncodedWith::PKCS8,
              }),
              Some(Classification::RSA) => Ok(PemEncodedKey {
                content: pem_contents,
                asn1: asn1_content,
                pem_type: PemType::RSAPublicKey,
                encoded_with: PemEncodedWith::PKCS8,
              }),
              _ => return Err(ErrorKind::InvalidKeyFormat)?,
            }
          }

          // Unknown type
          _ => return Err(ErrorKind::InvalidKeyFormat)?,
        }
      },
      Err(_) => return Err(ErrorKind::InvalidKeyFormat)?,
    }
  }

  /// This will do the initial parsing of a PEM file.
  /// Supported tagged pems include "RSA PRIVATE KEY", "RSA PUBLIC KEY",
  /// "PRIVATE KEY", "PUBLIC KEY"
  /// PEMs with multiple tagged portions are not supported
  pub fn as_key(&self) -> Result<Key<'_>> {
    match self.encoded_with {
      PemEncodedWith::PKCS1 => Ok(Key::Der(self.content.as_slice())),
      PemEncodedWith::PKCS8 => {
        match self.pem_type {
          PemType::RSAPrivateKey => Ok(Key::Der(extract_first_bitstring(&self.asn1)?)),
          PemType::RSAPublicKey => Ok(Key::Der(extract_first_bitstring(&self.asn1)?)),
          PemType::ECPrivateKey => Ok(Key::Pkcs8(self.content.as_slice())),
          PemType::ECPublicKey => Ok(Key::Pkcs8(extract_first_bitstring(&self.asn1)?)),
        }
      },
    }
  }
}

// This really just finds and returns the first bitstring or octet string
// Which is the x coordinate for EC public keys
// And the DER contents of an RSA key
// Though PKCS#11 keys shouldn't have anything else.
// It will get confusing with certificates.
fn extract_first_bitstring(asn1: &Vec<simple_asn1::ASN1Block>) -> Result<&[u8]> {
  for asn1_entry in asn1.iter() {
    match asn1_entry {
      simple_asn1::ASN1Block::Sequence(_, entries) => {
        if let Ok(result) = extract_first_bitstring(entries) {
          return Ok(result);
        }
      }
      simple_asn1::ASN1Block::BitString(_, _, value) => {
        return Ok(value.as_ref());
      }
      simple_asn1::ASN1Block::OctetString(_, value) => {
        return Ok(value.as_ref());
      }
      _ => ()
    }
  }
  return Err(ErrorKind::InvalidEcdsaKey)?
}

fn classify_pem(asn1: &Vec<simple_asn1::ASN1Block>) -> Option<Classification> {
  // These should be constant but the macro requires
  // #![feature(const_vec_new)]
  let ec_public_key_oid = simple_asn1::oid!(1,2,840,10045,2,1);
  let rsa_public_key_oid = simple_asn1::oid!(1,2,840,113549,1,1,1);

  for asn1_entry in asn1.iter() {
    match asn1_entry {
      simple_asn1::ASN1Block::Sequence(_, entries) => {
        if let Some(classification) = classify_pem(entries) {
          return Some(classification);
        }
      }
      simple_asn1::ASN1Block::ObjectIdentifier(_, oid) => {
        if oid == ec_public_key_oid {
          return Some(Classification::EC);
        } else if oid == rsa_public_key_oid {
          return Some(Classification::RSA);
        }
      }
      _ => {}
    }
  }
    None
}
<|endoftext|>


<commit_before>
use std::marker::PhantomData;

use Construct;
use Count;
use Data;
use ToPos;
use ToIndex;

/// Dimension is natural number, position is a list of numbers.
pub struct Permutation<T>(PhantomData<T>);

impl<T> Construct for Permutation<T> {
    fn new() -> Permutation<T> {
        Permutation(PhantomData)
    }
}

impl Count<usize> for Permutation<Data> {
    fn count(&self, dim: usize) -> usize {
        let mut res = 1;
        for x in 1..dim + 1 {
            res *= x;
        }
        res
    }
}

impl<'a> ToIndex<usize, &'a [usize]> for Permutation<Data> {
    fn to_index(&self, dim: usize, pos: &'a [usize]) -> usize {
        let mut index = 0;
        let mut count = 1;
        for (i, &x) in pos.iter().enumerate().rev() {
            let lower = pos[..i].iter().filter(|&&y| y < x).count();
            index += count * (x - lower);
            count *= dim - i;
        }
        index
    }
}

impl<'a> ToPos<usize, &'a mut Vec<usize>> for Permutation<Data> {
    fn to_pos(&self, dim: usize, mut index: usize, pos: &'a mut Vec<usize>) {
        unsafe { pos.set_len(0); }

        let mut count = 1;
        for (j, x) in (1..dim + 1).enumerate() {
            count *= x;
            pos.push(j);
        }

        for i in 0..dim {
            let block = count / (dim - i);
            let ind = index / block;
            let item = pos.remove(ind);
            pos.push(item);
            count /= dim - i;
            index -= ind * block;
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use Construct;
    use Data;
    use Count;
    use ToPos;
    use ToIndex;

    #[test]
    fn test() {
        let permutation: Permutation<Data> = Construct::new();
        assert_eq!(permutation.count(1), 1);
        assert_eq!(permutation.count(2), 2);
        assert_eq!(permutation.count(3), 6);
        assert_eq!(permutation.count(4), 24);

        let mut pos = Vec::new();
        let dim = 4;
        let count = permutation.count(dim);
        for i in 0..count {
            permutation.to_pos(dim, i, &mut pos);
            let index = permutation.to_index(dim, &pos);
            assert_eq!(index, i);
        }
    }
}
<commit_msg>Added `Count` and `ToIndex` for `Permutation<Of<T>>`<commit_after>
use std::marker::PhantomData;

use Construct;
use Count;
use Data;
use ToPos;
use ToIndex;
use Of;

/// Dimension is natural number, position is a list of numbers.
pub struct Permutation<T>(PhantomData<T>);

impl<T> Construct for Permutation<T> {
    fn new() -> Permutation<T> {
        Permutation(PhantomData)
    }
}

impl Count<usize> for Permutation<Data> {
    fn count(&self, dim: usize) -> usize {
        let mut res = 1;
        for x in 1..dim + 1 {
            res *= x;
        }
        res
    }
}

impl<T, U> Count<U> for Permutation<Of<T>>
    where
        T: Construct + Count<U>
{
    fn count(&self, dim: U) -> usize {
        let of: T = Construct::new();
        let mut res = 1;
        for x in 1..of.count(dim) + 1 {
            res *= x;
        }
        res
    }
}

impl<'a> ToIndex<usize, &'a [usize]> for Permutation<Data> {
    fn to_index(&self, dim: usize, pos: &'a [usize]) -> usize {
        let mut index = 0;
        let mut count = 1;
        for (i, &x) in pos.iter().enumerate().rev() {
            let lower = pos[..i].iter().filter(|&&y| y < x).count();
            index += count * (x - lower);
            count *= dim - i;
        }
        index
    }
}

impl<'a, T, U: Copy, V: Copy> ToIndex<U, &'a [V]> for Permutation<Of<T>>
    where
        T: Construct + ToIndex<U, V> + Count<U>
{
    fn to_index(&self, dim: U, pos: &'a [V]) -> usize {
        let of: T = Construct::new();
        let mut index = 0;
        let dim_count = of.count(dim);
        let mut count = 1;
        for (i, x) in pos.iter()
            .map(|&x| of.to_index(dim, x))
            .enumerate().rev() {
            let lower = pos[..i].iter()
                .map(|&y| of.to_index(dim, y))
                .filter(|&y| y < x).count();
            index += count * (x - lower);
            count *= dim_count - i;
        }
        index
    }
}

impl<'a> ToPos<usize, &'a mut Vec<usize>> for Permutation<Data> {
    fn to_pos(&self, dim: usize, mut index: usize, pos: &'a mut Vec<usize>) {
        unsafe { pos.set_len(0); }

        let mut count = 1;
        for (j, x) in (1..dim + 1).enumerate() {
            count *= x;
            pos.push(j);
        }

        for i in 0..dim {
            let block = count / (dim - i);
            let ind = index / block;
            let item = pos.remove(ind);
            pos.push(item);
            count /= dim - i;
            index -= ind * block;
        }
    }
}

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

    #[test]
    fn data() {
        let permutation: Permutation<Data> = Construct::new();
        assert_eq!(permutation.count(1), 1);
        assert_eq!(permutation.count(2), 2);
        assert_eq!(permutation.count(3), 6);
        assert_eq!(permutation.count(4), 24);

        let mut pos = Vec::new();
        let dim = 4;
        let count = permutation.count(dim);
        for i in 0..count {
            permutation.to_pos(dim, i, &mut pos);
            let index = permutation.to_index(dim, &pos);
            assert_eq!(index, i);
        }
    }

    #[test]
    fn of() {
        let space: Permutation<Of<Pair<Data>>> = Construct::new();
        let dim = 3;
        let count = space.count(dim);
        println!("{:?}", count);
        println!("{:?}", space.to_index(dim, &[(0, 1), (0, 2), (1, 2)]));
        println!("{:?}", space.to_index(dim, &[(0, 1), (1, 2), (0, 2)]));
        println!("{:?}", space.to_index(dim, &[(0, 2), (0, 1), (1, 2)]));
        println!("{:?}", space.to_index(dim, &[(0, 2), (1, 2), (0, 1)]));
        assert!(false);
    }
}
<|endoftext|>