<commit_before>extern crate cryt;
extern crate clap;
use clap::{App, Arg, SubCommand};
use std::io::{self, Read};

use cryt::criteria;
use cryt::encoding;
use cryt::xor;

fn main() {
    let matches = App::new("cryt")
                          .version("v0.1")
                          .author("Nicolas Schmidt <nfschmidt@gmail.com>")
                          .about("Cryptographic tools")
                          .subcommand(SubCommand::with_name("encode")
                                      .about("Encode input with the specified encoding")
                                      .subcommand(SubCommand::with_name("hex")
                                                  .about("Encode input in hex"))
                                      .subcommand(SubCommand::with_name("base64")
                                                  .about("Encode input in base64")))
                          .subcommand(SubCommand::with_name("decode")
                                      .about("Decode input with the specified encoding")
                                      .subcommand(SubCommand::with_name("hex")
                                                  .about("Decode input in hex"))
                                      .subcommand(SubCommand::with_name("base64")
                                                  .about("Decode input in base64")))
                          .subcommand(SubCommand::with_name("encrypt")
                                      .about("Encrypt input with the specified algorithm")
                                      .subcommand(SubCommand::with_name("xor")
                                                  .about("Encrypt using xor")
                                                  .arg(Arg::with_name("key")
                                                       .short("k")
                                                       .long("key")
                                                       .takes_value(true)
                                                       .required(true)
                                                       .help("xor key to be used"))))
                          .subcommand(SubCommand::with_name("encrypt")
                                      .about("Decrypt input with the specified algorithm")
                                      .subcommand(SubCommand::with_name("xor")
                                                  .about("Decrypt using xor")
                                                  .arg(Arg::with_name("key")
                                                       .short("k")
                                                       .long("key")
                                                       .takes_value(true)
                                                       .required(true)
                                                       .help("xor key to be used"))))
                          .subcommand(SubCommand::with_name("attack")
                                      .about("Attack the specified encryption algorithm to decrypt the input")
                                      .subcommand(SubCommand::with_name("xor")
                                                  .about("Attack xor encrypted input")
                                                  .arg(Arg::with_name("criterion")
                                                       .short("c")
                                                       .long("criterion")
                                                       .takes_value(true)
                                                       .possible_values(&["printable", "text"])
                                                       .help("criterion to be used for scoring the results"))
                                                  .arg(Arg::with_name("detailed")
                                                       .short("d")
                                                       .long("detailed")
                                                       .required(false)
                                                       .help("Print decrypted result, the key and the score for the selected criterion"))
                                                  .subcommand(SubCommand::with_name("keysize")
                                                              .about("Determine the keysize of a repeated xor encryption")
                                                              .arg(Arg::with_name("criterion")
                                                                   .help("Criterion to determine keysize")
                                                                   .short("c")
                                                                   .long("criterion")
                                                                   .takes_value(true)
                                                                   .possible_values(&["hamming-distance"])
                                                                   .required(false))
                                                              .arg(Arg::with_name("min")
                                                                   .help("Minimum keysize to try")
                                                                   .long("min")
                                                                   .takes_value(true)
                                                                   .required(false))
                                                              .arg(Arg::with_name("max")
                                                                   .help("Maximum keysize to try")
                                                                   .long("max")
                                                                   .short("m")
                                                                   .takes_value(true)
                                                                   .required(true)))
                                                  .subcommand(SubCommand::with_name("repeated")
                                                              .about("Attack repeated xor encrypted input")
                                                              .arg(Arg::with_name("keysize-criterion")
                                                                   .help("Criterion to determine keysize")
                                                                   .short("k")
                                                                   .long("keysize-criterion")
                                                                   .takes_value(true)
                                                                   .possible_values(&["hamming-distance"])
                                                                   .required(false))
                                                              .arg(Arg::with_name("criterion")
                                                                   .short("c")
                                                                   .long("criterion")
                                                                   .takes_value(true)
                                                                   .possible_values(&["printable", "text"])
                                                                   .help("criterion to be used for scoring the results"))
                                                              .arg(Arg::with_name("min")
                                                                   .help("Minimum keysize to try")
                                                                   .long("min")
                                                                   .takes_value(true)
                                                                   .required(false))
                                                              .arg(Arg::with_name("max")
                                                                   .help("Maximum keysize to try")
                                                                   .long("max")
                                                                   .short("m")
                                                                   .takes_value(true)
                                                                   .required(true)))))
                          .get_matches();

    if let Some(matches) = matches.subcommand_matches("encode") {
        if let Some(_) = matches.subcommand_matches("base64") {
            run_encode_base64();
        } else if let Some(_) = matches.subcommand_matches("hex") {
            run_encode_hex();
        }
    } else if let Some(matches) = matches.subcommand_matches("decode") {
        if let Some(_) = matches.subcommand_matches("base64") {
            run_decode_base64();
        } else if let Some(_) = matches.subcommand_matches("hex") {
            run_decode_hex();
        }
    } else if let Some(matches) = matches.subcommand_matches("encrypt") {
        if let Some(matches) = matches.subcommand_matches("xor") {
            match matches.value_of("key") {
                Some(k) => {
                    run_encrypt_xor(k);
                }
                None => {
                    println!("Error: No key received!");
                }
            }
        }
    } else if let Some(matches) = matches.subcommand_matches("attack") {
        if let Some(xor_matches) = matches.subcommand_matches("xor") {
            if let Some(keysize_matches) = xor_matches.subcommand_matches("keysize") {
                let criterion = match keysize_matches.value_of("criterion") {
                    Some("hamming-distance") => xor::hamming_distance_criterion,
                    Some(_) => xor::hamming_distance_criterion,
                    None => xor::hamming_distance_criterion
                };

                let min = match keysize_matches.value_of("min") {
                    Some(v) => v.parse::<u32>().unwrap(),
                    None => 1
                };

                let max = match keysize_matches.value_of("max") {
                    Some(v) => v.parse::<u32>().unwrap(),
                    None => 1
                };

                run_attack_xor_keysize(criterion, min, max);
                return;
            } else if let Some(repeated_matches) = xor_matches.subcommand_matches("repeated") {
                let xor_criterion = match repeated_matches.value_of("criterion") {
                    Some("printable") => criteria::printable_bytes,
                    Some("text") => criteria::text_bytes,
                    Some(_) => criteria::printable_bytes,
                    None => criteria::printable_bytes
                };

                let keysize_criterion = match repeated_matches.value_of("keysize-criterion") {
                    Some("hamming-distance") => xor::hamming_distance_criterion,
                    Some(_) => xor::hamming_distance_criterion,
                    None => xor::hamming_distance_criterion
                };

                let min = match repeated_matches.value_of("min") {
                    Some(v) => v.parse::<u32>().unwrap(),
                    None => 1
                };

                let max = match repeated_matches.value_of("max") {
                    Some(v) => v.parse::<u32>().unwrap(),
                    None => 1
                };

                run_attack_xor_repeated(keysize_criterion, min, max, xor_criterion);
                return;
            }

            let criterion = match xor_matches.value_of("criterion") {
                Some("printable") => criteria::printable_bytes,
                Some("text") => criteria::text_bytes,
                Some(_) => criteria::printable_bytes,
                None => criteria::printable_bytes
            };

            if xor_matches.is_present("detailed") {
                run_attack_xor_detailed(criterion);
            } else {
                run_attack_xor(criterion);
            }
        }
    } else {
        run_interpreter();
    }
}

fn run_encode_base64() {
    let result = encoding::base64_encode(io::stdin());
    print!("{}", result);
}

fn run_encode_hex() {
    let result = encoding::hex_encode(io::stdin());
    print!("{}", result);
}

fn run_decode_base64() {
    let mut input = String::new();
    match io::stdin().read_to_string(&mut input) {
        Ok(_) => {
            let result: String = encoding::base64_decode(&input)
                .into_iter()
                .map(|b| b as char)
                .collect();
            print!("{}", result);
        }
        Err(error) => { print!("Error: {}", error); }
    }
}

fn run_decode_hex() {
    let mut input = String::new();
    match io::stdin().read_to_string(&mut input) {
        Ok(_) => {
            let result: String = encoding::hex_decode(&input)
                .into_iter()
                .map(|b| b as char)
                .collect();
            print!("{}", result);
        }
        Err(error) => { println!("Error: {}", error); }
    }
}

fn run_encrypt_xor(key: &str) {
    let mut input = Vec::new();
    io::stdin().read_to_end(&mut input).unwrap();

    let result: String = xor::repeated_xor(&input, key.as_bytes())
        .into_iter()
        .map(|b| b as char)
        .collect();
    print!("{}", result);
}

fn run_attack_xor(criterion: fn(&Vec<u8>) -> f32) {
    let (_, _, decrypted) = xor::single_byte_decrypted(io::stdin(), criterion);
    let result: String = decrypted
        .into_iter()
        .map(|b| b as char)
        .collect();

    print!("{}", result);
}

fn run_attack_xor_detailed(criterion: fn(&Vec<u8>) -> f32) {
    let (key, score, decrypted) = xor::single_byte_decrypted(io::stdin(), criterion);
    let result: String = decrypted
        .into_iter()
        .map(|b| b as char)
        .collect();

    println!("Key: {}\tScore: {}\tResult: {}", key, score, result);
}

fn run_attack_xor_keysize(criterion: fn(&Vec<u8>, size: u32) -> f32, min: u32, max: u32) {
    let results = xor::repeated_xor_keysize(io::stdin(), min, max, criterion);

    for (size, score) in results {
        print!("Size: {}\tScore: {}", size, score);
    }
}

fn run_attack_xor_repeated(keysize_criterion: fn(&Vec<u8>, size: u32) -> f32, min: u32, max: u32, xor_criterion: fn(&Vec<u8>) -> f32) {
    let (key, decrypted) = xor::decrypted_repeated_xor(io::stdin(), min, max, keysize_criterion, xor_criterion);
    let key_string: String = key
        .into_iter()
        .map(|b| b as char)
        .collect();

    let decrypted_string: String = decrypted
        .into_iter()
        .map(|b| b as char)
        .collect();

    print!("Key: {}\nDecrypted:\n{}", key_string, decrypted_string);
}

fn run_interpreter() {
    println!("Interpreter");
}
<commit_msg>Simplified repeated xor input & output<commit_after>extern crate cryt;
extern crate clap;
use clap::{App, Arg, SubCommand};
use std::io::{self, Read, Write};

use cryt::criteria;
use cryt::encoding;
use cryt::xor;

fn main() {
    let matches = App::new("cryt")
                          .version("v0.1")
                          .author("Nicolas Schmidt <nfschmidt@gmail.com>")
                          .about("Cryptographic tools")
                          .subcommand(SubCommand::with_name("encode")
                                      .about("Encode input with the specified encoding")
                                      .subcommand(SubCommand::with_name("hex")
                                                  .about("Encode input in hex"))
                                      .subcommand(SubCommand::with_name("base64")
                                                  .about("Encode input in base64")))
                          .subcommand(SubCommand::with_name("decode")
                                      .about("Decode input with the specified encoding")
                                      .subcommand(SubCommand::with_name("hex")
                                                  .about("Decode input in hex"))
                                      .subcommand(SubCommand::with_name("base64")
                                                  .about("Decode input in base64")))
                          .subcommand(SubCommand::with_name("encrypt")
                                      .about("Encrypt input with the specified algorithm")
                                      .subcommand(SubCommand::with_name("xor")
                                                  .about("Encrypt using xor")
                                                  .arg(Arg::with_name("key")
                                                       .short("k")
                                                       .long("key")
                                                       .takes_value(true)
                                                       .required(true)
                                                       .help("xor key to be used"))))
                          .subcommand(SubCommand::with_name("encrypt")
                                      .about("Decrypt input with the specified algorithm")
                                      .subcommand(SubCommand::with_name("xor")
                                                  .about("Decrypt using xor")
                                                  .arg(Arg::with_name("key")
                                                       .short("k")
                                                       .long("key")
                                                       .takes_value(true)
                                                       .required(true)
                                                       .help("xor key to be used"))))
                          .subcommand(SubCommand::with_name("attack")
                                      .about("Attack the specified encryption algorithm to decrypt the input")
                                      .subcommand(SubCommand::with_name("xor")
                                                  .about("Attack xor encrypted input")
                                                  .arg(Arg::with_name("criterion")
                                                       .short("c")
                                                       .long("criterion")
                                                       .takes_value(true)
                                                       .possible_values(&["printable", "text"])
                                                       .help("criterion to be used for scoring the results"))
                                                  .arg(Arg::with_name("detailed")
                                                       .short("d")
                                                       .long("detailed")
                                                       .required(false)
                                                       .help("Print decrypted result, the key and the score for the selected criterion"))
                                                  .subcommand(SubCommand::with_name("keysize")
                                                              .about("Determine the keysize of a repeated xor encryption")
                                                              .arg(Arg::with_name("criterion")
                                                                   .help("Criterion to determine keysize")
                                                                   .short("c")
                                                                   .long("criterion")
                                                                   .takes_value(true)
                                                                   .possible_values(&["hamming-distance"])
                                                                   .required(false))
                                                              .arg(Arg::with_name("min")
                                                                   .help("Minimum keysize to try")
                                                                   .long("min")
                                                                   .takes_value(true)
                                                                   .required(false))
                                                              .arg(Arg::with_name("max")
                                                                   .help("Maximum keysize to try")
                                                                   .long("max")
                                                                   .short("m")
                                                                   .takes_value(true)
                                                                   .required(true)))
                                                  .subcommand(SubCommand::with_name("repeated")
                                                              .about("Attack repeated xor encrypted input")
                                                              .arg(Arg::with_name("keysize-criterion")
                                                                   .help("Criterion to determine keysize")
                                                                   .short("k")
                                                                   .long("keysize-criterion")
                                                                   .takes_value(true)
                                                                   .possible_values(&["hamming-distance"])
                                                                   .required(false))
                                                              .arg(Arg::with_name("criterion")
                                                                   .short("c")
                                                                   .long("criterion")
                                                                   .takes_value(true)
                                                                   .possible_values(&["printable", "text"])
                                                                   .help("criterion to be used for scoring the results"))
                                                              .arg(Arg::with_name("min")
                                                                   .help("Minimum keysize to try")
                                                                   .long("min")
                                                                   .takes_value(true)
                                                                   .required(false))
                                                              .arg(Arg::with_name("max")
                                                                   .help("Maximum keysize to try")
                                                                   .long("max")
                                                                   .short("m")
                                                                   .takes_value(true)
                                                                   .required(true)))))
                          .get_matches();

    if let Some(matches) = matches.subcommand_matches("encode") {
        if let Some(_) = matches.subcommand_matches("base64") {
            run_encode_base64();
        } else if let Some(_) = matches.subcommand_matches("hex") {
            run_encode_hex();
        }
    } else if let Some(matches) = matches.subcommand_matches("decode") {
        if let Some(_) = matches.subcommand_matches("base64") {
            run_decode_base64();
        } else if let Some(_) = matches.subcommand_matches("hex") {
            run_decode_hex();
        }
    } else if let Some(matches) = matches.subcommand_matches("encrypt") {
        if let Some(matches) = matches.subcommand_matches("xor") {
            match matches.value_of("key") {
                Some(k) => {
                    run_encrypt_xor(k);
                }
                None => {
                    println!("Error: No key received!");
                }
            }
        }
    } else if let Some(matches) = matches.subcommand_matches("attack") {
        if let Some(xor_matches) = matches.subcommand_matches("xor") {
            if let Some(keysize_matches) = xor_matches.subcommand_matches("keysize") {
                let criterion = match keysize_matches.value_of("criterion") {
                    Some("hamming-distance") => xor::hamming_distance_criterion,
                    Some(_) => xor::hamming_distance_criterion,
                    None => xor::hamming_distance_criterion
                };

                let min = match keysize_matches.value_of("min") {
                    Some(v) => v.parse::<u32>().unwrap(),
                    None => 1
                };

                let max = match keysize_matches.value_of("max") {
                    Some(v) => v.parse::<u32>().unwrap(),
                    None => 1
                };

                run_attack_xor_keysize(criterion, min, max);
                return;
            } else if let Some(repeated_matches) = xor_matches.subcommand_matches("repeated") {
                let xor_criterion = match repeated_matches.value_of("criterion") {
                    Some("printable") => criteria::printable_bytes,
                    Some("text") => criteria::text_bytes,
                    Some(_) => criteria::printable_bytes,
                    None => criteria::printable_bytes
                };

                let keysize_criterion = match repeated_matches.value_of("keysize-criterion") {
                    Some("hamming-distance") => xor::hamming_distance_criterion,
                    Some(_) => xor::hamming_distance_criterion,
                    None => xor::hamming_distance_criterion
                };

                let min = match repeated_matches.value_of("min") {
                    Some(v) => v.parse::<u32>().unwrap(),
                    None => 1
                };

                let max = match repeated_matches.value_of("max") {
                    Some(v) => v.parse::<u32>().unwrap(),
                    None => 1
                };

                run_attack_xor_repeated(keysize_criterion, min, max, xor_criterion);
                return;
            }

            let criterion = match xor_matches.value_of("criterion") {
                Some("printable") => criteria::printable_bytes,
                Some("text") => criteria::text_bytes,
                Some(_) => criteria::printable_bytes,
                None => criteria::printable_bytes
            };

            if xor_matches.is_present("detailed") {
                run_attack_xor_detailed(criterion);
            } else {
                run_attack_xor(criterion);
            }
        }
    } else {
        run_interpreter();
    }
}

fn run_encode_base64() {
    let result = encoding::base64_encode(io::stdin());
    print!("{}", result);
}

fn run_encode_hex() {
    let result = encoding::hex_encode(io::stdin());
    print!("{}", result);
}

fn run_decode_base64() {
    let mut input = String::new();
    match io::stdin().read_to_string(&mut input) {
        Ok(_) => {
            let result: String = encoding::base64_decode(&input)
                .into_iter()
                .map(|b| b as char)
                .collect();
            print!("{}", result);
        }
        Err(error) => { print!("Error: {}", error); }
    }
}

fn run_decode_hex() {
    let mut input = String::new();
    match io::stdin().read_to_string(&mut input) {
        Ok(_) => {
            let result: String = encoding::hex_decode(&input)
                .into_iter()
                .map(|b| b as char)
                .collect();
            print!("{}", result);
        }
        Err(error) => { println!("Error: {}", error); }
    }
}

fn run_encrypt_xor(key: &str) {
    let mut input = Vec::new();
    io::stdin().read_to_end(&mut input).unwrap();

    let result = xor::repeated_xor(&input, key.as_bytes());
    io::stdout().write(&result).unwrap();
}

fn run_attack_xor(criterion: fn(&Vec<u8>) -> f32) {
    let (_, _, decrypted) = xor::single_byte_decrypted(io::stdin(), criterion);
    let result: String = decrypted
        .into_iter()
        .map(|b| b as char)
        .collect();

    print!("{}", result);
}

fn run_attack_xor_detailed(criterion: fn(&Vec<u8>) -> f32) {
    let (key, score, decrypted) = xor::single_byte_decrypted(io::stdin(), criterion);
    let result: String = decrypted
        .into_iter()
        .map(|b| b as char)
        .collect();

    println!("Key: {}\tScore: {}\tResult: {}", key, score, result);
}

fn run_attack_xor_keysize(criterion: fn(&Vec<u8>, size: u32) -> f32, min: u32, max: u32) {
    let results = xor::repeated_xor_keysize(io::stdin(), min, max, criterion);

    for (size, score) in results {
        print!("Size: {}\tScore: {}", size, score);
    }
}

fn run_attack_xor_repeated(keysize_criterion: fn(&Vec<u8>, size: u32) -> f32, min: u32, max: u32, xor_criterion: fn(&Vec<u8>) -> f32) {
    let (key, decrypted) = xor::decrypted_repeated_xor(io::stdin(), min, max, keysize_criterion, xor_criterion);
    let key_string: String = key
        .into_iter()
        .map(|b| b as char)
        .collect();

    let decrypted_string: String = decrypted
        .into_iter()
        .map(|b| b as char)
        .collect();

    print!("Key: {}\nDecrypted:\n{}", key_string, decrypted_string);
}

fn run_interpreter() {
    println!("Interpreter");
}
<|endoftext|>


<commit_before>extern crate bitboard;
extern crate heuristic;
extern crate rand;

mod negamax_ab_timeout;
mod mtdf_id_timeout;
mod transposition;
mod search;
//mod monte_carlo;
mod pvs;

pub use negamax_ab_timeout::NegamaxSearch;
pub use mtdf_id_timeout::{mtdf_timeout, mtdf_id_timeout};
pub use transposition::TranspositionTable;
pub use pvs::pvs;
pub use pvs::pvs_id;
pub use search::Search;
pub use search::SearchInfo;

#[cfg(test)]
mod tests {
    extern crate rand;
    use heuristic::BasicHeuristic;
    use bitboard::Board;
    use bitboard::Move;
    use bitboard::empty_movelist;

    use ::mtdf_id_timeout;
    use ::TranspositionTable;
    use std::time::Instant;

    use self::rand::Rng;
    #[test]
    fn it_works() {
    }

    #[test]
    fn negamax_mtdf_consistency() {
        let mut b = Board::new();

        let m = mtdf_id_timeout(b, Box::new(BasicHeuristic::new()), 34, 10000);

        println!("Move: {}", m);
    }

    #[test]
    fn monte_carlo_test() {

    }
}
<commit_msg>PVS test<commit_after>extern crate bitboard;
extern crate heuristic;
extern crate rand;

mod negamax_ab_timeout;
mod mtdf_id_timeout;
mod transposition;
mod search;
//mod monte_carlo;
mod pvs;

pub use negamax_ab_timeout::NegamaxSearch;
pub use mtdf_id_timeout::{mtdf_timeout, mtdf_id_timeout};
pub use transposition::TranspositionTable;
pub use pvs::pvs;
pub use pvs::pvs_id;
pub use search::Search;
pub use search::SearchInfo;

#[cfg(test)]
mod tests {
    extern crate rand;
    use heuristic::BasicHeuristic;
    use bitboard::Board;
    use bitboard::Move;
    use bitboard::empty_movelist;

    use ::mtdf_id_timeout;
    use ::pvs_id;
    use ::TranspositionTable;
    use std::time::Instant;

    use self::rand::Rng;
    #[test]
    fn it_works() {
    }

    #[test]
    fn negamax_mtdf_consistency() {
        let mut b = Board::new();

        //let m = mtdf_id_timeout(b, Box::new(BasicHeuristic::new()), 34, 10000);

        //println!("Move: {}", m);
    }

    #[test]
    fn monte_carlo_test() {

    }

    #[test]
    fn pvs_test() {
        use heuristic::HandmadeHeuristic;
        use heuristic::ScaledBasicHeuristic;

        let tmp = Box::new(ScaledBasicHeuristic::new(10));
        let mut tmp_hr = [
            tmp.clone(), tmp.clone(), tmp.clone(), tmp.clone(), tmp.clone(),
            tmp.clone(), tmp.clone(), tmp.clone(), tmp.clone(), tmp.clone(),
            tmp.clone(), tmp.clone(), tmp.clone(), tmp.clone(), tmp.clone(),
            tmp.clone(), tmp.clone(), tmp.clone(), tmp.clone(), tmp.clone()
        ];

        let b1 = Board::from_string(
            // Vec::from("BWWWWBBB\nBWBBWBBB\nBBBWWB B\nBWBBWB  \nBWBBWB  \nBWWWWBBB\nBWWWWBBB\nBBBBBBB \n")
            Vec::from(" WWWWWW \nWWWBWW W\nWWWWBWWW\nWWWWBWWW\nWWWWWWWW\nWWWWBWWW\n BBBWW W\n WWWWW  \n")
        );

        let mut out_move = pvs_id(b1, &mut tmp_hr, &mut ScaledBasicHeuristic::new(10_000), 9, 1000);

        println!("BEST MOVE: {} FOR \n{}", out_move, b1);
    }
}
<|endoftext|>


<commit_before>//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//!   used for IPC within the Servo rendering engine.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//!   size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//!   language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [RON], a Rusty Object Notation.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
//!   definition.
//! - [Hjson], a variant of JSON designed to be readable and writable by humans.
//! - [JSON5], A superset of JSON including some productions from ES5.
//! - [URL], the x-www-form-urlencoded format.
//! - [Envy], a way to deserialize environment variables into Rust structs.
//!   *(deserialization only)*
//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
//!   Rust structs. *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [RON]: https://github.com/ron-rs/ron
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [Avro]: https://github.com/flavray/avro-rs
//! [Hjson]: https://github.com/laktak/hjson-rust
//! [JSON5]: https://github.com/callum-oakley/json5-rs
//! [URL]: https://github.com/nox/serde_urlencoded
//! [Envy]: https://github.com/softprops/envy
//! [Envy Store]: https://github.com/softprops/envy-store
//! [Cargo]: http://doc.crates.io/manifest.html
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html

////////////////////////////////////////////////////////////////////////////////

// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.85")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
//    https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Ignored clippy lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        cast_lossless,
        const_static_lifetime,
        doc_markdown,
        linkedlist,
        needless_pass_by_value,
        redundant_field_names,
        type_complexity,
        unreadable_literal,
        zero_prefixed_literal
    )
)]
// Ignored clippy_pedantic lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        // integer and float ser/de requires these sorts of casts
        cast_possible_truncation,
        cast_possible_wrap,
        cast_precision_loss,
        cast_sign_loss,
        // simplifies some macros
        invalid_upcast_comparisons,
        // things are often more readable this way
        decimal_literal_representation,
        module_name_repetitions,
        option_unwrap_used,
        result_unwrap_used,
        shadow_reuse,
        single_match_else,
        use_self,
        // not practical
        indexing_slicing,
        many_single_char_names,
        missing_docs_in_private_items,
        similar_names,
        // alternative is not stable
        empty_enum,
        use_debug,
    )
)]
// Blacklisted Rust lints.
//
// Compiler bug involving unused_imports:
// https://github.com/rust-lang/rust/issues/51661
#![deny(missing_docs, /*unused_imports*/)]

////////////////////////////////////////////////////////////////////////////////

#[cfg(feature = "alloc")]
extern crate alloc;

/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
    mod core {
        #[cfg(not(feature = "std"))]
        pub use core::*;
        #[cfg(feature = "std")]
        pub use std::*;
    }

    pub use self::core::{cmp, iter, mem, num, slice, str};
    pub use self::core::{f32, f64};
    pub use self::core::{i16, i32, i64, i8, isize};
    pub use self::core::{u16, u32, u64, u8, usize};

    pub use self::core::cell::{Cell, RefCell};
    pub use self::core::clone::{self, Clone};
    pub use self::core::convert::{self, From, Into};
    pub use self::core::default::{self, Default};
    pub use self::core::fmt::{self, Debug, Display};
    pub use self::core::marker::{self, PhantomData};
    pub use self::core::ops::Range;
    pub use self::core::option::{self, Option};
    pub use self::core::result::{self, Result};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::borrow::{Cow, ToOwned};
    #[cfg(feature = "std")]
    pub use std::borrow::{Cow, ToOwned};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::string::{String, ToString};
    #[cfg(feature = "std")]
    pub use std::string::String;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::vec::Vec;
    #[cfg(feature = "std")]
    pub use std::vec::Vec;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::boxed::Box;
    #[cfg(feature = "std")]
    pub use std::boxed::Box;

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::rc::{Rc, Weak as RcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::rc::{Rc, Weak as RcWeak};

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::sync::{Arc, Weak as ArcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::sync::{Arc, Weak as ArcWeak};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
    #[cfg(feature = "std")]
    pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};

    #[cfg(feature = "std")]
    pub use std::{error, net};

    #[cfg(feature = "std")]
    pub use std::collections::{HashMap, HashSet};
    #[cfg(feature = "std")]
    pub use std::ffi::{CStr, CString, OsStr, OsString};
    #[cfg(feature = "std")]
    pub use std::hash::{BuildHasher, Hash};
    #[cfg(feature = "std")]
    pub use std::io::Write;
    #[cfg(feature = "std")]
    pub use std::num::Wrapping;
    #[cfg(feature = "std")]
    pub use std::path::{Path, PathBuf};
    #[cfg(feature = "std")]
    pub use std::sync::{Mutex, RwLock};
    #[cfg(feature = "std")]
    pub use std::time::{SystemTime, UNIX_EPOCH};

    #[cfg(any(core_duration, feature = "std"))]
    pub use self::core::time::Duration;

    #[cfg(range_inclusive)]
    pub use self::core::ops::RangeInclusive;
}

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
mod macros;

#[macro_use]
mod integer128;

pub mod de;
pub mod ser;

#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[doc(inline)]
pub use ser::{Serialize, Serializer};

// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;

// Re-export #[derive(Serialize, Deserialize)].
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
<commit_msg>Remove clippy lints that are no longer triggering<commit_after>//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//!   used for IPC within the Servo rendering engine.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//!   size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//!   language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [RON], a Rusty Object Notation.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
//!   definition.
//! - [Hjson], a variant of JSON designed to be readable and writable by humans.
//! - [JSON5], A superset of JSON including some productions from ES5.
//! - [URL], the x-www-form-urlencoded format.
//! - [Envy], a way to deserialize environment variables into Rust structs.
//!   *(deserialization only)*
//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
//!   Rust structs. *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [RON]: https://github.com/ron-rs/ron
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [Avro]: https://github.com/flavray/avro-rs
//! [Hjson]: https://github.com/laktak/hjson-rust
//! [JSON5]: https://github.com/callum-oakley/json5-rs
//! [URL]: https://github.com/nox/serde_urlencoded
//! [Envy]: https://github.com/softprops/envy
//! [Envy Store]: https://github.com/softprops/envy-store
//! [Cargo]: http://doc.crates.io/manifest.html
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html

////////////////////////////////////////////////////////////////////////////////

// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.85")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
//    https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Ignored clippy lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        cast_lossless,
        const_static_lifetime,
        doc_markdown,
        needless_pass_by_value,
        redundant_field_names,
        type_complexity,
        zero_prefixed_literal
    )
)]
// Ignored clippy_pedantic lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        // integer and float ser/de requires these sorts of casts
        cast_possible_truncation,
        cast_possible_wrap,
        cast_precision_loss,
        cast_sign_loss,
        // things are often more readable this way
        module_name_repetitions,
        single_match_else,
        use_self,
        // not practical
        similar_names,
        // alternative is not stable
        empty_enum,
    )
)]
// Blacklisted Rust lints.
//
// Compiler bug involving unused_imports:
// https://github.com/rust-lang/rust/issues/51661
#![deny(missing_docs, /*unused_imports*/)]

////////////////////////////////////////////////////////////////////////////////

#[cfg(feature = "alloc")]
extern crate alloc;

/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
    mod core {
        #[cfg(not(feature = "std"))]
        pub use core::*;
        #[cfg(feature = "std")]
        pub use std::*;
    }

    pub use self::core::{cmp, iter, mem, num, slice, str};
    pub use self::core::{f32, f64};
    pub use self::core::{i16, i32, i64, i8, isize};
    pub use self::core::{u16, u32, u64, u8, usize};

    pub use self::core::cell::{Cell, RefCell};
    pub use self::core::clone::{self, Clone};
    pub use self::core::convert::{self, From, Into};
    pub use self::core::default::{self, Default};
    pub use self::core::fmt::{self, Debug, Display};
    pub use self::core::marker::{self, PhantomData};
    pub use self::core::ops::Range;
    pub use self::core::option::{self, Option};
    pub use self::core::result::{self, Result};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::borrow::{Cow, ToOwned};
    #[cfg(feature = "std")]
    pub use std::borrow::{Cow, ToOwned};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::string::{String, ToString};
    #[cfg(feature = "std")]
    pub use std::string::String;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::vec::Vec;
    #[cfg(feature = "std")]
    pub use std::vec::Vec;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::boxed::Box;
    #[cfg(feature = "std")]
    pub use std::boxed::Box;

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::rc::{Rc, Weak as RcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::rc::{Rc, Weak as RcWeak};

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::sync::{Arc, Weak as ArcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::sync::{Arc, Weak as ArcWeak};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
    #[cfg(feature = "std")]
    pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};

    #[cfg(feature = "std")]
    pub use std::{error, net};

    #[cfg(feature = "std")]
    pub use std::collections::{HashMap, HashSet};
    #[cfg(feature = "std")]
    pub use std::ffi::{CStr, CString, OsStr, OsString};
    #[cfg(feature = "std")]
    pub use std::hash::{BuildHasher, Hash};
    #[cfg(feature = "std")]
    pub use std::io::Write;
    #[cfg(feature = "std")]
    pub use std::num::Wrapping;
    #[cfg(feature = "std")]
    pub use std::path::{Path, PathBuf};
    #[cfg(feature = "std")]
    pub use std::sync::{Mutex, RwLock};
    #[cfg(feature = "std")]
    pub use std::time::{SystemTime, UNIX_EPOCH};

    #[cfg(any(core_duration, feature = "std"))]
    pub use self::core::time::Duration;

    #[cfg(range_inclusive)]
    pub use self::core::ops::RangeInclusive;
}

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
mod macros;

#[macro_use]
mod integer128;

pub mod de;
pub mod ser;

#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[doc(inline)]
pub use ser::{Serialize, Serializer};

// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;

// Re-export #[derive(Serialize, Deserialize)].
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
<|endoftext|>


<commit_before>//
// Sysinfo
//
// Copyright (c) 2017 Guillaume Gomez
//

#[test]
fn test_disks() {
    use sysinfo::SystemExt;

    if sysinfo::System::IS_SUPPORTED {
        let s = sysinfo::System::new_all();
        assert!(!s.disks().is_empty());
    }
}
<commit_msg>Update disk test<commit_after>//
// Sysinfo
//
// Copyright (c) 2017 Guillaume Gomez
//

#[test]
fn test_disks() {
    use sysinfo::SystemExt;

    if sysinfo::System::IS_SUPPORTED {
        let s = sysinfo::System::new_all();
        // If we don't have any physical core present, it's very likely that we're inside a VM...
        if s.physical_core_count().unwrap_or_default() > 0 {
            assert!(!s.disks().is_empty());
        }
    }
}
<|endoftext|>


<commit_before>extern crate ctest;

use std::env;

fn main() {
    let target = env::var("TARGET").unwrap();
    let windows = target.contains("windows");
    let mingw = target.contains("windows-gnu");
    let mut cfg = ctest::TestGenerator::new();

    // Pull in extra goodies on linux/mingw
    if target.contains("unknown-linux-gnu") {
        cfg.define("_GNU_SOURCE", None);
    } else if target.contains("windows") {
        cfg.define("_WIN32_WINNT", Some("0x8000"));
    }

    cfg.header("errno.h")
       .header("fcntl.h")
       .header("limits.h")
       .header("stddef.h")
       .header("stdint.h")
       .header("stdio.h")
       .header("stdlib.h")
       .header("sys/stat.h")
       .header("sys/types.h")
       .header("time.h")
       .header("wchar.h");

    if target.contains("apple-darwin") {
        cfg.header("mach-o/dyld.h");
        cfg.header("mach/mach_time.h");
    } else if target.contains("unknown-linux") ||
              target.contains("android") {
        cfg.header("linux/if_packet.h");
        cfg.header("net/ethernet.h");
    }

    if target.contains("windows") {
        cfg.header("winsock2.h"); // must be before windows.h

        cfg.header("direct.h");
        cfg.header("io.h");
        cfg.header("sys/utime.h");
        cfg.header("windows.h");
        cfg.header("process.h");
        cfg.header("ws2ipdef.h");

        if target.contains("gnu") {
            cfg.header("ws2tcpip.h");
        }
    } else {
        cfg.header("ctype.h");
        cfg.header("dirent.h");
        cfg.header("net/if.h");
        cfg.header("netdb.h");
        cfg.header("netinet/in.h");
        cfg.header("netinet/ip.h");
        cfg.header("netinet/tcp.h");
        cfg.header("pthread.h");
        cfg.header("signal.h");
        cfg.header("string.h");
        cfg.header("sys/file.h");
        cfg.header("sys/ioctl.h");
        cfg.header("sys/mman.h");
        cfg.header("sys/resource.h");
        cfg.header("sys/socket.h");
        cfg.header("sys/time.h");
        cfg.header("sys/un.h");
        cfg.header("sys/wait.h");
        cfg.header("unistd.h");
        cfg.header("utime.h");

        if target.contains("android") {
            cfg.header("arpa/inet.h");
        } else {
            cfg.header("glob.h");
            cfg.header("ifaddrs.h");
            cfg.header("sys/sysctl.h");
        }
    }

    cfg.type_name(move |ty, is_struct| {
        match ty {
            // Just pass all these through, no need for a "struct" prefix
            "glob_t" |
            "FILE" |
            "DIR" |
            "fpos_t" => ty.to_string(),
            t if t.starts_with("pthread") => t.to_string(),

            // Windows uppercase structs don't have `struct` in front, there's a
            // few special cases for windows, and then otherwise put `struct` in
            // front of everything.
            t if is_struct => {
                if windows && ty.chars().next().unwrap().is_uppercase() {
                    t.to_string()
                } else if windows && t == "stat" {
                    "struct __stat64".to_string()
                } else if windows && t == "utimbuf" {
                    "struct __utimbuf64".to_string()
                } else {
                    format!("struct {}", t)
                }
            }

            // Fixup a few types on windows that don't actually exist.
            "time64_t" if windows => "__time64_t".to_string(),
            "ssize_t" if windows => "SSIZE_T".to_string(),

            t => t.to_string(),
        }
    });

    let target2 = target.clone();
    cfg.field_name(move |struct_, field| {
        match field {
            // Our stat *_nsec fields normally don't actually exist but are part
            // of a timeval struct
            s if s.ends_with("_nsec") && struct_ == "stat" => {
                if target2.contains("apple-darwin") {
                    s.replace("_nsec", "spec.tv_nsec")
                } else if target2.contains("android") {
                    s.to_string()
                } else {
                    s.replace("e_nsec", ".tv_nsec")
                }
            }
            s => s.to_string(),
        }
    });

    let target2 = target.clone();
    cfg.skip_type(move |ty| {
        match ty {
            // sighandler_t is crazy across platforms
            "sighandler_t" => true,

            // Not actually defined on android, but it's not hurting anyone
            "in_port_t" if target2.contains("android") => true,
            _ => false
        }
    });

    cfg.skip_signededness(|c| {
        match c {
            "LARGE_INTEGER" |
            "mach_timebase_info_data_t" |
            "float" |
            "double" => true,
            n if n.starts_with("pthread") => true,

            // windows-isms
            n if n.starts_with("P") => true,
            n if n.starts_with("H") => true,
            n if n.starts_with("LP") => true,
            _ => false,
        }
    });

    // Apparently these don't exist in mingw headers?
    cfg.skip_const(move |name| {
        match name {
            "MEM_RESET_UNDO" |
            "FILE_ATTRIBUTE_NO_SCRUB_DATA" |
            "FILE_ATTRIBUTE_INTEGRITY_STREAM" |
            "ERROR_NOTHING_TO_TERMINATE" if mingw => true,
            "SIG_IGN" => true, // sighandler_t weirdness
            _ => false,
        }
    });

    cfg.skip_fn(|name| {
        match name {
            // manually verified
            "execv" |
            "execve" |
            "execvp" |
            "execvpe" |
            "glob" |
            "getrlimit" |
            "setrlimit" |
            "signal" |
            "getopt" => true,
            _ => false,
        }
    });

    cfg.generate("../src/lib.rs", "all.rs");
}
<commit_msg>Skip the pointer check for functions on windows<commit_after>extern crate ctest;

use std::env;

fn main() {
    let target = env::var("TARGET").unwrap();
    let windows = target.contains("windows");
    let mingw = target.contains("windows-gnu");
    let mut cfg = ctest::TestGenerator::new();

    // Pull in extra goodies on linux/mingw
    if target.contains("unknown-linux-gnu") {
        cfg.define("_GNU_SOURCE", None);
    } else if target.contains("windows") {
        cfg.define("_WIN32_WINNT", Some("0x8000"));
    }

    cfg.header("errno.h")
       .header("fcntl.h")
       .header("limits.h")
       .header("stddef.h")
       .header("stdint.h")
       .header("stdio.h")
       .header("stdlib.h")
       .header("sys/stat.h")
       .header("sys/types.h")
       .header("time.h")
       .header("wchar.h");

    if target.contains("apple-darwin") {
        cfg.header("mach-o/dyld.h");
        cfg.header("mach/mach_time.h");
    } else if target.contains("unknown-linux") ||
              target.contains("android") {
        cfg.header("linux/if_packet.h");
        cfg.header("net/ethernet.h");
    }

    if target.contains("windows") {
        cfg.header("winsock2.h"); // must be before windows.h

        cfg.header("direct.h");
        cfg.header("io.h");
        cfg.header("sys/utime.h");
        cfg.header("windows.h");
        cfg.header("process.h");
        cfg.header("ws2ipdef.h");

        if target.contains("gnu") {
            cfg.header("ws2tcpip.h");
        }
    } else {
        cfg.header("ctype.h");
        cfg.header("dirent.h");
        cfg.header("net/if.h");
        cfg.header("netdb.h");
        cfg.header("netinet/in.h");
        cfg.header("netinet/ip.h");
        cfg.header("netinet/tcp.h");
        cfg.header("pthread.h");
        cfg.header("signal.h");
        cfg.header("string.h");
        cfg.header("sys/file.h");
        cfg.header("sys/ioctl.h");
        cfg.header("sys/mman.h");
        cfg.header("sys/resource.h");
        cfg.header("sys/socket.h");
        cfg.header("sys/time.h");
        cfg.header("sys/un.h");
        cfg.header("sys/wait.h");
        cfg.header("unistd.h");
        cfg.header("utime.h");

        if target.contains("android") {
            cfg.header("arpa/inet.h");
        } else {
            cfg.header("glob.h");
            cfg.header("ifaddrs.h");
            cfg.header("sys/sysctl.h");
        }
    }

    cfg.type_name(move |ty, is_struct| {
        match ty {
            // Just pass all these through, no need for a "struct" prefix
            "glob_t" |
            "FILE" |
            "DIR" |
            "fpos_t" => ty.to_string(),
            t if t.starts_with("pthread") => t.to_string(),

            // Windows uppercase structs don't have `struct` in front, there's a
            // few special cases for windows, and then otherwise put `struct` in
            // front of everything.
            t if is_struct => {
                if windows && ty.chars().next().unwrap().is_uppercase() {
                    t.to_string()
                } else if windows && t == "stat" {
                    "struct __stat64".to_string()
                } else if windows && t == "utimbuf" {
                    "struct __utimbuf64".to_string()
                } else {
                    format!("struct {}", t)
                }
            }

            // Fixup a few types on windows that don't actually exist.
            "time64_t" if windows => "__time64_t".to_string(),
            "ssize_t" if windows => "SSIZE_T".to_string(),

            t => t.to_string(),
        }
    });

    let target2 = target.clone();
    cfg.field_name(move |struct_, field| {
        match field {
            // Our stat *_nsec fields normally don't actually exist but are part
            // of a timeval struct
            s if s.ends_with("_nsec") && struct_ == "stat" => {
                if target2.contains("apple-darwin") {
                    s.replace("_nsec", "spec.tv_nsec")
                } else if target2.contains("android") {
                    s.to_string()
                } else {
                    s.replace("e_nsec", ".tv_nsec")
                }
            }
            s => s.to_string(),
        }
    });

    let target2 = target.clone();
    cfg.skip_type(move |ty| {
        match ty {
            // sighandler_t is crazy across platforms
            "sighandler_t" => true,

            // Not actually defined on android, but it's not hurting anyone
            "in_port_t" if target2.contains("android") => true,
            _ => false
        }
    });

    cfg.skip_signededness(|c| {
        match c {
            "LARGE_INTEGER" |
            "mach_timebase_info_data_t" |
            "float" |
            "double" => true,
            n if n.starts_with("pthread") => true,

            // windows-isms
            n if n.starts_with("P") => true,
            n if n.starts_with("H") => true,
            n if n.starts_with("LP") => true,
            _ => false,
        }
    });

    // Apparently these don't exist in mingw headers?
    cfg.skip_const(move |name| {
        match name {
            "MEM_RESET_UNDO" |
            "FILE_ATTRIBUTE_NO_SCRUB_DATA" |
            "FILE_ATTRIBUTE_INTEGRITY_STREAM" |
            "ERROR_NOTHING_TO_TERMINATE" if mingw => true,
            "SIG_IGN" => true, // sighandler_t weirdness
            _ => false,
        }
    });

    cfg.skip_fn(|name| {
        match name {
            // manually verified
            "execv" |
            "execve" |
            "execvp" |
            "execvpe" |
            "glob" |
            "getrlimit" |
            "setrlimit" |
            "signal" |
            "getopt" => true,
            _ => false,
        }
    });

    // Windows dllimport oddness?
    cfg.skip_fn_ptrcheck(move |_| windows);

    cfg.generate("../src/lib.rs", "all.rs");
}
<|endoftext|>


<commit_before>extern mod euler;

use euler::prime::{ Prime, sum_of_proper_divisors };

fn main() {
    let max_idx = 28123;
    let p = Prime();

    let abundant = {
        let dv = dvec::DVec();
        dv.reserve(max_idx + 1);
        for uint::range(2, max_idx + 1) |i| {
            let sum = sum_of_proper_divisors(i, &p);
            if sum > i {
                dv.push(i)
            }
        }
        dvec::unwrap(dv)
    };

    let sum_of_abundant = {
        let mut sum = 0;
        let v = vec::to_mut(vec::from_elem(max_idx + 1,  false));
        for abundant.eachi |i, ai| {
            for vec::view(abundant, i, abundant.len()).each |aj| {
                let s = *ai + *aj;
                if s > max_idx { break; }
                if !v[s] { sum += s }
                v[s] = true;
            }
        }
        sum
    };

    io::println(fmt!("%u", sum_of_abundant));
}<commit_msg>Fix problem #23 breakage<commit_after>extern mod euler;

use euler::prime::{ Prime, sum_of_proper_divisors };

fn main() {
    let max_num = 28123;
    let p = Prime();

    let abundant = {
        let dv = dvec::DVec();
        dv.reserve(max_num + 1);
        for uint::range(2, max_num + 1) |i| {
            let sum = sum_of_proper_divisors(i, &p);
            if sum > i { dv.push(i) }
        }
        dvec::unwrap(dv)
    };

    let sum_of_abundant = {
        let mut sum = 0;
        let v = vec::to_mut(vec::from_elem(max_num + 1,  false));
        for abundant.eachi |i, ai| {
            for vec::view(abundant, i, abundant.len()).each |aj| {
                let s = *ai + *aj;
                if s > max_num { break; }
                if !v[s] { sum += s; }
                v[s] = true;
            }
        }
        sum
    };

    let sum_of_all_int = (1 + max_num) * max_num / 2;

    io::println(fmt!("%u", sum_of_all_int - sum_of_abundant));
}
<|endoftext|>


<commit_before><commit_msg>println!() requires semicolon after the line<commit_after><|endoftext|>


<commit_before>use std::collections::HashMap;
use std::net::SocketAddr;
use std::pin::Pin;
use std::str;
use std::task::{Context, Poll};

use futures::prelude::*;
use futures::Future;

use hyper::Client;

use tokio::net::UdpSocket;
use tokio::time::timeout;

use hyper::body::Bytes;

use crate::aio::Gateway;
use crate::common::{messages, parsing, SearchOptions};
use crate::errors::SearchError;

const MAX_RESPONSE_SIZE: usize = 1500;

/// Search for a gateway with the provided options
pub async fn search_gateway(options: SearchOptions) -> Result<Gateway, SearchError> {
    // Create socket for future calls
    let socket = UdpSocket::bind(&options.bind_addr).await?;

    let search_future = SearchFuture::search(socket, options.broadcast_address).await?;
    // Create future and issue request
    match options.timeout {
        Some(t) => timeout(t, search_future).await?,
        None => search_future.await,
    }
}

pub struct SearchFuture {
    socket: UdpSocket,
    pending: HashMap<SocketAddr, SearchState>,
}

enum SearchState {
    Connecting(Pin<Box<dyn Future<Output = Result<Bytes, SearchError>> + Send>>),
    Done(String),
    Error,
}

impl SearchFuture {
    // Create a new search
    async fn search(mut socket: UdpSocket, addr: SocketAddr) -> Result<SearchFuture, SearchError> {
        debug!(
            "sending broadcast request to: {} on interface: {:?}",
            addr,
            socket.local_addr()
        );
        socket.send_to(messages::SEARCH_REQUEST.as_bytes(), &addr).await?;
        Ok(SearchFuture {
            socket,
            pending: HashMap::new(),
        })
    }

    // Handle a UDP response message
    fn handle_broadcast_resp(from: SocketAddr, data: &[u8]) -> Result<(SocketAddr, String), SearchError> {
        debug!("handling broadcast response from: {}", from);

        // Convert response to text
        let text = str::from_utf8(&data).map_err(|e| SearchError::from(e))?;

        // Parse socket address and path
        let (addr, path) = parsing::parse_search_result(text)?;

        Ok((SocketAddr::V4(addr), path))
    }

    // Issue a control URL request over HTTP using the provided
    fn request_control_url(
        addr: SocketAddr,
        path: String,
    ) -> Result<Pin<Box<dyn Future<Output = Result<Bytes, SearchError>> + Send>>, SearchError> {
        let client = Client::new();

        let uri = match format!("http://{}{}", addr, path).parse() {
            Ok(uri) => uri,
            Err(err) => return Err(SearchError::from(err)),
        };

        debug!("requesting control url from: {}", uri);

        Ok(Box::pin(
            client
                .get(uri)
                .and_then(|resp| hyper::body::to_bytes(resp.into_body()))
                .map_err(|e| SearchError::from(e)),
        ))
    }

    // Process a control response to extract the control URL
    fn handle_control_resp(addr: SocketAddr, resp: Bytes) -> Result<String, SearchError> {
        debug!("handling control response from: {}", addr);

        // Create a cursor over the response data
        let c = std::io::Cursor::new(&resp);

        // Parse control URL out of body
        let url = parsing::parse_control_url(c)?;

        Ok(url)
    }
}

impl Future for SearchFuture {
    type Output = Result<Gateway, SearchError>;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<Gateway, SearchError>> {
        // Poll for (and handle) incoming messages
        let mut buff = [0u8; MAX_RESPONSE_SIZE];
        let resp = self.socket.poll_recv_from(cx, &mut buff);
        if let Poll::Ready(Ok((n, from))) = resp {
            // Try handle response messages
            if let Ok((addr, path)) = Self::handle_broadcast_resp(from, &buff[0..n]) {
                if !self.pending.contains_key(&addr) {
                    debug!("received broadcast response from: {}", from);

                    // Issue control request
                    match Self::request_control_url(addr, path) {
                        // Store pending requests
                        Ok(f) => {
                            self.pending.insert(addr, SearchState::Connecting(f));
                        }
                        Err(e) => return Poll::Ready(Err(e)),
                    }
                } else {
                    debug!("received duplicate broadcast response from: {}, dropping", from);
                }
            }
        }
        if let Poll::Ready(Err(err)) = resp {
            return Poll::Ready(Err(err.into()));
        }

        // Poll on any outstanding control requests
        for (addr, state) in &mut self.pending {
            // Poll if we're in the connecting state
            let resp = {
                let c = match state {
                    SearchState::Connecting(c) => c,
                    _ => continue,
                };

                match c.as_mut().poll(cx)? {
                    Poll::Ready(resp) => resp,
                    _ => continue,
                }
            };

            // Handle any responses
            if let Ok(url) = Self::handle_control_resp(*addr, resp) {
                debug!("received control url from: {} (url: {})", addr, url);
                *state = SearchState::Done(url.clone());

                match addr {
                    SocketAddr::V4(a) => {
                        let g = Gateway {
                            addr: *a,
                            contorl_url: url,
                        };
                        return Poll::Ready(Ok(g));
                    }
                    _ => warn!("unsupported IPv6 gateway response from addr: {}", addr),
                }
            } else {
                *state = SearchState::Error;
            }
        }

        Poll::Pending
    }
}
<commit_msg>Rename variable to be more explicit<commit_after>use std::collections::HashMap;
use std::net::SocketAddr;
use std::pin::Pin;
use std::str;
use std::task::{Context, Poll};

use futures::prelude::*;
use futures::Future;

use hyper::Client;

use tokio::net::UdpSocket;
use tokio::time::timeout;

use hyper::body::Bytes;

use crate::aio::Gateway;
use crate::common::{messages, parsing, SearchOptions};
use crate::errors::SearchError;

const MAX_RESPONSE_SIZE: usize = 1500;

/// Search for a gateway with the provided options
pub async fn search_gateway(options: SearchOptions) -> Result<Gateway, SearchError> {
    // Create socket for future calls
    let socket = UdpSocket::bind(&options.bind_addr).await?;

    let search_future = SearchFuture::search(socket, options.broadcast_address).await?;
    // Create future and issue request
    match options.timeout {
        Some(t) => timeout(t, search_future).await?,
        None => search_future.await,
    }
}

pub struct SearchFuture {
    socket: UdpSocket,
    pending: HashMap<SocketAddr, SearchState>,
}

enum SearchState {
    Connecting(Pin<Box<dyn Future<Output = Result<Bytes, SearchError>> + Send>>),
    Done(String),
    Error,
}

impl SearchFuture {
    // Create a new search
    async fn search(mut socket: UdpSocket, addr: SocketAddr) -> Result<SearchFuture, SearchError> {
        debug!(
            "sending broadcast request to: {} on interface: {:?}",
            addr,
            socket.local_addr()
        );
        socket.send_to(messages::SEARCH_REQUEST.as_bytes(), &addr).await?;
        Ok(SearchFuture {
            socket,
            pending: HashMap::new(),
        })
    }

    // Handle a UDP response message
    fn handle_broadcast_resp(from: SocketAddr, data: &[u8]) -> Result<(SocketAddr, String), SearchError> {
        debug!("handling broadcast response from: {}", from);

        // Convert response to text
        let text = str::from_utf8(&data).map_err(|e| SearchError::from(e))?;

        // Parse socket address and path
        let (addr, path) = parsing::parse_search_result(text)?;

        Ok((SocketAddr::V4(addr), path))
    }

    // Issue a control URL request over HTTP using the provided
    fn request_control_url(
        addr: SocketAddr,
        path: String,
    ) -> Result<Pin<Box<dyn Future<Output = Result<Bytes, SearchError>> + Send>>, SearchError> {
        let client = Client::new();

        let uri = match format!("http://{}{}", addr, path).parse() {
            Ok(uri) => uri,
            Err(err) => return Err(SearchError::from(err)),
        };

        debug!("requesting control url from: {}", uri);

        Ok(Box::pin(
            client
                .get(uri)
                .and_then(|resp| hyper::body::to_bytes(resp.into_body()))
                .map_err(|e| SearchError::from(e)),
        ))
    }

    // Process a control response to extract the control URL
    fn handle_control_resp(addr: SocketAddr, resp: Bytes) -> Result<String, SearchError> {
        debug!("handling control response from: {}", addr);

        // Create a cursor over the response data
        let c = std::io::Cursor::new(&resp);

        // Parse control URL out of body
        let url = parsing::parse_control_url(c)?;

        Ok(url)
    }
}

impl Future for SearchFuture {
    type Output = Result<Gateway, SearchError>;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<Gateway, SearchError>> {
        // Poll for (and handle) incoming messages
        let mut buff = [0u8; MAX_RESPONSE_SIZE];
        let resp = self.socket.poll_recv_from(cx, &mut buff);
        if let Poll::Ready(Ok((n, from))) = resp {
            // Try handle response messages
            if let Ok((addr, path)) = Self::handle_broadcast_resp(from, &buff[0..n]) {
                if !self.pending.contains_key(&addr) {
                    debug!("received broadcast response from: {}", from);

                    // Issue control request
                    match Self::request_control_url(addr, path) {
                        // Store pending requests
                        Ok(f) => {
                            self.pending.insert(addr, SearchState::Connecting(f));
                        }
                        Err(e) => return Poll::Ready(Err(e)),
                    }
                } else {
                    debug!("received duplicate broadcast response from: {}, dropping", from);
                }
            }
        }
        if let Poll::Ready(Err(err)) = resp {
            return Poll::Ready(Err(err.into()));
        }

        // Poll on any outstanding control requests
        for (addr, state) in &mut self.pending {
            // Poll if we're in the connecting state
            let resp = {
                let c = match state {
                    SearchState::Connecting(c) => c,
                    _ => continue,
                };

                match c.as_mut().poll(cx)? {
                    Poll::Ready(resp) => resp,
                    _ => continue,
                }
            };

            // Handle any responses
            if let Ok(control_url) = Self::handle_control_resp(*addr, resp) {
                debug!("received control url from: {} (url: {})", addr, control_url);
                *state = SearchState::Done(url.clone());

                match addr {
                    SocketAddr::V4(a) => {
                        let g = Gateway {
                            addr: *a,
                            control_url,
                        };
                        return Poll::Ready(Ok(g));
                    }
                    _ => warn!("unsupported IPv6 gateway response from addr: {}", addr),
                }
            } else {
                *state = SearchState::Error;
            }
        }

        Poll::Pending
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 FaultyRAM
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT
// or http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! Types for safely allocating memory.

#![cfg_attr(feature = "clippy", allow(inline_always))]

use core::{fmt, intrinsics, isize};
use core::ptr::Unique;
use super::error::Error;
use super::result::Result;

extern "C" {
    #[allocator]
    fn __rust_allocate(len: usize, align: usize) -> *mut u8;
    fn __rust_allocate_zeroed(len: usize, align: usize) -> *mut u8;
    fn __rust_deallocate(ptr: *mut u8, old_len: usize, align: usize);
    fn __rust_reallocate(ptr: *mut u8, old_len: usize, len: usize, align: usize) -> *mut u8;
    fn __rust_reallocate_inplace(ptr: *mut u8, old_len: usize, len: usize, align: usize) -> usize;
}

#[cfg_attr(feature = "clippy", allow(cast_sign_loss))]
#[inline(always)]
/// Performs sanity checks on the length of a requested memory allocation.
fn check_len(len: usize) -> Result<()> {
    if len == 0 {
        Err(Error::ZeroLength)
    } else if len > isize::MAX as usize {
        Err(Error::NotEnoughMemory)
    } else {
        Ok(())
    }
}

#[inline(always)]
/// Performs sanity checks on the length and alignment of a requested memory allocation.
fn check_len_and_align(len: usize, align: usize) -> Result<()> {
    check_len(len).and_then(
        |_| if usize::is_power_of_two(align) {
            Ok(())
        } else {
            Err(Error::BadAlignment)
        }
    )
}

#[allow(missing_copy_implementations)]
/// An owned, allocated block of memory.
pub struct Allocation {
    /// A raw pointer to the allocated block of memory.
    ptr: Unique<u8>,
    /// The length in bytes of the allocation.
    len: usize,
    /// The alignment in bytes of the allocation.
    align: usize,
}

#[cfg_attr(feature = "clippy", allow(len_without_is_empty))]
impl Allocation {
    #[inline]
    /// Allocates a block of memory using the specified length and alignment.
    pub fn new(len: usize, align: usize) -> Result<Allocation> {
        check_len_and_align(len, align).and_then(
            |_| {
                let ptr = unsafe { __rust_allocate(len, align) };
                if ptr.is_null() {
                    Err(Error::NotEnoughMemory)
                } else {
                    Ok(
                        Allocation {
                            ptr: unsafe { Unique::new(ptr) },
                            len: len,
                            align: align,
                        }
                    )
                }
            }
        )
    }

    #[inline]
    /// Allocates a block of memory with all bytes initialized to zero, using the specified length
    /// and alignment.
    pub fn zeroed(len: usize, align: usize) -> Result<Allocation> {
        check_len_and_align(len, align).and_then(
            |_| {
                let ptr = unsafe { __rust_allocate_zeroed(len, align) };
                if ptr.is_null() {
                    Err(Error::NotEnoughMemory)
                } else {
                    Ok(
                        Allocation {
                            ptr: unsafe { Unique::new(ptr) },
                            len: len,
                            align: align,
                        }
                    )
                }
            }
        )
    }

    #[inline]
    /// Resizes an existing allocation.
    ///
    /// On failure, returns an error without modifying the existing allocation.
    pub fn resize(&mut self, new_len: usize) -> Result<()> {
        check_len(new_len).and_then(
            |_| {
                let ptr =
                    unsafe { __rust_reallocate(self.as_mut_ptr(), self.len, new_len, self.align) };
                if ptr.is_null() {
                    Err(Error::NotEnoughMemory)
                } else {
                    self.ptr = unsafe { Unique::new(ptr) };
                    self.len = new_len;
                    Ok(())
                }
            }
        )
    }

    #[inline]
    /// Resizes an existing allocation without moving it.
    ///
    /// On failure, returns an error without modifying the existing allocation.
    pub fn resize_in_place(&mut self, new_len: usize) -> Result<()> {
        check_len(new_len).and_then(
            |_| {
                self.len = unsafe {
                    __rust_reallocate_inplace(self.as_mut_ptr(), self.len, new_len, self.align)
                };
                Ok(())
            }
        )
    }

    /// Creates a new memory allocation with the same length, alignment and contents as an
    /// existing allocation.
    pub fn duplicate(&self) -> Result<Allocation> {
        Allocation::new(self.len, self.align).map(
            |mut new_alloc| {
                unsafe {
                    intrinsics::copy_nonoverlapping(
                        self.as_ptr(),
                        new_alloc.as_mut_ptr(),
                        self.len,
                    );
                }
                new_alloc
            }
        )
    }

    /// Returns a raw pointer to the allocated block of memory.
    pub fn as_ptr(&self) -> *const u8 {
        unsafe { &*self.ptr.as_ptr() }
    }

    /// Returns a mutable raw pointer to the allocated block of memory.
    pub fn as_mut_ptr(&mut self) -> *mut u8 {
        self.ptr.as_ptr()
    }

    /// Returns the length in bytes of the allocated block of memory.
    pub fn len(&self) -> usize {
        self.len
    }

    /// Returns the alignment in bytes of the allocated block of memory.
    pub fn align(&self) -> usize {
        self.align
    }
}

impl Drop for Allocation {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            __rust_deallocate(self.ptr.as_ptr(), self.len, self.align);
        }
    }
}

impl fmt::Debug for Allocation {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Allocation")
            .field("ptr", &self.ptr.as_ptr())
            .field("len", &self.len)
            .field("align", &self.align)
            .finish()
    }
}
<commit_msg>Fix typo<commit_after>// Copyright (c) 2017 FaultyRAM
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT
// or http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! Types for safely allocating memory.

#![cfg_attr(feature = "clippy", allow(inline_always))]

use core::{fmt, intrinsics, isize};
use core::ptr::Unique;
use super::error::Error;
use super::result::Result;

extern "C" {
    #[allocator]
    fn __rust_allocate(len: usize, align: usize) -> *mut u8;
    fn __rust_allocate_zeroed(len: usize, align: usize) -> *mut u8;
    fn __rust_deallocate(ptr: *mut u8, old_len: usize, align: usize);
    fn __rust_reallocate(ptr: *mut u8, old_len: usize, len: usize, align: usize) -> *mut u8;
    fn __rust_reallocate_inplace(ptr: *mut u8, old_len: usize, len: usize, align: usize) -> usize;
}

#[cfg_attr(feature = "clippy", allow(cast_sign_loss))]
#[inline(always)]
/// Performs sanity checks on the length of a requested memory allocation.
fn check_len(len: usize) -> Result<()> {
    if len == 0 {
        Err(Error::ZeroLength)
    } else if len > isize::MAX as usize {
        Err(Error::NotEnoughMemory)
    } else {
        Ok(())
    }
}

#[inline(always)]
/// Performs sanity checks on the length and alignment of a requested memory allocation.
fn check_len_and_align(len: usize, align: usize) -> Result<()> {
    check_len(len).and_then(
        |_| if usize::is_power_of_two(align) {
            Ok(())
        } else {
            Err(Error::BadAlignment)
        }
    )
}

#[allow(missing_copy_implementations)]
/// An owned, allocated block of memory.
pub struct Allocation {
    /// A raw pointer to the allocated block of memory.
    ptr: Unique<u8>,
    /// The length in bytes of the allocation.
    len: usize,
    /// The alignment in bytes of the allocation.
    align: usize,
}

#[cfg_attr(feature = "clippy", allow(len_without_is_empty))]
impl Allocation {
    #[inline]
    /// Allocates a block of memory using the specified length and alignment.
    pub fn new(len: usize, align: usize) -> Result<Allocation> {
        check_len_and_align(len, align).and_then(
            |_| {
                let ptr = unsafe { __rust_allocate(len, align) };
                if ptr.is_null() {
                    Err(Error::NotEnoughMemory)
                } else {
                    Ok(
                        Allocation {
                            ptr: unsafe { Unique::new(ptr) },
                            len: len,
                            align: align,
                        }
                    )
                }
            }
        )
    }

    #[inline]
    /// Allocates a block of memory with all bytes initialized to zero, using the specified length
    /// and alignment.
    pub fn zeroed(len: usize, align: usize) -> Result<Allocation> {
        check_len_and_align(len, align).and_then(
            |_| {
                let ptr = unsafe { __rust_allocate_zeroed(len, align) };
                if ptr.is_null() {
                    Err(Error::NotEnoughMemory)
                } else {
                    Ok(
                        Allocation {
                            ptr: unsafe { Unique::new(ptr) },
                            len: len,
                            align: align,
                        }
                    )
                }
            }
        )
    }

    #[inline]
    /// Resizes an existing allocation.
    ///
    /// On failure, returns an error without modifying the existing allocation.
    pub fn resize(&mut self, new_len: usize) -> Result<()> {
        check_len(new_len).and_then(
            |_| {
                let ptr =
                    unsafe { __rust_reallocate(self.as_mut_ptr(), self.len, new_len, self.align) };
                if ptr.is_null() {
                    Err(Error::NotEnoughMemory)
                } else {
                    self.ptr = unsafe { Unique::new(ptr) };
                    self.len = new_len;
                    Ok(())
                }
            }
        )
    }

    #[inline]
    /// Resizes an existing allocation without moving it.
    ///
    /// On failure, returns an error without modifying the existing allocation.
    pub fn resize_in_place(&mut self, new_len: usize) -> Result<()> {
        check_len(new_len).and_then(
            |_| {
                self.len = unsafe {
                    __rust_reallocate_inplace(self.as_mut_ptr(), self.len, new_len, self.align)
                };
                Ok(())
            }
        )
    }

    /// Creates a new memory allocation with the same length, alignment and contents as an
    /// existing allocation.
    pub fn duplicate(&self) -> Result<Allocation> {
        Allocation::new(self.len, self.align).map(
            |mut new_alloc| {
                unsafe {
                    intrinsics::copy_nonoverlapping(
                        self.as_ptr(),
                        new_alloc.as_mut_ptr(),
                        self.len,
                    );
                }
                new_alloc
            }
        )
    }

    /// Returns a raw pointer to the allocated block of memory.
    pub fn as_ptr(&self) -> *const u8 {
        unsafe { &*self.ptr.as_ptr() }
    }

    /// Returns a mutable raw pointer to the allocated block of memory.
    pub fn as_mut_ptr(&mut self) -> *mut u8 {
        self.ptr.as_ptr()
    }

    /// Returns the length in bytes of the allocated block of memory.
    pub fn len(&self) -> usize {
        self.len
    }

    /// Returns the alignment in bytes of the allocated block of memory.
    pub fn align(&self) -> usize {
        self.align
    }
}

impl Drop for Allocation {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            __rust_deallocate(self.as_mut_ptr(), self.len, self.align);
        }
    }
}

impl fmt::Debug for Allocation {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Allocation")
            .field("ptr", &self.ptr.as_ptr())
            .field("len", &self.len)
            .field("align", &self.align)
            .finish()
    }
}
<|endoftext|>