<commit_before>//! Test metadata fetch, group membership, consumer metadata.
extern crate env_logger;
extern crate futures;
extern crate rand;
extern crate rdkafka;

use futures::*;

use rdkafka::consumer::{Consumer, StreamConsumer};
use rdkafka::topic_partition_list::TopicPartitionList;
use rdkafka::config::ClientConfig;

use std::time::Duration;

mod utils;
use crate::utils::*;

fn create_consumer(group_id: &str) -> StreamConsumer {
    ClientConfig::new()
        .set("group.id", group_id)
        .set("enable.partition.eof", "true")
        .set("client.id", "rdkafka_integration_test_client")
        .set("bootstrap.servers", get_bootstrap_server().as_str())
        .set("session.timeout.ms", "6000")
        .set("api.version.request", "true")
        .set("debug", "all")
        .create()
        .expect("Failed to create StreamConsumer")
}

#[test]
fn test_metadata() {
    let _r = env_logger::init();

    let topic_name = rand_test_topic();
    populate_topic(&topic_name, 1, &value_fn, &key_fn, Some(0), None);
    populate_topic(&topic_name, 1, &value_fn, &key_fn, Some(1), None);
    populate_topic(&topic_name, 1, &value_fn, &key_fn, Some(2), None);
    let consumer = create_consumer(&rand_test_group());

    let metadata = consumer.fetch_metadata(None, Duration::from_secs(5)).unwrap();
    assert_eq!(metadata.orig_broker_id(), 0);
    assert!(!metadata.orig_broker_name().is_empty());

    let broker_metadata = metadata.brokers();
    assert_eq!(broker_metadata.len(), 1);
    assert_eq!(broker_metadata[0].id(), 0);
    assert!(!broker_metadata[0].host().is_empty());
    assert_eq!(broker_metadata[0].port(), 9092);

    let topic_metadata = metadata.topics().iter()
        .find(|m| m.name() == topic_name).unwrap();

    let mut ids = topic_metadata.partitions().iter()
        .map(|p| {
            assert_eq!(p.error(), None);
            p.id()
        })
        .collect::<Vec<_>>();
    ids.sort();

    assert_eq!(ids, vec![0, 1, 2]);
    assert_eq!(topic_metadata.error(), None);
    assert_eq!(topic_metadata.partitions().len(), 3);
    assert_eq!(topic_metadata.partitions()[0].leader(), 0);
    assert_eq!(topic_metadata.partitions()[1].leader(), 0);
    assert_eq!(topic_metadata.partitions()[2].leader(), 0);
    assert_eq!(topic_metadata.partitions()[0].replicas(), &[0]);
    assert_eq!(topic_metadata.partitions()[0].isr(), &[0]);

    let metadata_one_topic = consumer.fetch_metadata(Some(&topic_name), Duration::from_secs(5))
        .unwrap();
    assert_eq!(metadata_one_topic.topics().len(), 1);
}

#[test]
fn test_subscription() {
    let _r = env_logger::init();

    let topic_name = rand_test_topic();
    populate_topic(&topic_name, 10, &value_fn, &key_fn, None, None);
    let consumer = create_consumer(&rand_test_group());
    consumer.subscribe(&[topic_name.as_str()]).unwrap();

    let _consumer_future = consumer.start().take(10).wait();

    let mut tpl = TopicPartitionList::new();
    tpl.add_topic_unassigned(&topic_name);
    assert_eq!(tpl, consumer.subscription().unwrap());
}

#[test]
fn test_group_membership() {
    let _r = env_logger::init();

    let topic_name = rand_test_topic();
    let group_name = rand_test_group();
    populate_topic(&topic_name, 1, &value_fn, &key_fn, Some(0), None);
    populate_topic(&topic_name, 1, &value_fn, &key_fn, Some(1), None);
    populate_topic(&topic_name, 1, &value_fn, &key_fn, Some(2), None);
    let consumer = create_consumer(&group_name);
    consumer.subscribe(&[topic_name.as_str()]).unwrap();

    // Make sure the consumer joins the group
    let _consumer_future = consumer.start()
        .take(1)
        .for_each(|_| Ok(()))
        .wait();

    let group_list = consumer.fetch_group_list(None, Duration::from_secs(5)).unwrap();

    // Print all the data, valgrind will check memory access
    for group in group_list.groups().iter() {
        println!("{} {} {} {}", group.name(), group.state(), group.protocol(), group.protocol_type());
        for member in group.members() {
            println!("  {} {} {}", member.id(), member.client_id(), member.client_host());
        }
    }

    let group_list2 = consumer.fetch_group_list(Some(&group_name), Duration::from_secs(5))
        .unwrap();
    assert_eq!(group_list2.groups().len(), 1);

    let consumer_group = group_list2.groups().iter().find(|&g| g.name() == group_name).unwrap();
    assert_eq!(consumer_group.members().len(), 1);

    let consumer_member = &consumer_group.members()[0];
    assert_eq!(consumer_member.client_id(), "rdkafka_integration_test_client");
}
<commit_msg>Allow -1 as orig_broker_id<commit_after>//! Test metadata fetch, group membership, consumer metadata.
extern crate env_logger;
extern crate futures;
extern crate rand;
extern crate rdkafka;

use futures::*;

use rdkafka::consumer::{Consumer, StreamConsumer};
use rdkafka::topic_partition_list::TopicPartitionList;
use rdkafka::config::ClientConfig;

use std::time::Duration;

mod utils;
use crate::utils::*;

fn create_consumer(group_id: &str) -> StreamConsumer {
    ClientConfig::new()
        .set("group.id", group_id)
        .set("enable.partition.eof", "true")
        .set("client.id", "rdkafka_integration_test_client")
        .set("bootstrap.servers", get_bootstrap_server().as_str())
        .set("session.timeout.ms", "6000")
        .set("api.version.request", "true")
        .set("debug", "all")
        .create()
        .expect("Failed to create StreamConsumer")
}

#[test]
fn test_metadata() {
    let _r = env_logger::init();

    let topic_name = rand_test_topic();
    populate_topic(&topic_name, 1, &value_fn, &key_fn, Some(0), None);
    populate_topic(&topic_name, 1, &value_fn, &key_fn, Some(1), None);
    populate_topic(&topic_name, 1, &value_fn, &key_fn, Some(2), None);
    let consumer = create_consumer(&rand_test_group());

    let metadata = consumer.fetch_metadata(None, Duration::from_secs(5)).unwrap();
    let orig_broker_id = metadata.orig_broker_id();
    // The orig_broker_id may be -1 if librdkafka's bootstrap "broker" handles
    // the request.
    if orig_broker_id != -1 && orig_broker_id != 0 {
        panic!("metadata.orig_broker_id = {}, not 0 or 1 as expected", orig_broker_id)
    }
    assert!(!metadata.orig_broker_name().is_empty());

    let broker_metadata = metadata.brokers();
    assert_eq!(broker_metadata.len(), 1);
    assert_eq!(broker_metadata[0].id(), 0);
    assert!(!broker_metadata[0].host().is_empty());
    assert_eq!(broker_metadata[0].port(), 9092);

    let topic_metadata = metadata.topics().iter()
        .find(|m| m.name() == topic_name).unwrap();

    let mut ids = topic_metadata.partitions().iter()
        .map(|p| {
            assert_eq!(p.error(), None);
            p.id()
        })
        .collect::<Vec<_>>();
    ids.sort();

    assert_eq!(ids, vec![0, 1, 2]);
    assert_eq!(topic_metadata.error(), None);
    assert_eq!(topic_metadata.partitions().len(), 3);
    assert_eq!(topic_metadata.partitions()[0].leader(), 0);
    assert_eq!(topic_metadata.partitions()[1].leader(), 0);
    assert_eq!(topic_metadata.partitions()[2].leader(), 0);
    assert_eq!(topic_metadata.partitions()[0].replicas(), &[0]);
    assert_eq!(topic_metadata.partitions()[0].isr(), &[0]);

    let metadata_one_topic = consumer.fetch_metadata(Some(&topic_name), Duration::from_secs(5))
        .unwrap();
    assert_eq!(metadata_one_topic.topics().len(), 1);
}

#[test]
fn test_subscription() {
    let _r = env_logger::init();

    let topic_name = rand_test_topic();
    populate_topic(&topic_name, 10, &value_fn, &key_fn, None, None);
    let consumer = create_consumer(&rand_test_group());
    consumer.subscribe(&[topic_name.as_str()]).unwrap();

    let _consumer_future = consumer.start().take(10).wait();

    let mut tpl = TopicPartitionList::new();
    tpl.add_topic_unassigned(&topic_name);
    assert_eq!(tpl, consumer.subscription().unwrap());
}

#[test]
fn test_group_membership() {
    let _r = env_logger::init();

    let topic_name = rand_test_topic();
    let group_name = rand_test_group();
    populate_topic(&topic_name, 1, &value_fn, &key_fn, Some(0), None);
    populate_topic(&topic_name, 1, &value_fn, &key_fn, Some(1), None);
    populate_topic(&topic_name, 1, &value_fn, &key_fn, Some(2), None);
    let consumer = create_consumer(&group_name);
    consumer.subscribe(&[topic_name.as_str()]).unwrap();

    // Make sure the consumer joins the group
    let _consumer_future = consumer.start()
        .take(1)
        .for_each(|_| Ok(()))
        .wait();

    let group_list = consumer.fetch_group_list(None, Duration::from_secs(5)).unwrap();

    // Print all the data, valgrind will check memory access
    for group in group_list.groups().iter() {
        println!("{} {} {} {}", group.name(), group.state(), group.protocol(), group.protocol_type());
        for member in group.members() {
            println!("  {} {} {}", member.id(), member.client_id(), member.client_host());
        }
    }

    let group_list2 = consumer.fetch_group_list(Some(&group_name), Duration::from_secs(5))
        .unwrap();
    assert_eq!(group_list2.groups().len(), 1);

    let consumer_group = group_list2.groups().iter().find(|&g| g.name() == group_name).unwrap();
    assert_eq!(consumer_group.members().len(), 1);

    let consumer_member = &consumer_group.members()[0];
    assert_eq!(consumer_member.client_id(), "rdkafka_integration_test_client");
}
<|endoftext|>


<commit_before>extern crate gcc;

use std::process::{Command, Stdio};
use std::env;

fn main() {
    // 1. Build the object file from source using node-gyp.
    build_object_file();

    // 2. Link the library from the object file using gcc.
    link_library();
}

fn build_object_file() {
    let npm_command = if cfg!(unix) { "npm" } else { "npm.cmd" };
    let node_gyp_command = if cfg!(unix) { "node-gyp" } else { "node-gyp.cmd" };

    // Ensure that all package.json dependencies and dev dependencies are installed.
    Command::new(npm_command).args(&["install", "--silent"]).status().ok().expect("Failed to run \"npm install\" for neon-sys!");

    // Run `node-gyp configure` (appending -d in debug mode).
    let configure_args = if debug() { vec!["configure", "-d", "--arch=ia32"] } else { vec!["configure", "--arch=ia32"] };
    let output = Command::new(node_gyp_command)
        .args(&configure_args)
        .output()
        .expect("Failed to run \"node-gyp configure\" for neon-sys!");

    if cfg!(windows) {
        let node_gyp_output = String::from_utf8_lossy(&output.stderr);
        let node_root_dir_flag_pattern = "'-Dnode_root_dir=";
        let node_root_dir_start_index = node_gyp_output
            .find(node_root_dir_flag_pattern)
            .map(|i| i + node_root_dir_flag_pattern.len())
            .expect("Couldn't find node_root_dir in node-gyp output.");
        let node_root_dir_end_index = node_gyp_output[node_root_dir_start_index..].find("'").unwrap() + node_root_dir_start_index;
        println!("cargo:node_root_dir={}", &node_gyp_output[node_root_dir_start_index..node_root_dir_end_index]);
    }

    // Run `node-gyp build` (appending -d in debug mode).
    let build_args = if debug() { vec!["build", "-d"] } else { vec!["build"] };
    Command::new(node_gyp_command)
        .stderr(Stdio::null()) // Prevent cargo build from hanging on Windows.
        .args(&build_args)
        .status()
        .ok()
        .expect("Failed to run \"node-gyp build\" for neon-sys!");
}

// Link the built object file into a static library.
fn link_library() {
    let configuration = if debug() { "Debug" } else { "Release" };
    let object_path = if cfg!(unix) {
        format!("build/{}/obj.target/neon/src/neon.o", configuration)
    } else {
        format!("build\\{}\\obj\\neon\\neon.obj", configuration)
    };

    gcc::Config::new().object(object_path).compile("libneon.a");
}

fn debug() -> bool {
    match env::var("DEBUG") {
        Ok(s) => s == "true",
        Err(_) => false
    }
}
<commit_msg>Base node-gyp --arch flag on Cargo target architecture<commit_after>extern crate gcc;

use std::process::{Command, Stdio};
use std::env;

fn main() {
    // 1. Build the object file from source using node-gyp.
    build_object_file();

    // 2. Link the library from the object file using gcc.
    link_library();
}

fn build_object_file() {
    let npm_command = if cfg!(unix) { "npm" } else { "npm.cmd" };
    let node_gyp_command = if cfg!(unix) { "node-gyp" } else { "node-gyp.cmd" };

    // Ensure that all package.json dependencies and dev dependencies are installed.
    Command::new(npm_command).args(&["install", "--silent"]).status().ok().expect("Failed to run \"npm install\" for neon-sys!");

    // Run `node-gyp configure` with correct debug and architecture flags
    let mut configure_args = vec!["configure"];
    if debug() {
        configure_args.push("--debug")
    }
    let target = env::var("TARGET").unwrap();
    if target.contains("i686") || target.contains("i586") {
        configure_args.push("--arch=ia32");
    } else if target.contains("x86_64") {
        configure_args.push("--arch=x64");
    }

    let output = Command::new(node_gyp_command)
        .args(&configure_args)
        .output()
        .expect("Failed to run \"node-gyp configure\" for neon-sys!");

    if cfg!(windows) {
        let node_gyp_output = String::from_utf8_lossy(&output.stderr);
        let node_root_dir_flag_pattern = "'-Dnode_root_dir=";
        let node_root_dir_start_index = node_gyp_output
            .find(node_root_dir_flag_pattern)
            .map(|i| i + node_root_dir_flag_pattern.len())
            .expect("Couldn't find node_root_dir in node-gyp output.");
        let node_root_dir_end_index = node_gyp_output[node_root_dir_start_index..].find("'").unwrap() + node_root_dir_start_index;
        println!("cargo:node_root_dir={}", &node_gyp_output[node_root_dir_start_index..node_root_dir_end_index]);
    }

    // Run `node-gyp build` (appending -d in debug mode).
    let build_args = if debug() { vec!["build", "-d"] } else { vec!["build"] };
    Command::new(node_gyp_command)
        .stderr(Stdio::null()) // Prevent cargo build from hanging on Windows.
        .args(&build_args)
        .status()
        .ok()
        .expect("Failed to run \"node-gyp build\" for neon-sys!");
}

// Link the built object file into a static library.
fn link_library() {
    let configuration = if debug() { "Debug" } else { "Release" };
    let object_path = if cfg!(unix) {
        format!("build/{}/obj.target/neon/src/neon.o", configuration)
    } else {
        format!("build\\{}\\obj\\neon\\neon.obj", configuration)
    };

    gcc::Config::new().object(object_path).compile("libneon.a");
}

fn debug() -> bool {
    match env::var("DEBUG") {
        Ok(s) => s == "true",
        Err(_) => false
    }
}
<|endoftext|>


<commit_before>extern crate find_folder;

use screen::*;
use piston_window;
use conrod;
use conrod::frame::Frameable;
use conrod::color::Colorable;
use conrod::position::Positionable;

pub struct MainMenuScreen;

impl MainMenuScreen {
    pub fn new() -> MainMenuScreen {
        MainMenuScreen
    }
}

impl Screen for MainMenuScreen {
    fn on_input(&mut self, input: &piston_window::Input, window: &piston_window::PistonWindow) -> InputResults {
        use piston_window::{Input, Button, MouseButton};

        let mut result = Vec::new();

        match input {
            &Input::Press(Button::Mouse(MouseButton::Left)) => {
                result.push(InputResult::PopScreen);
                result.push(InputResult::PushScreen(Box::new(BattleScreen::new(&window))));
            }
            _ => {}
        }

        result
    }

    fn on_draw(&mut self, args: &piston_window::RenderArgs, window: &piston_window::PistonWindow) {
        window.draw_2d(|context, graphics| {
            piston_window::clear([0., 0., 1., 1.0], graphics);

////////////////////////////////////////////////////////////////////////////////////
        // TODO: Move Ui to some context?
        // piston_window::Glyphs
        // type Ui = conrod::Ui<Glyphs>;
        let mut ui = {
            let assets = find_folder::Search::KidsThenParents(3, 5).for_folder("assets").unwrap();
            let font_path = assets.join("fonts/NotoSans/NotoSans-Regular.ttf");
            let theme = conrod::Theme::default();
            let glyph_cache = piston_window::Glyphs::new(&font_path, window.factory.borrow().clone());
            conrod::Ui::new(glyph_cache.unwrap(), theme)
        };

        conrod::Canvas::new()
            .frame(200.)
            .pad(30.0)
            .color(conrod::color::rgb(0.2, 0.35, 0.45))
            .scroll_kids()
            .set(CANVAS, &mut ui);

        conrod::Text::new("Widget Demonstration")
            .top_left_with_margins_on(CANVAS, 0.0, 350.0)
            .font_size(32)
            .color(conrod::color::rgb(0.2, 0.35, 0.45).plain_contrast())
            .set(TITLE, &mut ui);
////////////////////////////////////////////////////////////////////////////////////
        });
    }

    fn on_update(&mut self, args: &piston_window::UpdateArgs) {}
}

widget_ids! {
    CANVAS,
    TITLE,
}
<commit_msg>Build fix<commit_after>extern crate find_folder;

use screen::*;
use piston_window;
use conrod;
use conrod::Widget;
use conrod::Frameable;
use conrod::color::Colorable;
use conrod::Positionable;

pub struct MainMenuScreen;

impl MainMenuScreen {
    pub fn new() -> MainMenuScreen {
        MainMenuScreen
    }
}

impl Screen for MainMenuScreen {
    fn on_input(&mut self, input: &piston_window::Input, window: &piston_window::PistonWindow) -> InputResults {
        use piston_window::{Input, Button, MouseButton};

        let mut result = Vec::new();

        match input {
            &Input::Press(Button::Mouse(MouseButton::Left)) => {
                result.push(InputResult::PopScreen);
                result.push(InputResult::PushScreen(Box::new(BattleScreen::new(&window))));
            }
            _ => {}
        }

        result
    }

    fn on_draw(&mut self, args: &piston_window::RenderArgs, window: &piston_window::PistonWindow) {
        window.draw_2d(|context, graphics| {
            piston_window::clear([0., 0., 1., 1.0], graphics);

////////////////////////////////////////////////////////////////////////////////////
        // TODO: Move Ui to some context?
        // piston_window::Glyphs
        // type Ui = conrod::Ui<Glyphs>;
        let mut ui = {
            let assets = find_folder::Search::KidsThenParents(3, 5).for_folder("assets").unwrap();
            let font_path = assets.join("fonts/NotoSans/NotoSans-Regular.ttf");
            let theme = conrod::Theme::default();
            let glyph_cache = piston_window::Glyphs::new(&font_path, window.factory.borrow().clone());
            conrod::Ui::new(glyph_cache.unwrap(), theme)
        };

        conrod::Canvas::new()
            .frame(200.)
            .pad(30.0)
            .color(conrod::color::rgb(0.2, 0.35, 0.45))
            .scroll_kids()
            .set(CANVAS, &mut ui);

        conrod::Text::new("Widget Demonstration")
            .top_left_with_margins_on(CANVAS, 0.0, 350.0)
            .font_size(32)
            .color(conrod::color::rgb(0.2, 0.35, 0.45).plain_contrast())
            .set(TITLE, &mut ui);
////////////////////////////////////////////////////////////////////////////////////
        });
    }

    fn on_update(&mut self, args: &piston_window::UpdateArgs) {}
}

widget_ids! {
    CANVAS,
    TITLE,
}
<|endoftext|>


<commit_before>//! Standard Rust log crate adapter to slog-rs
//!
//! This crate allows setting one of `slog` `Logger`s
//! as a global handler of Rust de facto standard logging statements
//! (eg ``info!(...)``) provided by `log` create.
//!
//! ```
//! #[macro_use]
//! extern crate slog;
//! #[macro_use]
//! extern crate log;
//! extern crate slog_stdlog;
//!
//! use slog::*;
//!
//! fn main() {
//!     let root = Logger::new_root(
//!         o!("build-id" => "8dfljdf"),
//!         slog::drain::discard(),
//!     );
//!     slog_stdlog::set_logger(root).unwrap();
//!     info!("standard logging redirected to slog");
//! }
//! ```
#![warn(missing_docs)]

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

use log::LogMetadata;
use std::sync;

use slog::Level;

// TODO: Change this to use thread local copies
struct Logger(sync::Mutex<slog::Logger>);

impl Logger {
    fn new(logger: slog::Logger) -> Self {
        Logger ( sync::Mutex::new(logger) )
    }
}

fn log_to_slog_level(level: log::LogLevel) -> Level {
    match level {
        log::LogLevel::Trace => Level::Trace,
        log::LogLevel::Debug => Level::Debug,
        log::LogLevel::Info => Level::Info,
        log::LogLevel::Warn => Level::Warning,
        log::LogLevel::Error => Level::Error,
    }
}

impl log::Log for Logger {
    fn enabled(&self, _: &LogMetadata) -> bool {
        true
    }

    fn log(&self, r: &log::LogRecord) {
        let level = log_to_slog_level(r.metadata().level());

        let target = r.target();
        let module = r.location().module_path();
        let file = r.location().file();
        let line = r.location().line();
        let msg = format!("{}", r.args());
        {
            let _ = self.0.lock()
                .map(|l| (*l).log(level,
                               &msg,
                               &[("target", &target),
                                 ("module", &module),
                                 ("file", &file),
                                 ("line", &line)]));
        }
    }
}

/// Set a `slog::Logger` as a global `log` create handler
///
/// This will forward all `log` records to `slog` logger.
pub fn set_logger(logger: slog::Logger) -> Result<(), log::SetLoggerError> {
    log::set_logger(|max_log_level| {
        max_log_level.set(log::LogLevelFilter::max());
        Box::new(Logger::new(logger))
    })
}

/// Set a `slog::Logger` as a global `log` create handler
///
/// This will forward `log` records that satisfy `log_level_filter` to `slog` logger.
pub fn set_logger_level(logger: slog::Logger,
                        log_level_filter: log::LogLevelFilter)
                        -> Result<(), log::SetLoggerError> {
    log::set_logger(|max_log_level| {
        max_log_level.set(log_level_filter);
        Box::new(Logger::new(logger))
    })
}
<commit_msg>Don't allocate/format on every log in stdlog<commit_after>//! Standard Rust log crate adapter to slog-rs
//!
//! This crate allows setting one of `slog` `Logger`s
//! as a global handler of Rust de facto standard logging statements
//! (eg ``info!(...)``) provided by `log` create.
//!
//! ```
//! #[macro_use]
//! extern crate slog;
//! #[macro_use]
//! extern crate log;
//! extern crate slog_stdlog;
//!
//! use slog::*;
//!
//! fn main() {
//!     let root = Logger::new_root(
//!         o!("build-id" => "8dfljdf"),
//!         slog::drain::discard(),
//!     );
//!     slog_stdlog::set_logger(root).unwrap();
//!     info!("standard logging redirected to slog");
//! }
//! ```
#![warn(missing_docs)]

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

use log::LogMetadata;
use std::sync;

use slog::Level;
use slog::logger::RecordInfo;

// TODO: Change this to use thread local copies
struct Logger(sync::Mutex<slog::Logger>);

impl Logger {
    fn new(logger: slog::Logger) -> Self {
        Logger ( sync::Mutex::new(logger) )
    }
}

fn log_to_slog_level(level: log::LogLevel) -> Level {
    match level {
        log::LogLevel::Trace => Level::Trace,
        log::LogLevel::Debug => Level::Debug,
        log::LogLevel::Info => Level::Info,
        log::LogLevel::Warn => Level::Warning,
        log::LogLevel::Error => Level::Error,
    }
}

impl log::Log for Logger {
    fn enabled(&self, _: &LogMetadata) -> bool {
        true
    }

    fn log(&self, r: &log::LogRecord) {
        let level = log_to_slog_level(r.metadata().level());

        let target = r.target();
        let module = r.location().module_path();
        let file = r.location().file();
        let line = r.location().line();
        {
            let _ = self.0.lock()
                .map(|l| (*l).log(level,
                                  &"stdlog",
                                  b!(
                                      "target" => target,
                                      "module" => module,
                                      "file" => file,
                                      "line" => line,
                                      "stdmsg" => |_:&RecordInfo|{format!("{}", r.args())}
                                  )));
        }
    }
}

/// Set a `slog::Logger` as a global `log` create handler
///
/// This will forward all `log` records to `slog` logger.
pub fn set_logger(logger: slog::Logger) -> Result<(), log::SetLoggerError> {
    log::set_logger(|max_log_level| {
        max_log_level.set(log::LogLevelFilter::max());
        Box::new(Logger::new(logger))
    })
}

/// Set a `slog::Logger` as a global `log` create handler
///
/// This will forward `log` records that satisfy `log_level_filter` to `slog` logger.
pub fn set_logger_level(logger: slog::Logger,
                        log_level_filter: log::LogLevelFilter)
                        -> Result<(), log::SetLoggerError> {
    log::set_logger(|max_log_level| {
        max_log_level.set(log_level_filter);
        Box::new(Logger::new(logger))
    })
}
<|endoftext|>


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

#[macro_use]
extern crate lazy_static;
pub fn get_number<P: AsRef<Path>>(filename: P) -> io::Result<u32> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"NUMBER=(\d+)").unwrap();
    }
    let mut matches = match_lines(filename, &*RE)?;
    return Ok(matches.next().unwrap().parse().unwrap());
}

pub fn get_output<'a, P:'a + AsRef<Path>>(filename: P) -> io::Result<impl Iterator<Item = i32> + 'a> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"OUTPUT:(.*)").unwrap();
    }
    let matches = match_lines(filename, &*RE)?;
    let values = matches.map(|s|
        s.split(',').map(|v| v.parse().unwrap()).collect::<Vec<_>>().into_iter()
    ).flatten();
    Ok(values)
}

fn match_lines<'a, P: 'a + AsRef<Path>>(filename: P, regex: &'a Regex) -> io::Result<impl Iterator<Item = String> + 'a> {
    let lines = read_lines(filename)?;
    let matches = lines.filter_map(move |line| {
        regex.captures(&line).map(|captures|
            captures[1].to_string()
        )
    });
    Ok(matches)
}

fn read_lines<P: AsRef<Path>>(filename: P) -> io::Result<impl Iterator<Item = String>> {
    let file = File::open(filename)?;
    return Ok(io::BufReader::new(file).lines().map(|line|
        line.unwrap()
    ));
}

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

    #[test]
    fn test_number() {
        assert_eq!(get_number("../data/test.txt").unwrap() , 3);
    }

    #[test]
    fn test_output() {
        let output = [1,1,2,2,3,4,4,6,7,9,9,20,21];
        assert_eq!(get_output("../data/test.txt").unwrap().collect::<Vec<_>>(), output);
    }
}
<commit_msg>closure for read_lines<commit_after>
use std::fs::File;
use std::io::{self, BufRead};
use std::path::Path;
use regex::Regex;

#[macro_use]
extern crate lazy_static;
pub fn get_number<P: AsRef<Path>>(filename: P) -> io::Result<u32> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"NUMBER=(\d+)").unwrap();
    }
    let mut matches = match_lines(filename, &*RE)?;
    return Ok(matches.next().unwrap().parse().unwrap());
}

pub fn get_output<'a, P:'a + AsRef<Path>>(filename: P) -> io::Result<impl Iterator<Item = i32> + 'a> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"OUTPUT:(.*)").unwrap();
    }
    let matches = match_lines(filename, &*RE)?;
    let values = matches.map(|s|
        s.split(',').map(|v| v.parse().unwrap()).collect::<Vec<_>>().into_iter()
    ).flatten();
    Ok(values)
}

fn match_lines<'a, P: 'a + AsRef<Path>>(filename: P, regex: &'a Regex) -> io::Result<impl Iterator<Item = String> + 'a> {
    let read_lines = move || -> io::Result<_> {
        let file = File::open(filename)?;
        Ok(io::BufReader::new(file).lines().map(|line|
            line.unwrap()))
    };
    let lines = read_lines()?;
    let matches = lines.filter_map(move |line| {
        regex.captures(&line).map(|captures|
            captures[1].to_string()
        )
    });
    Ok(matches)
}

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

    #[test]
    fn test_number() {
        assert_eq!(get_number("../data/test.txt").unwrap() , 3);
    }

    #[test]
    fn test_output() {
        let output = [1,1,2,2,3,4,4,6,7,9,9,20,21];
        assert_eq!(get_output("../data/test.txt").unwrap().collect::<Vec<_>>(), output);
    }
}
<|endoftext|>


<commit_before>// encoding.rs

// import enum variants in misc.rs
use Base16         = misc::Base16;
use Base32         = misc::Base32;
use Base64         = misc::Base64;
use Base32Hex      = misc::Base32Hex;
use Base64Url      = misc::Base64Url;

// import constants in misc/base{16,32,64}.rs
use BASE16         = misc::base16::BASE16;
use BASE32         = misc::base32::BASE32_STD;
use BASE64         = misc::base64::BASE64_STD;
use BASE32_HEX     = misc::base32::BASE32_HEX;
use BASE64_URL     = misc::base64::BASE64_URL;

// import structs in misc/base{16,32,64}.rs
use Base16Writer   = misc::base16::Base16Writer;
use Base32Writer   = misc::base32::Base32Writer;
use Base64Writer   = misc::base64::Base64Writer;
use Base32Reader   = misc::base32::Base32Reader;
use Base64Reader   = misc::base64::Base64Reader;

// export all enum variants in misc.rs
export Base16;
export Base32;
export Base64;
export Base32Hex;
export Base64Url;

// export constants
export BASE16;
export BASE32;
export BASE64;
export BASE32_HEX;
export BASE64_URL;

// export structs
export Base16Writer;
export Base32Writer;
export Base64Writer;
export Base32Reader;
export Base64Reader;

export Convert;
export Encode;
export Decode;
export Codec;

struct Convert<T: Encode Decode> {
    from: T,
    to: T,
}

trait Encode {
    fn encode(buf: &[u8]) -> ~[u8];
}

trait Decode {
    fn decode(buf: &[u8]) -> ~[u8];
}

trait Codec<T: Encode Decode> {
    fn encode(encoder: T) -> ~[u8];
    fn decode(decoder: T) -> ~[u8];
}

impl<T: Encode Decode> Convert<T> : Encode {
    fn encode(buf: &[u8]) -> ~[u8] {
        let buf = self.from.decode(buf);
        let buf = self.to.encode(buf);
        return buf;
    }
}

impl<T: Encode Decode> Convert<T> : Decode {
    fn decode(buf: &[u8]) -> ~[u8] {
        let buf = self.from.decode(buf);
        let buf = self.to.encode(buf);
        return buf;
    }
}

impl<T: Encode Decode> &[u8] : Codec<T> {
    fn encode(encoder: T) -> ~[u8] {
        encoder.encode(self)
    }
    fn decode(decoder: T) -> ~[u8] {
        decoder.decode(self)
    }
}

impl<T: Encode Decode> &str : Codec<T> {
    fn encode(encoder: T) -> ~[u8] {
        encoder.encode(str::to_bytes(self))
    }
    fn decode(decoder: T) -> ~[u8] {
        decoder.decode(str::to_bytes(self))
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_codec_base64() {
        let source = str::to_bytes("foobar");
        let expect = str::to_bytes("Zm9vYmFy");

        let actual = source.encode(Base64);

        assert expect == actual;
    }
    #[test]
    fn test_codec_convert() {
        let string = "foobar";
        let source = string.encode(Base32);
        let expect = string.encode(Base64);

        let actual = source.encode(Convert{from: Base32, to: Base64});

        assert expect == actual;
    }
}
<commit_msg>Use str::byte_slice to avoid copying<commit_after>// encoding.rs

// import enum variants in misc.rs
use Base16         = misc::Base16;
use Base32         = misc::Base32;
use Base64         = misc::Base64;
use Base32Hex      = misc::Base32Hex;
use Base64Url      = misc::Base64Url;

// import constants in misc/base{16,32,64}.rs
use BASE16         = misc::base16::BASE16;
use BASE32         = misc::base32::BASE32_STD;
use BASE64         = misc::base64::BASE64_STD;
use BASE32_HEX     = misc::base32::BASE32_HEX;
use BASE64_URL     = misc::base64::BASE64_URL;

// import structs in misc/base{16,32,64}.rs
use Base16Writer   = misc::base16::Base16Writer;
use Base32Writer   = misc::base32::Base32Writer;
use Base64Writer   = misc::base64::Base64Writer;
use Base32Reader   = misc::base32::Base32Reader;
use Base64Reader   = misc::base64::Base64Reader;

// export all enum variants in misc.rs
export Base16;
export Base32;
export Base64;
export Base32Hex;
export Base64Url;

// export constants
export BASE16;
export BASE32;
export BASE64;
export BASE32_HEX;
export BASE64_URL;

// export structs
export Base16Writer;
export Base32Writer;
export Base64Writer;
export Base32Reader;
export Base64Reader;

export Convert;
export Encode;
export Decode;
export Codec;

struct Convert<T: Encode Decode> {
    from: T,
    to: T,
}

trait Encode {
    fn encode(buf: &[u8]) -> ~[u8];
}

trait Decode {
    fn decode(buf: &[u8]) -> ~[u8];
}

trait Codec<T: Encode Decode> {
    fn encode(encoder: T) -> ~[u8];
    fn decode(decoder: T) -> ~[u8];
}

impl<T: Encode Decode> Convert<T> : Encode {
    fn encode(buf: &[u8]) -> ~[u8] {
        let buf = self.from.decode(buf);
        let buf = self.to.encode(buf);
        return buf;
    }
}

impl<T: Encode Decode> Convert<T> : Decode {
    fn decode(buf: &[u8]) -> ~[u8] {
        let buf = self.from.decode(buf);
        let buf = self.to.encode(buf);
        return buf;
    }
}

impl<T: Encode Decode> &[u8] : Codec<T> {
    fn encode(encoder: T) -> ~[u8] {
        encoder.encode(self)
    }
    fn decode(decoder: T) -> ~[u8] {
        decoder.decode(self)
    }
}

impl<T: Encode Decode> &str : Codec<T> {
    fn encode(encoder: T) -> ~[u8] {
        str::byte_slice(self, |b| encoder.encode(b))
    }
    fn decode(decoder: T) -> ~[u8] {
        str::byte_slice(self, |b| decoder.decode(b))
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_codec_base64() {
        let source = str::to_bytes("foobar");
        let expect = str::to_bytes("Zm9vYmFy");

        let actual = source.encode(Base64);

        assert expect == actual;
    }
    #[test]
    fn test_codec_convert() {
        let string = "foobar";
        let source = string.encode(Base32);
        let expect = string.encode(Base64);

        let actual = source.encode(Convert{from: Base32, to: Base64});

        assert expect == actual;
    }
}
<|endoftext|>


<commit_before>//
// base64.rs - base64 implementation
//
// The Base64 Alphabet
//
//  Value Encoding  Value Encoding  Value Encoding  Value Encoding
//   0 A            17 R            34 i            51 z
//   1 B            18 S            35 j            52 0
//   2 C            19 T            36 k            53 1
//   3 D            20 U            37 l            54 2
//   4 E            21 V            38 m            55 3
//   5 F            22 W            39 n            56 4
//   6 G            23 X            40 o            57 5
//   7 H            24 Y            41 p            58 6
//   8 I            25 Z            42 q            59 7
//   9 J            26 a            43 r            60 8
//  10 K            27 b            44 s            61 9
//  11 L            28 c            45 t            62 +
//  12 M            29 d            46 u            63 /
//  13 N            30 e            47 v
//  14 O            31 f            48 w         (pad) =
//  15 P            32 g            49 x
//  16 Q            33 h            50 y
//

use std;

import std::map;

export base64, mk_base64;

iface base64 {
    fn encode(src: [u8]) -> [u8];
    fn decode(src: [u8]) -> [u8];
    fn urlsafe_encode(src: [u8]) -> [u8];
    fn urlsafe_decode(src: [u8]) -> [u8];
}

fn mk_base64() -> base64 {
    type _base64 = {padd: u8, table: [u8]};
    impl of base64 for _base64 {
        fn encode(src: [u8]) -> [u8] {
            let srclen = vec::len(src);
            let targ = if srclen % 3u == 0u {
                vec::init_elt_mut((srclen / 3u) * 4u, 0u8)
            } else {
                vec::init_elt_mut((srclen / 3u + 1u) * 4u, 0u8)
            };
            let input = vec::init_elt_mut(3u, 0u8);
            let output = vec::init_elt_mut(4u, 0u8);
            let curr = 0u, src_curr = 0u;
            let table = self.table;

            while srclen > 2u {
                input[0] = src[src_curr];
                input[1] = src[src_curr + 1u];
                input[2] = src[src_curr + 2u];
                srclen -= 3u; src_curr += 3u;

                output[0] = input[0] >> 2u8;
                output[1] = ((input[0] &  3u8) << 4u8) | (input[1] >> 4u8);
                output[2] = ((input[1] & 15u8) << 2u8) | (input[2] >> 6u8);
                output[3] = input[2] & 63u8;

                targ[curr] = table[output[0]]; curr += 1u;
                targ[curr] = table[output[1]]; curr += 1u;
                targ[curr] = table[output[2]]; curr += 1u;
                targ[curr] = table[output[3]]; curr += 1u;
            }

            if srclen != 0u {
                input[0] = 0u8; input[1] = 0u8; input[2] = 0u8;

                alt srclen {
                  1u { input[0] = src[src_curr]; }
                  2u { input[0] = src[src_curr];
                       input[1] = src[src_curr + 1u]; }
                  _  { }
                }

                output[0] = input[0] >> 2u8;
                output[1] = ((input[0] &  3u8) << 4u8) | (input[1] >> 4u8);
                output[2] = ((input[1] & 15u8) << 2u8) | (input[2] >> 6u8);

                targ[curr] = table[output[0]]; curr += 1u;
                targ[curr] = table[output[1]]; curr += 1u;
                targ[curr] = if srclen == 1u {
                    self.padd
                } else {
                    table[output[2]]
                };
                curr += 1u; targ[curr] = self.padd;
            }

            vec::from_mut(targ)
        }
        fn decode(src: [u8]) -> [u8] {
            let srclen = vec::len(src);

            if srclen % 4u != 0u { fail "malformed base64 string"; }
            if srclen == 0u { ret []; }

            let input  = vec::init_elt_mut(4u, 0u8);
            let output = vec::init_elt_mut(4u, 0u8);
            let targ = if src[srclen - 2u] == self.padd {
                vec::init_elt_mut(srclen / 4u * 3u - 2u, 0u8)
            } else if src[srclen - 1u] == self.padd {
                vec::init_elt_mut(srclen / 4u * 3u - 1u, 0u8)
            } else {
                vec::init_elt_mut(srclen / 4u * 3u, 0u8)
            };
            let curr = 0u, src_curr = 0u;
            let table = self.table;

            while srclen > 4u {
                input[0] = src[src_curr];
                input[1] = src[src_curr + 1u];
                input[2] = src[src_curr + 2u];
                input[3] = src[src_curr + 3u];
                srclen -= 4u; src_curr += 4u;

                output[0] = idx(table, input[0]);
                if output[0] == 64u8 { fail "malformed base64 string"; }

                output[1] = idx(table, input[1]);
                if output[1] == 64u8 { fail "malformed base64 string"; }

                output[2] = idx(table, input[2]);
                if output[2] == 64u8 { fail "malformed base64 string"; }

                output[3] = idx(table, input[3]);
                if output[3] == 64u8 { fail "malformed base64 string"; }

                targ[curr] = (output[0] << 2u8) | (output[1] >> 4u8);
                curr += 1u;

                targ[curr] =
                    ((output[1] & 15u8) << 4u8) | (output[2] >> 2u8);
                curr += 1u;

                targ[curr] = ((output[2] &  3u8) << 6u8) | output[3];
                curr += 1u;
            }

            if srclen == 4u {
                input[0] = src[src_curr];
                input[1] = src[src_curr + 1u];
                input[2] = src[src_curr + 2u];
                input[3] = src[src_curr + 3u];

                output[0] = idx(table, input[0]);
                if output[0] == 64u8 { fail "malformed base64 string"; }

                output[1] = idx(table, input[1]);
                if output[1] == 64u8 { fail "malformed base64 string"; }

                targ[curr] = (output[0] << 2u8) | (output[1] >> 4u8);
                curr += 1u;

                if input[2] == self.padd { ret vec::from_mut(targ); }

                output[2] = idx(table, input[2]);
                if output[2] == 64u8 { fail "malformed base64 string"; }

                targ[curr] = ((output[1] & 15u8) << 4u8) | (output[2] >> 2u8);
                curr += 1u;

                if input[3] == self.padd { ret vec::from_mut(targ); }

                output[3] = idx(table, input[3]);
                if output[3] == 64u8 { fail "malformed base64 string"; }

                targ[curr] = ((output[2] & 3u8) << 6u8) | output[3];
            }

            vec::from_mut(targ)
        }
        fn urlsafe_encode(src: [u8]) -> [u8] {
            let res = self.encode(src);
            vec::map(res) { |i|
                if i == 43u8 { 45u8 }
                else if i == 47u8 { 95u8 }
                else { i }
            }
        }
        fn urlsafe_decode(src: [u8]) -> [u8] {
            let src0 = vec::map(src) { |i|
                if i == 45u8 { 43u8 }
                else if i == 95u8 { 47u8 }
                else { i }
            };
            self.decode(src0)
        }
    }

    let table = vec::init_elt_mut(64u, 0u8), i = 0u8;
    u8::range(65u8, 91u8)  { |j| table[i] = j; i += 1u8; }
    u8::range(97u8, 123u8) { |j| table[i] = j; i += 1u8; }
    u8::range(48u8, 58u8)  { |j| table[i] = j; i += 1u8; }
    table[i] = 43u8; i += 1u8;
    table[i] = 47u8; i += 1u8;

    {padd: 61u8, table: vec::from_mut(table)} as base64
}

fn idx(elems: [const u8], x: u8) -> u8 {
    let i = 0u8;
    while i < 64u8 {
        if elems[i] == x { break; }
        i += 1u8;
    }
    ret i;
}

#[cfg(test)]
mod tests {
    import core::str::{from_bytes, bytes};
    enum mode {
        t_decode,
        t_encode,
        t_urlsafe_encode,
        t_urlsafe_decode
    }
    fn setup(t: mode) -> map::hashmap<str, str> {
        let m = map::new_str_hash::<str>();
        m.insert("", "");
        alt t {
          t_decode | t_urlsafe_decode {
            m.insert("cGxlYXN1cmUu", "pleasure.");
            m.insert("bGVhc3VyZS4=",  "leasure.");
            m.insert("ZWFzdXJlLg==",   "easure.");
            m.insert("YXN1cmUu",        "asure.");
            m.insert("c3VyZS4=",         "sure.");
          }
          t_encode | t_urlsafe_encode {
            m.insert("pleasure.", "cGxlYXN1cmUu");
            m.insert("leasure.",  "bGVhc3VyZS4=");
            m.insert("easure.",   "ZWFzdXJlLg==");
            m.insert("asure.",        "YXN1cmUu");
            m.insert("sure.",         "c3VyZS4=");
          }
        }
        m
    }
    fn do_test(t: mode) {
        let b64 = mk_base64();
        let m = setup(t);
        m.keys { |k|
            let expected = m.get(k);
            let actual = alt t {
              t_decode { from_bytes(b64.decode(bytes(k))) }
              t_encode { from_bytes(b64.encode(bytes(k))) }
              t_urlsafe_decode { from_bytes(b64.urlsafe_decode(bytes(k))) }
              t_urlsafe_encode { from_bytes(b64.urlsafe_encode(bytes(k))) }
            };
            #debug("expected: %s", expected);
            #debug("actual:   %s", actual);
            assert expected == actual;
        }
    }
    #[test]
    fn decode() { do_test(t_decode); }
    #[test]
    fn encode() { do_test(t_encode); }
    #[test]
    fn urlsafe_decode() { do_test(t_urlsafe_decode); }
    #[test]
    fn urlsafe_encode() { do_test(t_urlsafe_encode); }
}
<commit_msg>changes<commit_after>//
// base64.rs - base64 implementation
//
// The Base64 Alphabet
//
//  Value Encoding  Value Encoding  Value Encoding  Value Encoding
//   0 A            17 R            34 i            51 z
//   1 B            18 S            35 j            52 0
//   2 C            19 T            36 k            53 1
//   3 D            20 U            37 l            54 2
//   4 E            21 V            38 m            55 3
//   5 F            22 W            39 n            56 4
//   6 G            23 X            40 o            57 5
//   7 H            24 Y            41 p            58 6
//   8 I            25 Z            42 q            59 7
//   9 J            26 a            43 r            60 8
//  10 K            27 b            44 s            61 9
//  11 L            28 c            45 t            62 +
//  12 M            29 d            46 u            63 /
//  13 N            30 e            47 v
//  14 O            31 f            48 w         (pad) =
//  15 P            32 g            49 x
//  16 Q            33 h            50 y
//

use std;

import std::map;

export base64, mk_base64;

iface base64 {
    fn encode(src: [u8]) -> [u8];
    fn decode(src: [u8]) -> [u8];
    fn urlsafe_encode(src: [u8]) -> [u8];
    fn urlsafe_decode(src: [u8]) -> [u8];
}

fn mk_base64() -> base64 {
    type _base64 = {padd: u8, mutable table: [u8]};
    impl of base64 for _base64 {
        fn encode(src: [u8]) -> [u8] {
            let srclen = vec::len(src);
            let targ = if srclen % 3u == 0u {
                vec::init_elt_mut((srclen / 3u) * 4u, 0u8)
            } else {
                vec::init_elt_mut((srclen / 3u + 1u) * 4u, 0u8)
            };
            let input = vec::init_elt_mut(3u, 0u8);
            let output = vec::init_elt_mut(4u, 0u8);
            let curr = 0u, src_curr = 0u;
            let table = self.table;

            while srclen > 2u {
                input[0] = src[src_curr];
                input[1] = src[src_curr + 1u];
                input[2] = src[src_curr + 2u];
                srclen -= 3u; src_curr += 3u;

                output[0] = input[0] >> 2u8;
                output[1] = ((input[0] &  3u8) << 4u8) | (input[1] >> 4u8);
                output[2] = ((input[1] & 15u8) << 2u8) | (input[2] >> 6u8);
                output[3] = input[2] & 63u8;

                targ[curr] = table[output[0]]; curr += 1u;
                targ[curr] = table[output[1]]; curr += 1u;
                targ[curr] = table[output[2]]; curr += 1u;
                targ[curr] = table[output[3]]; curr += 1u;
            }

            if srclen != 0u {
                input[0] = 0u8; input[1] = 0u8; input[2] = 0u8;

                alt srclen {
                  1u { input[0] = src[src_curr]; }
                  2u { input[0] = src[src_curr];
                       input[1] = src[src_curr + 1u]; }
                  _  { }
                }

                output[0] = input[0] >> 2u8;
                output[1] = ((input[0] &  3u8) << 4u8) | (input[1] >> 4u8);
                output[2] = ((input[1] & 15u8) << 2u8) | (input[2] >> 6u8);

                targ[curr] = table[output[0]]; curr += 1u;
                targ[curr] = table[output[1]]; curr += 1u;
                targ[curr] = if srclen == 1u {
                    self.padd
                } else {
                    table[output[2]]
                };
                curr += 1u; targ[curr] = self.padd;
            }

            vec::from_mut(targ)
        }
        fn decode(src: [u8]) -> [u8] {
            let srclen = vec::len(src);

            if srclen % 4u != 0u { fail "malformed base64 string"; }
            if srclen == 0u { ret []; }

            let input  = vec::init_elt_mut(4u, 0u8);
            let output = vec::init_elt_mut(4u, 0u8);
            let targ = if src[srclen - 2u] == self.padd {
                vec::init_elt_mut(srclen / 4u * 3u - 2u, 0u8)
            } else if src[srclen - 1u] == self.padd {
                vec::init_elt_mut(srclen / 4u * 3u - 1u, 0u8)
            } else {
                vec::init_elt_mut(srclen / 4u * 3u, 0u8)
            };
            let curr = 0u, src_curr = 0u;
            let table = self.table;

            while srclen > 4u {
                input[0] = src[src_curr];
                input[1] = src[src_curr + 1u];
                input[2] = src[src_curr + 2u];
                input[3] = src[src_curr + 3u];
                srclen -= 4u; src_curr += 4u;

                output[0] = idx(table, input[0]);
                if output[0] == 64u8 { fail "malformed base64 string"; }

                output[1] = idx(table, input[1]);
                if output[1] == 64u8 { fail "malformed base64 string"; }

                output[2] = idx(table, input[2]);
                if output[2] == 64u8 { fail "malformed base64 string"; }

                output[3] = idx(table, input[3]);
                if output[3] == 64u8 { fail "malformed base64 string"; }

                targ[curr] = (output[0] << 2u8) | (output[1] >> 4u8);
                curr += 1u;

                targ[curr] =
                    ((output[1] & 15u8) << 4u8) | (output[2] >> 2u8);
                curr += 1u;

                targ[curr] = ((output[2] &  3u8) << 6u8) | output[3];
                curr += 1u;
            }

            if srclen == 4u {
                input[0] = src[src_curr];
                input[1] = src[src_curr + 1u];
                input[2] = src[src_curr + 2u];
                input[3] = src[src_curr + 3u];

                output[0] = idx(table, input[0]);
                if output[0] == 64u8 { fail "malformed base64 string"; }

                output[1] = idx(table, input[1]);
                if output[1] == 64u8 { fail "malformed base64 string"; }

                targ[curr] = (output[0] << 2u8) | (output[1] >> 4u8);
                curr += 1u;

                if input[2] == self.padd { ret vec::from_mut(targ); }

                output[2] = idx(table, input[2]);
                if output[2] == 64u8 { fail "malformed base64 string"; }

                targ[curr] = ((output[1] & 15u8) << 4u8) | (output[2] >> 2u8);
                curr += 1u;

                if input[3] == self.padd { ret vec::from_mut(targ); }

                output[3] = idx(table, input[3]);
                if output[3] == 64u8 { fail "malformed base64 string"; }

                targ[curr] = ((output[2] & 3u8) << 6u8) | output[3];
            }

            vec::from_mut(targ)
        }
        fn urlsafe_encode(src: [u8]) -> [u8] {
            let tmp = self.table;
            self.table = vec::map(tmp) { |i|
                if i == 43u8 { 45u8 }
                else if i == 47u8 { 95u8 }
                else { i }
            };
            let res = self.encode(src);
            self.table = tmp;
            res
        }
        fn urlsafe_decode(src: [u8]) -> [u8] {
            let tmp = self.table;
            self.table = vec::map(tmp) { |i|
                if i == 43u8 { 45u8 }
                else if i == 47u8 { 95u8 }
                else { i }
            };
            let res = self.decode(src);
            self.table = tmp;
            res
        }
    }

    let table = vec::init_elt_mut(64u, 0u8), i = 0u8;
    u8::range(65u8, 91u8)  { |j| table[i] = j; i += 1u8; }
    u8::range(97u8, 123u8) { |j| table[i] = j; i += 1u8; }
    u8::range(48u8, 58u8)  { |j| table[i] = j; i += 1u8; }
    table[i] = 43u8; i += 1u8;
    table[i] = 47u8; i += 1u8;

    {padd: 61u8, mutable table: vec::from_mut(table)} as base64
}

fn idx(elems: [const u8], x: u8) -> u8 {
    let i = 0u8;
    while i < 64u8 {
        if elems[i] == x { break; }
        i += 1u8;
    }
    ret i;
}

#[cfg(test)]
mod tests {
    import core::str::{from_bytes, bytes};
    enum mode {
        t_decode,
        t_encode,
        t_urlsafe_encode,
        t_urlsafe_decode
    }
    fn setup(t: mode) -> map::hashmap<str, str> {
        let m = map::new_str_hash::<str>();
        m.insert("", "");
        alt t {
          t_decode | t_urlsafe_decode {
            m.insert("cGxlYXN1cmUu", "pleasure.");
            m.insert("bGVhc3VyZS4=",  "leasure.");
            m.insert("ZWFzdXJlLg==",   "easure.");
            m.insert("YXN1cmUu",        "asure.");
            m.insert("c3VyZS4=",         "sure.");
          }
          t_encode | t_urlsafe_encode {
            m.insert("pleasure.", "cGxlYXN1cmUu");
            m.insert("leasure.",  "bGVhc3VyZS4=");
            m.insert("easure.",   "ZWFzdXJlLg==");
            m.insert("asure.",        "YXN1cmUu");
            m.insert("sure.",         "c3VyZS4=");
          }
        }
        m
    }
    fn do_test(t: mode) {
        let b64 = mk_base64();
        let m = setup(t);
        m.keys { |k|
            let expected = m.get(k);
            let actual = alt t {
              t_decode { from_bytes(b64.decode(bytes(k))) }
              t_encode { from_bytes(b64.encode(bytes(k))) }
              t_urlsafe_decode { from_bytes(b64.urlsafe_decode(bytes(k))) }
              t_urlsafe_encode { from_bytes(b64.urlsafe_encode(bytes(k))) }
            };
            #debug("expected: %s", expected);
            #debug("actual:   %s", actual);
            assert expected == actual;
        }
    }
    #[test]
    fn decode() { do_test(t_decode); }
    #[test]
    fn encode() { do_test(t_encode); }
    #[test]
    fn urlsafe_decode() { do_test(t_urlsafe_decode); }
    #[test]
    fn urlsafe_encode() { do_test(t_urlsafe_encode); }
}
<|endoftext|>


<commit_before>//! ARMv6K Nintendo 3DS C Newlib definitions

pub type c_char = u8;
pub type c_long = i32;
pub type c_ulong = u32;

pub type wchar_t = ::c_uint;

pub type u_register_t = ::c_uint;
pub type u_char = ::c_uchar;
pub type u_short = ::c_ushort;
pub type u_int = ::c_uint;
pub type u_long = c_ulong;
pub type ushort = ::c_ushort;
pub type uint = ::c_uint;
pub type ulong = c_ulong;
pub type clock_t = c_ulong;
pub type daddr_t = c_long;
pub type caddr_t = *mut c_char;
pub type sbintime_t = ::c_longlong;
pub type sigset_t = ::c_ulong;

s! {
    pub struct sockaddr {
        pub sa_family: ::sa_family_t,
        pub sa_data: [::c_char; 26usize],
    }

    pub struct sockaddr_storage {
        pub ss_family: ::sa_family_t,
        pub __ss_padding: [::c_char; 26usize],
    }

    pub struct sockaddr_in {
        pub sin_family: ::sa_family_t,
        pub sin_port: ::in_port_t,
        pub sin_addr: ::in_addr,
    }

    pub struct sockaddr_in6 {
        pub sin6_family: ::sa_family_t,
        pub sin6_port: ::in_port_t,
        pub sin6_flowinfo: u32,
        pub sin6_addr: ::in6_addr,
        pub sin6_scope_id: u32,
    }

    pub struct sockaddr_un {
        pub sun_len: ::c_uchar,
        pub sun_family: ::sa_family_t,
        pub sun_path: [::c_char; 104usize],
    }

    pub struct sched_param {
        pub sched_priority: ::c_int,
    }

    pub struct stat {
        pub st_dev: ::dev_t,
        pub st_ino: ::ino_t,
        pub st_mode: ::mode_t,
        pub st_nlink: ::nlink_t,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::dev_t,
        pub st_size: ::off_t,
        pub st_atim: ::timespec,
        pub st_mtim: ::timespec,
        pub st_ctim: ::timespec,
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::blkcnt_t,
        pub st_spare4: [::c_long; 2usize],
    }
}

pub const SIGEV_NONE: ::c_int = 1;
pub const SIGEV_SIGNAL: ::c_int = 2;
pub const SIGEV_THREAD: ::c_int = 3;
pub const SA_NOCLDSTOP: ::c_int = 1;
pub const MINSIGSTKSZ: ::c_int = 2048;
pub const SIGSTKSZ: ::c_int = 8192;
pub const SS_ONSTACK: ::c_int = 1;
pub const SS_DISABLE: ::c_int = 2;
pub const SIG_SETMASK: ::c_int = 0;
pub const SIG_BLOCK: ::c_int = 1;
pub const SIG_UNBLOCK: ::c_int = 2;
pub const SIGHUP: ::c_int = 1;
pub const SIGINT: ::c_int = 2;
pub const SIGQUIT: ::c_int = 3;
pub const SIGILL: ::c_int = 4;
pub const SIGTRAP: ::c_int = 5;
pub const SIGABRT: ::c_int = 6;
pub const SIGEMT: ::c_int = 7;
pub const SIGFPE: ::c_int = 8;
pub const SIGKILL: ::c_int = 9;
pub const SIGBUS: ::c_int = 10;
pub const SIGSEGV: ::c_int = 11;
pub const SIGSYS: ::c_int = 12;
pub const SIGPIPE: ::c_int = 13;
pub const SIGALRM: ::c_int = 14;
pub const SIGTERM: ::c_int = 15;
pub const SIGURG: ::c_int = 16;
pub const SIGSTOP: ::c_int = 17;
pub const SIGTSTP: ::c_int = 18;
pub const SIGCONT: ::c_int = 19;
pub const SIGCHLD: ::c_int = 20;
pub const SIGCLD: ::c_int = 20;
pub const SIGTTIN: ::c_int = 21;
pub const SIGTTOU: ::c_int = 22;
pub const SIGIO: ::c_int = 23;
pub const SIGPOLL: ::c_int = 23;
pub const SIGXCPU: ::c_int = 24;
pub const SIGXFSZ: ::c_int = 25;
pub const SIGVTALRM: ::c_int = 26;
pub const SIGPROF: ::c_int = 27;
pub const SIGWINCH: ::c_int = 28;
pub const SIGLOST: ::c_int = 29;
pub const SIGUSR1: ::c_int = 30;
pub const SIGUSR2: ::c_int = 31;
pub const NSIG: ::c_int = 32;
pub const CLOCK_ENABLED: ::c_uint = 1;
pub const CLOCK_DISABLED: ::c_uint = 0;
pub const CLOCK_ALLOWED: ::c_uint = 1;
pub const CLOCK_DISALLOWED: ::c_uint = 0;
pub const TIMER_ABSTIME: ::c_uint = 4;
pub const SOL_SOCKET: ::c_int = 65535;
pub const MSG_OOB: ::c_int = 1;
pub const MSG_PEEK: ::c_int = 2;
pub const MSG_DONTWAIT: ::c_int = 4;
pub const MSG_DONTROUTE: ::c_int = 0;
pub const MSG_WAITALL: ::c_int = 0;
pub const MSG_MORE: ::c_int = 0;
pub const MSG_NOSIGNAL: ::c_int = 0;
pub const SOL_CONFIG: ::c_uint = 65534;

pub const _SC_PAGESIZE: ::c_int = 8;
pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 51;

pub const PTHREAD_STACK_MIN: ::size_t = 4096;
pub const WNOHANG: ::c_int = 1;

pub const POLLIN: ::c_short = 0x0001;
pub const POLLPRI: ::c_short = 0x0002;
pub const POLLOUT: ::c_short = 0x0004;
pub const POLLRDNORM: ::c_short = 0x0040;
pub const POLLWRNORM: ::c_short = POLLOUT;
pub const POLLRDBAND: ::c_short = 0x0080;
pub const POLLWRBAND: ::c_short = 0x0100;
pub const POLLERR: ::c_short = 0x0008;
pub const POLLHUP: ::c_short = 0x0010;
pub const POLLNVAL: ::c_short = 0x0020;

pub const EAI_AGAIN: ::c_int = 2;
pub const EAI_BADFLAGS: ::c_int = 3;
pub const EAI_FAIL: ::c_int = 4;
pub const EAI_SERVICE: ::c_int = 9;
pub const EAI_SYSTEM: ::c_int = 11;
pub const EAI_BADHINTS: ::c_int = 12;
pub const EAI_PROTOCOL: ::c_int = 13;
pub const EAI_OVERFLOW: ::c_int = 14;
pub const EAI_MAX: ::c_int = 15;

pub const AF_UNIX: ::c_int = 1;
pub const AF_INET6: ::c_int = 23;

pub const FIONBIO: ::c_ulong = 1;

pub const RTLD_DEFAULT: *mut ::c_void = 0 as *mut ::c_void;

// For pthread get/setschedparam
pub const SCHED_FIFO: ::c_int = 1;
pub const SCHED_RR: ::c_int = 2;

// For getrandom()
pub const GRND_NONBLOCK: ::c_uint = 0x1;
pub const GRND_RANDOM: ::c_uint = 0x2;

// Horizon OS works doesn't or can't hold any of this information
safe_f! {
    pub {const} fn WIFSTOPPED(_status: ::c_int) -> bool {
        false
    }

    pub {const} fn WSTOPSIG(_status: ::c_int) -> ::c_int {
        0
    }

    pub {const} fn WIFCONTINUED(_status: ::c_int) -> bool {
        true
    }

    pub {const} fn WIFSIGNALED(_status: ::c_int) -> bool {
        false
    }

    pub {const} fn WTERMSIG(_status: ::c_int) -> ::c_int {
        0
    }

    pub {const} fn WIFEXITED(_status: ::c_int) -> bool {
        true
    }

    pub {const} fn WEXITSTATUS(_status: ::c_int) -> ::c_int {
        0
    }

    pub {const} fn WCOREDUMP(_status: ::c_int) -> bool {
        false
    }
}

extern "C" {
    pub fn pthread_create(
        native: *mut ::pthread_t,
        attr: *const ::pthread_attr_t,
        f: extern "C" fn(_: *mut ::c_void) -> *mut ::c_void,
        value: *mut ::c_void,
    ) -> ::c_int;

    pub fn pthread_attr_getschedparam(
        attr: *const ::pthread_attr_t,
        param: *mut sched_param,
    ) -> ::c_int;

    pub fn pthread_attr_setschedparam(
        attr: *mut ::pthread_attr_t,
        param: *const sched_param,
    ) -> ::c_int;

    pub fn pthread_attr_getprocessorid_np(
        attr: *const ::pthread_attr_t,
        processor_id: *mut ::c_int,
    ) -> ::c_int;

    pub fn pthread_attr_setprocessorid_np(
        attr: *mut ::pthread_attr_t,
        processor_id: ::c_int,
    ) -> ::c_int;

    pub fn pthread_getschedparam(
        native: ::pthread_t,
        policy: *mut ::c_int,
        param: *mut ::sched_param,
    ) -> ::c_int;

    pub fn pthread_setschedparam(
        native: ::pthread_t,
        policy: ::c_int,
        param: *const ::sched_param,
    ) -> ::c_int;

    pub fn pthread_getprocessorid_np() -> ::c_int;

    pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t;

    pub fn gethostid() -> ::c_long;
}
<commit_msg>Add pthread_condattr_{set,get}clock on Horizon OS<commit_after>//! ARMv6K Nintendo 3DS C Newlib definitions

pub type c_char = u8;
pub type c_long = i32;
pub type c_ulong = u32;

pub type wchar_t = ::c_uint;

pub type u_register_t = ::c_uint;
pub type u_char = ::c_uchar;
pub type u_short = ::c_ushort;
pub type u_int = ::c_uint;
pub type u_long = c_ulong;
pub type ushort = ::c_ushort;
pub type uint = ::c_uint;
pub type ulong = c_ulong;
pub type clock_t = c_ulong;
pub type daddr_t = c_long;
pub type caddr_t = *mut c_char;
pub type sbintime_t = ::c_longlong;
pub type sigset_t = ::c_ulong;

s! {
    pub struct sockaddr {
        pub sa_family: ::sa_family_t,
        pub sa_data: [::c_char; 26usize],
    }

    pub struct sockaddr_storage {
        pub ss_family: ::sa_family_t,
        pub __ss_padding: [::c_char; 26usize],
    }

    pub struct sockaddr_in {
        pub sin_family: ::sa_family_t,
        pub sin_port: ::in_port_t,
        pub sin_addr: ::in_addr,
    }

    pub struct sockaddr_in6 {
        pub sin6_family: ::sa_family_t,
        pub sin6_port: ::in_port_t,
        pub sin6_flowinfo: u32,
        pub sin6_addr: ::in6_addr,
        pub sin6_scope_id: u32,
    }

    pub struct sockaddr_un {
        pub sun_len: ::c_uchar,
        pub sun_family: ::sa_family_t,
        pub sun_path: [::c_char; 104usize],
    }

    pub struct sched_param {
        pub sched_priority: ::c_int,
    }

    pub struct stat {
        pub st_dev: ::dev_t,
        pub st_ino: ::ino_t,
        pub st_mode: ::mode_t,
        pub st_nlink: ::nlink_t,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::dev_t,
        pub st_size: ::off_t,
        pub st_atim: ::timespec,
        pub st_mtim: ::timespec,
        pub st_ctim: ::timespec,
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::blkcnt_t,
        pub st_spare4: [::c_long; 2usize],
    }
}

pub const SIGEV_NONE: ::c_int = 1;
pub const SIGEV_SIGNAL: ::c_int = 2;
pub const SIGEV_THREAD: ::c_int = 3;
pub const SA_NOCLDSTOP: ::c_int = 1;
pub const MINSIGSTKSZ: ::c_int = 2048;
pub const SIGSTKSZ: ::c_int = 8192;
pub const SS_ONSTACK: ::c_int = 1;
pub const SS_DISABLE: ::c_int = 2;
pub const SIG_SETMASK: ::c_int = 0;
pub const SIG_BLOCK: ::c_int = 1;
pub const SIG_UNBLOCK: ::c_int = 2;
pub const SIGHUP: ::c_int = 1;
pub const SIGINT: ::c_int = 2;
pub const SIGQUIT: ::c_int = 3;
pub const SIGILL: ::c_int = 4;
pub const SIGTRAP: ::c_int = 5;
pub const SIGABRT: ::c_int = 6;
pub const SIGEMT: ::c_int = 7;
pub const SIGFPE: ::c_int = 8;
pub const SIGKILL: ::c_int = 9;
pub const SIGBUS: ::c_int = 10;
pub const SIGSEGV: ::c_int = 11;
pub const SIGSYS: ::c_int = 12;
pub const SIGPIPE: ::c_int = 13;
pub const SIGALRM: ::c_int = 14;
pub const SIGTERM: ::c_int = 15;
pub const SIGURG: ::c_int = 16;
pub const SIGSTOP: ::c_int = 17;
pub const SIGTSTP: ::c_int = 18;
pub const SIGCONT: ::c_int = 19;
pub const SIGCHLD: ::c_int = 20;
pub const SIGCLD: ::c_int = 20;
pub const SIGTTIN: ::c_int = 21;
pub const SIGTTOU: ::c_int = 22;
pub const SIGIO: ::c_int = 23;
pub const SIGPOLL: ::c_int = 23;
pub const SIGXCPU: ::c_int = 24;
pub const SIGXFSZ: ::c_int = 25;
pub const SIGVTALRM: ::c_int = 26;
pub const SIGPROF: ::c_int = 27;
pub const SIGWINCH: ::c_int = 28;
pub const SIGLOST: ::c_int = 29;
pub const SIGUSR1: ::c_int = 30;
pub const SIGUSR2: ::c_int = 31;
pub const NSIG: ::c_int = 32;
pub const CLOCK_ENABLED: ::c_uint = 1;
pub const CLOCK_DISABLED: ::c_uint = 0;
pub const CLOCK_ALLOWED: ::c_uint = 1;
pub const CLOCK_DISALLOWED: ::c_uint = 0;
pub const TIMER_ABSTIME: ::c_uint = 4;
pub const SOL_SOCKET: ::c_int = 65535;
pub const MSG_OOB: ::c_int = 1;
pub const MSG_PEEK: ::c_int = 2;
pub const MSG_DONTWAIT: ::c_int = 4;
pub const MSG_DONTROUTE: ::c_int = 0;
pub const MSG_WAITALL: ::c_int = 0;
pub const MSG_MORE: ::c_int = 0;
pub const MSG_NOSIGNAL: ::c_int = 0;
pub const SOL_CONFIG: ::c_uint = 65534;

pub const _SC_PAGESIZE: ::c_int = 8;
pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 51;

pub const PTHREAD_STACK_MIN: ::size_t = 4096;
pub const WNOHANG: ::c_int = 1;

pub const POLLIN: ::c_short = 0x0001;
pub const POLLPRI: ::c_short = 0x0002;
pub const POLLOUT: ::c_short = 0x0004;
pub const POLLRDNORM: ::c_short = 0x0040;
pub const POLLWRNORM: ::c_short = POLLOUT;
pub const POLLRDBAND: ::c_short = 0x0080;
pub const POLLWRBAND: ::c_short = 0x0100;
pub const POLLERR: ::c_short = 0x0008;
pub const POLLHUP: ::c_short = 0x0010;
pub const POLLNVAL: ::c_short = 0x0020;

pub const EAI_AGAIN: ::c_int = 2;
pub const EAI_BADFLAGS: ::c_int = 3;
pub const EAI_FAIL: ::c_int = 4;
pub const EAI_SERVICE: ::c_int = 9;
pub const EAI_SYSTEM: ::c_int = 11;
pub const EAI_BADHINTS: ::c_int = 12;
pub const EAI_PROTOCOL: ::c_int = 13;
pub const EAI_OVERFLOW: ::c_int = 14;
pub const EAI_MAX: ::c_int = 15;

pub const AF_UNIX: ::c_int = 1;
pub const AF_INET6: ::c_int = 23;

pub const FIONBIO: ::c_ulong = 1;

pub const RTLD_DEFAULT: *mut ::c_void = 0 as *mut ::c_void;

// For pthread get/setschedparam
pub const SCHED_FIFO: ::c_int = 1;
pub const SCHED_RR: ::c_int = 2;

// For getrandom()
pub const GRND_NONBLOCK: ::c_uint = 0x1;
pub const GRND_RANDOM: ::c_uint = 0x2;

// Horizon OS works doesn't or can't hold any of this information
safe_f! {
    pub {const} fn WIFSTOPPED(_status: ::c_int) -> bool {
        false
    }

    pub {const} fn WSTOPSIG(_status: ::c_int) -> ::c_int {
        0
    }

    pub {const} fn WIFCONTINUED(_status: ::c_int) -> bool {
        true
    }

    pub {const} fn WIFSIGNALED(_status: ::c_int) -> bool {
        false
    }

    pub {const} fn WTERMSIG(_status: ::c_int) -> ::c_int {
        0
    }

    pub {const} fn WIFEXITED(_status: ::c_int) -> bool {
        true
    }

    pub {const} fn WEXITSTATUS(_status: ::c_int) -> ::c_int {
        0
    }

    pub {const} fn WCOREDUMP(_status: ::c_int) -> bool {
        false
    }
}

extern "C" {
    pub fn pthread_create(
        native: *mut ::pthread_t,
        attr: *const ::pthread_attr_t,
        f: extern "C" fn(_: *mut ::c_void) -> *mut ::c_void,
        value: *mut ::c_void,
    ) -> ::c_int;

    pub fn pthread_attr_getschedparam(
        attr: *const ::pthread_attr_t,
        param: *mut sched_param,
    ) -> ::c_int;

    pub fn pthread_attr_setschedparam(
        attr: *mut ::pthread_attr_t,
        param: *const sched_param,
    ) -> ::c_int;

    pub fn pthread_attr_getprocessorid_np(
        attr: *const ::pthread_attr_t,
        processor_id: *mut ::c_int,
    ) -> ::c_int;

    pub fn pthread_attr_setprocessorid_np(
        attr: *mut ::pthread_attr_t,
        processor_id: ::c_int,
    ) -> ::c_int;

    pub fn pthread_getschedparam(
        native: ::pthread_t,
        policy: *mut ::c_int,
        param: *mut ::sched_param,
    ) -> ::c_int;

    pub fn pthread_setschedparam(
        native: ::pthread_t,
        policy: ::c_int,
        param: *const ::sched_param,
    ) -> ::c_int;

    pub fn pthread_condattr_getclock(
        attr: *const ::pthread_condattr_t,
        clock_id: *mut ::clockid_t,
    ) -> ::c_int;

    pub fn pthread_condattr_setclock(
        attr: *mut ::pthread_condattr_t,
        clock_id: ::clockid_t,
    ) -> ::c_int;

    pub fn pthread_getprocessorid_np() -> ::c_int;

    pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t;

    pub fn gethostid() -> ::c_long;
}
<|endoftext|>


<commit_before>use super::{Mass, Schwarzschild};
use diffgeom::coordinates::{ConversionTo, CoordinateSystem, Point};
use diffgeom::metric::MetricSystem;
use diffgeom::tensors::{ContravariantIndex, CovariantIndex, InvTwoForm, Matrix, Tensor, TwoForm};
use std::marker::PhantomData;
use typenum::consts::U4;

pub struct EddingtonFinkelstein<M: Mass> {
    _m: PhantomData<M>,
}

impl<M: Mass> CoordinateSystem for EddingtonFinkelstein<M> {
    type Dimension = U4;
}

impl<M: Mass> MetricSystem for EddingtonFinkelstein<M> {
    fn g(x: &Point<Self>) -> TwoForm<Self> {
        let r = x[1];
        let th = x[2];
        let m = M::mass();
        TwoForm::new(
            x.clone(),
            arr![f64;
                1.0 - 2.0*m/r, -1.0, 0.0, 0.0,
                -1.0, 0.0, 0.0, 0.0,
                0.0, 0.0, -r*r, 0.0,
                0.0, 0.0, 0.0, -r*r*th.sin()*th.sin()
            ],
        )
    }

    fn inv_g(x: &Point<Self>) -> InvTwoForm<Self> {
        let r = x[1];
        let th = x[2];
        let m = M::mass();
        InvTwoForm::new(
            x.clone(),
            arr![f64;
                -1.0 + 2.0*m/r, -1.0, 0.0, 0.0,
                -1.0, 0.0, 0.0, 0.0,
                0.0, 0.0, -1.0/(r*r), 0.0,
                0.0, 0.0, 0.0, -1.0/(r*r*th.sin()*th.sin())
            ],
        )
    }

    fn christoffel(
        x: &Point<Self>,
    ) -> Tensor<Self, (ContravariantIndex, (CovariantIndex, CovariantIndex))> {
        let r = x[1];
        let th = x[2];
        let m = M::mass();
        let mr = m / r;
        let r2m = r - 2.0 * m;
        Tensor::<Self, (ContravariantIndex, (CovariantIndex, CovariantIndex))>::new(
            x.clone(),
            arr![f64;
                mr/r, 0.0, 0.0, 0.0,
                0.0, 0.0, 0.0, 0.0,
                0.0, 0.0, -r, 0.0,
                0.0, 0.0, 0.0, -r*th.sin()*th.sin(),

                m*r2m/r/r/r, -mr/r, 0.0, 0.0,
                -mr/r, 0.0, 0.0, 0.0,
                0.0, 0.0, -r2m, 0.0,
                0.0, 0.0, 0.0, -r2m*th.sin()*th.sin(),

                0.0, 0.0, 0.0, 0.0,
                0.0, 0.0, 1.0/r, 0.0,
                0.0, 1.0/r, 0.0, 0.0,
                0.0, 0.0, 0.0, -th.sin()*th.cos(),

                0.0, 0.0, 0.0, 0.0,
                0.0, 0.0, 0.0, 1.0/r,
                0.0, 0.0, 0.0, th.cos()/th.sin(),
                0.0, 1.0/r, th.cos()/th.sin(), 0.0
            ],
        )
    }

    // TODO
    //fn dg(x: &Point<Self>) -> Tensor<Self, (CovariantIndex, (CovariantIndex, CovariantIndex))>
    //fn covariant_christoffel(x: &Point<Self>) -> Tensor<Self, (CovariantIndex, (CovariantIndex, CovariantIndex))>
}

// Conversions

impl<M: Mass + 'static> ConversionTo<Schwarzschild<M>> for EddingtonFinkelstein<M> {
    fn convert_point(p: &Point<Self>) -> Point<Schwarzschild<M>> {
        let u = p[0];
        let r = p[1];
        let m = M::mass();
        let t = u - r - (0.5 * (r - 2.0 * m) / m).ln() * 2.0 * m;
        Point::new(arr![f64; t, r, p[2], p[3]])
    }

    fn jacobian(p: &Point<Self>) -> Matrix<Schwarzschild<M>> {
        let r = p[1];
        let m = M::mass();
        let dtdr = -r / (r - 2.0 * m);
        Matrix::new(
            Self::convert_point(p),
            arr![f64;
                1.0, dtdr, 0.0, 0.0,
                0.0, 1.0, 0.0, 0.0,
                0.0, 0.0, 1.0, 0.0,
                0.0, 0.0, 0.0, 1.0,
            ],
        )
    }

    fn inv_jacobian(
        p: &Point<Self>,
    ) -> Tensor<Schwarzschild<M>, (CovariantIndex, ContravariantIndex)> {
        let r = p[1];
        let m = M::mass();
        let dtdr = -r / (r - 2.0 * m);
        Tensor::<Schwarzschild<M>, (CovariantIndex, ContravariantIndex)>::new(
            Self::convert_point(p),
            arr![f64;
                1.0, -dtdr, 0.0, 0.0,
                0.0, 1.0, 0.0, 0.0,
                0.0, 0.0, 1.0, 0.0,
                0.0, 0.0, 0.0, 1.0,
            ],
        )
    }
}
<commit_msg>coords/schw: conversions from EF to near-pole coords<commit_after>use super::{Mass, NearPole0EF, NearPolePiEF, Schwarzschild};
use diffgeom::coordinates::{ConversionTo, CoordinateSystem, Point};
use diffgeom::metric::MetricSystem;
use diffgeom::tensors::{ContravariantIndex, CovariantIndex, InvTwoForm, Matrix, Tensor, TwoForm};
use std::f64::consts::PI;
use std::marker::PhantomData;
use typenum::consts::U4;

pub struct EddingtonFinkelstein<M: Mass> {
    _m: PhantomData<M>,
}

impl<M: Mass> CoordinateSystem for EddingtonFinkelstein<M> {
    type Dimension = U4;
}

impl<M: Mass> MetricSystem for EddingtonFinkelstein<M> {
    fn g(x: &Point<Self>) -> TwoForm<Self> {
        let r = x[1];
        let th = x[2];
        let m = M::mass();
        TwoForm::new(
            x.clone(),
            arr![f64;
                1.0 - 2.0*m/r, -1.0, 0.0, 0.0,
                -1.0, 0.0, 0.0, 0.0,
                0.0, 0.0, -r*r, 0.0,
                0.0, 0.0, 0.0, -r*r*th.sin()*th.sin()
            ],
        )
    }

    fn inv_g(x: &Point<Self>) -> InvTwoForm<Self> {
        let r = x[1];
        let th = x[2];
        let m = M::mass();
        InvTwoForm::new(
            x.clone(),
            arr![f64;
                -1.0 + 2.0*m/r, -1.0, 0.0, 0.0,
                -1.0, 0.0, 0.0, 0.0,
                0.0, 0.0, -1.0/(r*r), 0.0,
                0.0, 0.0, 0.0, -1.0/(r*r*th.sin()*th.sin())
            ],
        )
    }

    fn christoffel(
        x: &Point<Self>,
    ) -> Tensor<Self, (ContravariantIndex, (CovariantIndex, CovariantIndex))> {
        let r = x[1];
        let th = x[2];
        let m = M::mass();
        let mr = m / r;
        let r2m = r - 2.0 * m;
        Tensor::<Self, (ContravariantIndex, (CovariantIndex, CovariantIndex))>::new(
            x.clone(),
            arr![f64;
                mr/r, 0.0, 0.0, 0.0,
                0.0, 0.0, 0.0, 0.0,
                0.0, 0.0, -r, 0.0,
                0.0, 0.0, 0.0, -r*th.sin()*th.sin(),

                m*r2m/r/r/r, -mr/r, 0.0, 0.0,
                -mr/r, 0.0, 0.0, 0.0,
                0.0, 0.0, -r2m, 0.0,
                0.0, 0.0, 0.0, -r2m*th.sin()*th.sin(),

                0.0, 0.0, 0.0, 0.0,
                0.0, 0.0, 1.0/r, 0.0,
                0.0, 1.0/r, 0.0, 0.0,
                0.0, 0.0, 0.0, -th.sin()*th.cos(),

                0.0, 0.0, 0.0, 0.0,
                0.0, 0.0, 0.0, 1.0/r,
                0.0, 0.0, 0.0, th.cos()/th.sin(),
                0.0, 1.0/r, th.cos()/th.sin(), 0.0
            ],
        )
    }

    // TODO
    //fn dg(x: &Point<Self>) -> Tensor<Self, (CovariantIndex, (CovariantIndex, CovariantIndex))>
    //fn covariant_christoffel(x: &Point<Self>) -> Tensor<Self, (CovariantIndex, (CovariantIndex, CovariantIndex))>
}

// Conversions

impl<M: Mass + 'static> ConversionTo<Schwarzschild<M>> for EddingtonFinkelstein<M> {
    fn convert_point(p: &Point<Self>) -> Point<Schwarzschild<M>> {
        let u = p[0];
        let r = p[1];
        let m = M::mass();
        let t = u - r - (0.5 * (r - 2.0 * m) / m).ln() * 2.0 * m;
        Point::new(arr![f64; t, r, p[2], p[3]])
    }

    fn jacobian(p: &Point<Self>) -> Matrix<Schwarzschild<M>> {
        let r = p[1];
        let m = M::mass();
        let dtdr = -r / (r - 2.0 * m);
        Matrix::new(
            Self::convert_point(p),
            arr![f64;
                1.0, dtdr, 0.0, 0.0,
                0.0, 1.0, 0.0, 0.0,
                0.0, 0.0, 1.0, 0.0,
                0.0, 0.0, 0.0, 1.0,
            ],
        )
    }

    fn inv_jacobian(
        p: &Point<Self>,
    ) -> Tensor<Schwarzschild<M>, (CovariantIndex, ContravariantIndex)> {
        let r = p[1];
        let m = M::mass();
        let dtdr = -r / (r - 2.0 * m);
        Tensor::<Schwarzschild<M>, (CovariantIndex, ContravariantIndex)>::new(
            Self::convert_point(p),
            arr![f64;
                1.0, -dtdr, 0.0, 0.0,
                0.0, 1.0, 0.0, 0.0,
                0.0, 0.0, 1.0, 0.0,
                0.0, 0.0, 0.0, 1.0,
            ],
        )
    }
}

impl<M: Mass + 'static> ConversionTo<NearPole0EF<M>> for EddingtonFinkelstein<M> {
    fn convert_point(p: &Point<Self>) -> Point<NearPole0EF<M>> {
        let th = p[2];
        let ph = p[3];
        let x = (th / 2.0).tan() * ph.cos();
        let y = (th / 2.0).tan() * ph.sin();
        Point::new(arr![f64; p[0], p[1], x, y])
    }

    fn jacobian(p: &Point<Self>) -> Matrix<NearPole0EF<M>> {
        let t2 = p[2] / 2.0;
        let ph = p[3];
        let tan2th1 = 1.0 + t2.tan() * t2.tan();
        Matrix::new(
            Self::convert_point(p),
            arr![f64;
                1.0, 0.0, 0.0, 0.0,
                0.0, 1.0, 0.0, 0.0,
                0.0, 0.0, 2.0 * ph.cos() / tan2th1, 2.0 * ph.sin() / tan2th1,
                0.0, 0.0, -ph.sin() / t2.tan(), ph.cos() / t2.tan(),
            ],
        )
    }

    fn inv_jacobian(
        p: &Point<Self>,
    ) -> Tensor<NearPole0EF<M>, (CovariantIndex, ContravariantIndex)> {
        let t2 = p[2] / 2.0;
        let ph = p[3];
        let cos2t2 = t2.cos() * t2.cos();
        Tensor::<NearPole0EF<M>, (CovariantIndex, ContravariantIndex)>::new(
            Self::convert_point(p),
            arr![f64;
                1.0, 0.0, 0.0, 0.0,
                0.0, 1.0, 0.0, 0.0,
                0.0, 0.0, 0.5 * ph.cos() / cos2t2, -t2.tan() * ph.sin(),
                0.0, 0.0, 0.5 * ph.sin() / cos2t2, t2.tan() * ph.cos(),
            ],
        )
    }
}

impl<M: Mass + 'static> ConversionTo<NearPolePiEF<M>> for EddingtonFinkelstein<M> {
    fn convert_point(p: &Point<Self>) -> Point<NearPolePiEF<M>> {
        let th = p[2];
        let ph = p[3];
        let x = ((PI - th) / 2.0).tan() * ph.cos();
        let y = ((PI - th) / 2.0).tan() * ph.sin();
        Point::new(arr![f64; p[0], p[1], x, y])
    }

    fn jacobian(p: &Point<Self>) -> Matrix<NearPolePiEF<M>> {
        let t2 = p[2] / 2.0;
        let ph = p[3];
        let tan2th1 = 1.0 + t2.tan() * t2.tan();
        Matrix::new(
            Self::convert_point(p),
            arr![f64;
                1.0, 0.0, 0.0, 0.0,
                0.0, 1.0, 0.0, 0.0,
                0.0, 0.0, -2.0 * ph.cos() / tan2th1, -2.0 * ph.sin() / tan2th1,
                0.0, 0.0, -ph.sin() / t2.tan(), ph.cos() / t2.tan(),
            ],
        )
    }

    fn inv_jacobian(
        p: &Point<Self>,
    ) -> Tensor<NearPolePiEF<M>, (CovariantIndex, ContravariantIndex)> {
        let t2 = p[2] / 2.0;
        let ph = p[3];
        let cos2t2 = t2.cos() * t2.cos();
        Tensor::<NearPolePiEF<M>, (CovariantIndex, ContravariantIndex)>::new(
            Self::convert_point(p),
            arr![f64;
                1.0, 0.0, 0.0, 0.0,
                0.0, 1.0, 0.0, 0.0,
                0.0, 0.0, -0.5 * ph.cos() / cos2t2, -t2.tan() * ph.sin(),
                0.0, 0.0, -0.5 * ph.sin() / cos2t2, t2.tan() * ph.cos(),
            ],
        )
    }
}
<|endoftext|>


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

use interfaces::cef_command_line_t;

use libc::{calloc, c_int, c_char, size_t};
use std::ffi;
use std::mem;
use std::slice;
use std::str;
use string as cef_string;
use string::cef_string_utf16_set;
use types::{cef_string_t, cef_string_userfree_t, cef_string_utf16_t};

type command_line_t = command_line;
struct command_line {
    pub cl: cef_command_line_t,
    pub argc: c_int,
    pub argv: Vec<String>,
}

static mut GLOBAL_CMDLINE: Option<*mut command_line_t> = None;

fn command_line_new() -> *mut command_line_t {
    unsafe {
        let cl = calloc(1, mem::size_of::<command_line>() as size_t) as *mut command_line_t;
        (*cl).cl.base.size = mem::size_of::<cef_command_line_t>() as size_t;
        cl
    }
}

pub fn command_line_init(argc: c_int, argv: *const *const u8) {
    unsafe {
        let mut a: Vec<String> = vec!();
        for i in 0..(argc as usize) {
            let slice = ffi::CStr::from_ptr(*argv.offset(i as isize) as *const c_char);
            let s = str::from_utf8(slice.to_bytes()).unwrap();
            a.push(s.to_owned());
        }
        let cl = command_line_new();
        (*cl).argc = argc;
        (*cl).argv = a;
        (*cl).cl.get_switch_value = Some(command_line_get_switch_value as extern "C" fn(*mut cef_command_line_t, *const cef_string_t) -> cef_string_userfree_t);
        GLOBAL_CMDLINE = Some(cl);
    }
}

#[no_mangle]
pub extern "C" fn command_line_get_switch_value(cmd: *mut cef_command_line_t, name: *const cef_string_t) -> cef_string_userfree_t {
    if cmd.is_null() || name.is_null() {
        return cef_string::empty_utf16_userfree_string()
    }
    unsafe {
        //technically cef_string_t can be any type of character size
        //but the default cef callback uses utf16, so I'm jumping on board the SS Copy
        let cl: *mut command_line_t = mem::transmute(cmd);
        let cs: *const cef_string_utf16_t = mem::transmute(name);
        let buf = (*cs).str as *const _;
        let slice = slice::from_raw_parts(buf, (*cs).length as usize);
        let opt = String::from_utf16(slice).unwrap();
            //debug!("opt: {}", opt);
        for s in (*cl).argv.iter() {
            let o = s.trim_left_matches('-');
            //debug!("arg: {}", o);
            if o.starts_with(&opt) {
                let mut string = mem::uninitialized();
                let arg = o[opt.len() + 1..].as_bytes();
                let c_str = ffi::CString::new(arg).unwrap();
                cef_string_utf16_set(c_str.as_bytes().as_ptr() as *const _,
                                     arg.len() as size_t,
                                     &mut string,
                                     1);
                return cef_string::string_to_userfree_string(string)
            }
        }
    }
    return cef_string::empty_utf16_userfree_string()
}

#[no_mangle]
pub extern "C" fn cef_command_line_create() -> *mut cef_command_line_t {
        unsafe {
            let cl = command_line_new();
            (*cl).cl.get_switch_value = Some(command_line_get_switch_value as extern "C" fn(*mut cef_command_line_t, *const cef_string_t) -> cef_string_userfree_t);
            mem::transmute(cl)
        }
}

#[no_mangle]
pub extern "C" fn cef_command_line_get_global() -> *mut cef_command_line_t {
    unsafe {
        match GLOBAL_CMDLINE {
            Some(scl) => {
                mem::transmute(scl)
            },
            None => {
                0 as *mut cef_command_line_t
            }
        }
    }
}

cef_stub_static_method_impls! {
    fn cef_command_line_create_command_line() -> *mut cef_command_line_t
    fn cef_command_line_get_global_command_line() -> *mut cef_command_line_t
}

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

use interfaces::cef_command_line_t;

use libc::{calloc, c_int, c_char, size_t};
use std::ffi;
use std::mem;
use std::slice;
use std::str;
use string as cef_string;
use string::cef_string_utf16_set;
use types::{cef_string_t, cef_string_userfree_t, cef_string_utf16_t};

type command_line_t = command_line;
struct command_line {
    pub cl: cef_command_line_t,
    pub argc: c_int,
    pub argv: Vec<String>,
}

static mut GLOBAL_CMDLINE: Option<*mut command_line_t> = None;

fn command_line_new() -> *mut command_line_t {
    unsafe {
        let cl = calloc(1, mem::size_of::<command_line>() as size_t) as *mut command_line_t;
        (*cl).cl.base.size = mem::size_of::<cef_command_line_t>() as size_t;
        cl
    }
}

pub fn command_line_init(argc: c_int, argv: *const *const u8) {
    unsafe {
        let args = slice::from_raw_parts(argv, argc as usize);
        let a = args.iter().map(|&arg| {
            let slice = ffi::CStr::from_ptr(arg as *const c_char);
            str::from_utf8(slice.to_bytes()).unwrap().to_owned()
        }).collect();
        let cl = command_line_new();
        (*cl).argc = argc;
        (*cl).argv = a;
        (*cl).cl.get_switch_value = Some(command_line_get_switch_value as extern "C" fn(*mut cef_command_line_t, *const cef_string_t) -> cef_string_userfree_t);
        GLOBAL_CMDLINE = Some(cl);
    }
}

#[no_mangle]
pub extern "C" fn command_line_get_switch_value(cmd: *mut cef_command_line_t, name: *const cef_string_t) -> cef_string_userfree_t {
    if cmd.is_null() || name.is_null() {
        return cef_string::empty_utf16_userfree_string()
    }
    unsafe {
        //technically cef_string_t can be any type of character size
        //but the default cef callback uses utf16, so I'm jumping on board the SS Copy
        let cl: *mut command_line_t = mem::transmute(cmd);
        let cs: *const cef_string_utf16_t = mem::transmute(name);
        let buf = (*cs).str as *const _;
        let slice = slice::from_raw_parts(buf, (*cs).length as usize);
        let opt = String::from_utf16(slice).unwrap();
            //debug!("opt: {}", opt);
        for s in (*cl).argv.iter() {
            let o = s.trim_left_matches('-');
            //debug!("arg: {}", o);
            if o.starts_with(&opt) {
                let mut string = mem::uninitialized();
                let arg = o[opt.len() + 1..].as_bytes();
                let c_str = ffi::CString::new(arg).unwrap();
                cef_string_utf16_set(c_str.as_bytes().as_ptr() as *const _,
                                     arg.len() as size_t,
                                     &mut string,
                                     1);
                return cef_string::string_to_userfree_string(string)
            }
        }
    }
    return cef_string::empty_utf16_userfree_string()
}

#[no_mangle]
pub extern "C" fn cef_command_line_create() -> *mut cef_command_line_t {
        unsafe {
            let cl = command_line_new();
            (*cl).cl.get_switch_value = Some(command_line_get_switch_value as extern "C" fn(*mut cef_command_line_t, *const cef_string_t) -> cef_string_userfree_t);
            mem::transmute(cl)
        }
}

#[no_mangle]
pub extern "C" fn cef_command_line_get_global() -> *mut cef_command_line_t {
    unsafe {
        match GLOBAL_CMDLINE {
            Some(scl) => {
                mem::transmute(scl)
            },
            None => {
                0 as *mut cef_command_line_t
            }
        }
    }
}

cef_stub_static_method_impls! {
    fn cef_command_line_create_command_line() -> *mut cef_command_line_t
    fn cef_command_line_get_global_command_line() -> *mut cef_command_line_t
}

<|endoftext|>