<commit_before><commit_msg>Add fat image scanning<commit_after>use std::error;
use std::fs;
use std::io;
use std::io::Read;
use std::io::Write;

const BYTES_PER_SECTOR: usize = 512;
const SECTORS_PER_FAT: usize = 9;
const SECTORS_PER_ROOT: usize = 14;
const SECTORS_PER_DATA_AREA: usize = 2847;

const BYTES_PER_FAT: usize = BYTES_PER_SECTOR * SECTORS_PER_FAT;
const BYTES_PER_ROOT: usize
    = BYTES_PER_SECTOR * SECTORS_PER_ROOT;
const BYTES_PER_DATA_AREA: usize
    = BYTES_PER_SECTOR * SECTORS_PER_DATA_AREA;

pub struct Image {
    boot_sector: Vec<u8>,
    fat_1: Vec<u8>,
    fat_2: Vec<u8>,
    root_dir: Vec<u8>,
    data_area: Vec<u8>,
}

impl Image {
    pub fn new() -> Image {
        Image {
            boot_sector: vec![0; 1 * BYTES_PER_SECTOR],
            fat_1: vec![0; BYTES_PER_FAT],
            fat_2: vec![0; BYTES_PER_FAT],
            root_dir: vec![0; BYTES_PER_ROOT],
            data_area: vec![0; BYTES_PER_DATA_AREA],
        }
    }

    fn blank_image() -> Image {
        Image {
            boot_sector: Vec::with_capacity(BYTES_PER_SECTOR),
            fat_1: Vec::with_capacity(BYTES_PER_FAT),
            fat_2: Vec::with_capacity(BYTES_PER_FAT),
            root_dir: Vec::with_capacity(BYTES_PER_ROOT),
            data_area: Vec::with_capacity(BYTES_PER_DATA_AREA),
        }
    }

    pub fn from(image_fn: String)
        -> Result<Image, Box<error::Error>>
    {
        let mut file = fs::File::open(image_fn)?;
        let mut image = Image::blank_image();

        try!(file.read_exact(&mut image.boot_sector));
        try!(file.read_exact(&mut image.fat_1));
        try!(file.read_exact(&mut image.fat_2));
        try!(file.read_exact(&mut image.root_dir));
        try!(file.read_exact(&mut image.data_area));

        Ok(image)
    }

    pub fn save(&self, image_fn: String)
        -> Result<(), io::Error>
    {
        let mut file = fs::File::create(image_fn)?;

        try!(file.write_all(&self.boot_sector));
        try!(file.write_all(&self.fat_1));
        try!(file.write_all(&self.fat_2));
        try!(file.write_all(&self.root_dir));
        try!(file.write_all(&self.data_area));

        Ok(())
    }
}
<|endoftext|>


<commit_before><commit_msg>inline b_tree methods<commit_after><|endoftext|>


<commit_before><commit_msg>Adding new 1bit decoding method.<commit_after><|endoftext|>


<commit_before><commit_msg>Better generic support. Nearly working, one might say.<commit_after><|endoftext|>


<commit_before><commit_msg>Implement some traits for Parameters to make it match HashMap more<commit_after><|endoftext|>


<commit_before><commit_msg>updated to current buildable api<commit_after><|endoftext|>


<commit_before><commit_msg>Don't export run anymore<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unnecessary attributes<commit_after><|endoftext|>


<commit_before><commit_msg>Handle TODO tests<commit_after><|endoftext|>


<commit_before><commit_msg>Use new Sign trait<commit_after><|endoftext|>


<commit_before>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

#![feature(negate_unsigned)]
#![feature(intrinsics)]

mod rusti {
    extern "rust-intrinsic" {
        pub fn ctpop8(x: u8) -> u8;
        pub fn ctpop16(x: u16) -> u16;
        pub fn ctpop32(x: u32) -> u32;
        pub fn ctpop64(x: u64) -> u64;

        pub fn ctlz8(x: u8) -> u8;
        pub fn ctlz16(x: u16) -> u16;
        pub fn ctlz32(x: u32) -> u32;
        pub fn ctlz64(x: u64) -> u64;

        pub fn cttz8(x: u8) -> u8;
        pub fn cttz16(x: u16) -> u16;
        pub fn cttz32(x: u32) -> u32;
        pub fn cttz64(x: u64) -> u64;

        pub fn bswap16(x: u16) -> u16;
        pub fn bswap32(x: u32) -> u32;
        pub fn bswap64(x: u64) -> u64;
    }
}

pub fn main() {
    unsafe {
        use rusti::*;

        assert_eq!(ctpop8(0), 0);
        assert_eq!(ctpop16(0), 0);
        assert_eq!(ctpop32(0), 0);
        assert_eq!(ctpop64(0), 0);

        assert_eq!(ctpop8(1), 1);
        assert_eq!(ctpop16(1), 1);
        assert_eq!(ctpop32(1), 1);
        assert_eq!(ctpop64(1), 1);

        assert_eq!(ctpop8(10), 2);
        assert_eq!(ctpop16(10), 2);
        assert_eq!(ctpop32(10), 2);
        assert_eq!(ctpop64(10), 2);

        assert_eq!(ctpop8(100), 3);
        assert_eq!(ctpop16(100), 3);
        assert_eq!(ctpop32(100), 3);
        assert_eq!(ctpop64(100), 3);

        assert_eq!(ctpop8(-1), 8);
        assert_eq!(ctpop16(-1), 16);
        assert_eq!(ctpop32(-1), 32);
        assert_eq!(ctpop64(-1), 64);

        assert_eq!(ctlz8(0), 8);
        assert_eq!(ctlz16(0), 16);
        assert_eq!(ctlz32(0), 32);
        assert_eq!(ctlz64(0), 64);

        assert_eq!(ctlz8(1), 7);
        assert_eq!(ctlz16(1), 15);
        assert_eq!(ctlz32(1), 31);
        assert_eq!(ctlz64(1), 63);

        assert_eq!(ctlz8(10), 4);
        assert_eq!(ctlz16(10), 12);
        assert_eq!(ctlz32(10), 28);
        assert_eq!(ctlz64(10), 60);

        assert_eq!(ctlz8(100), 1);
        assert_eq!(ctlz16(100), 9);
        assert_eq!(ctlz32(100), 25);
        assert_eq!(ctlz64(100), 57);

        assert_eq!(cttz8(-1), 0);
        assert_eq!(cttz16(-1), 0);
        assert_eq!(cttz32(-1), 0);
        assert_eq!(cttz64(-1), 0);

        assert_eq!(cttz8(0), 8);
        assert_eq!(cttz16(0), 16);
        assert_eq!(cttz32(0), 32);
        assert_eq!(cttz64(0), 64);

        assert_eq!(cttz8(1), 0);
        assert_eq!(cttz16(1), 0);
        assert_eq!(cttz32(1), 0);
        assert_eq!(cttz64(1), 0);

        assert_eq!(cttz8(10), 1);
        assert_eq!(cttz16(10), 1);
        assert_eq!(cttz32(10), 1);
        assert_eq!(cttz64(10), 1);

        assert_eq!(cttz8(100), 2);
        assert_eq!(cttz16(100), 2);
        assert_eq!(cttz32(100), 2);
        assert_eq!(cttz64(100), 2);

        assert_eq!(cttz8(-1), 0);
        assert_eq!(cttz16(-1), 0);
        assert_eq!(cttz32(-1), 0);
        assert_eq!(cttz64(-1), 0);

        assert_eq!(bswap16(0x0A0B), 0x0B0A);
        assert_eq!(bswap32(0x0ABBCC0D), 0x0DCCBB0A);
        assert_eq!(bswap64(0x0122334455667708), 0x0877665544332201);
    }
}
<commit_msg>Remove duplicated tests for the cttz intrinsic<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

#![feature(negate_unsigned)]
#![feature(intrinsics)]

mod rusti {
    extern "rust-intrinsic" {
        pub fn ctpop8(x: u8) -> u8;
        pub fn ctpop16(x: u16) -> u16;
        pub fn ctpop32(x: u32) -> u32;
        pub fn ctpop64(x: u64) -> u64;

        pub fn ctlz8(x: u8) -> u8;
        pub fn ctlz16(x: u16) -> u16;
        pub fn ctlz32(x: u32) -> u32;
        pub fn ctlz64(x: u64) -> u64;

        pub fn cttz8(x: u8) -> u8;
        pub fn cttz16(x: u16) -> u16;
        pub fn cttz32(x: u32) -> u32;
        pub fn cttz64(x: u64) -> u64;

        pub fn bswap16(x: u16) -> u16;
        pub fn bswap32(x: u32) -> u32;
        pub fn bswap64(x: u64) -> u64;
    }
}

pub fn main() {
    unsafe {
        use rusti::*;

        assert_eq!(ctpop8(0), 0);
        assert_eq!(ctpop16(0), 0);
        assert_eq!(ctpop32(0), 0);
        assert_eq!(ctpop64(0), 0);

        assert_eq!(ctpop8(1), 1);
        assert_eq!(ctpop16(1), 1);
        assert_eq!(ctpop32(1), 1);
        assert_eq!(ctpop64(1), 1);

        assert_eq!(ctpop8(10), 2);
        assert_eq!(ctpop16(10), 2);
        assert_eq!(ctpop32(10), 2);
        assert_eq!(ctpop64(10), 2);

        assert_eq!(ctpop8(100), 3);
        assert_eq!(ctpop16(100), 3);
        assert_eq!(ctpop32(100), 3);
        assert_eq!(ctpop64(100), 3);

        assert_eq!(ctpop8(-1), 8);
        assert_eq!(ctpop16(-1), 16);
        assert_eq!(ctpop32(-1), 32);
        assert_eq!(ctpop64(-1), 64);

        assert_eq!(ctlz8(0), 8);
        assert_eq!(ctlz16(0), 16);
        assert_eq!(ctlz32(0), 32);
        assert_eq!(ctlz64(0), 64);

        assert_eq!(ctlz8(1), 7);
        assert_eq!(ctlz16(1), 15);
        assert_eq!(ctlz32(1), 31);
        assert_eq!(ctlz64(1), 63);

        assert_eq!(ctlz8(10), 4);
        assert_eq!(ctlz16(10), 12);
        assert_eq!(ctlz32(10), 28);
        assert_eq!(ctlz64(10), 60);

        assert_eq!(ctlz8(100), 1);
        assert_eq!(ctlz16(100), 9);
        assert_eq!(ctlz32(100), 25);
        assert_eq!(ctlz64(100), 57);

        assert_eq!(cttz8(-1), 0);
        assert_eq!(cttz16(-1), 0);
        assert_eq!(cttz32(-1), 0);
        assert_eq!(cttz64(-1), 0);

        assert_eq!(cttz8(0), 8);
        assert_eq!(cttz16(0), 16);
        assert_eq!(cttz32(0), 32);
        assert_eq!(cttz64(0), 64);

        assert_eq!(cttz8(1), 0);
        assert_eq!(cttz16(1), 0);
        assert_eq!(cttz32(1), 0);
        assert_eq!(cttz64(1), 0);

        assert_eq!(cttz8(10), 1);
        assert_eq!(cttz16(10), 1);
        assert_eq!(cttz32(10), 1);
        assert_eq!(cttz64(10), 1);

        assert_eq!(cttz8(100), 2);
        assert_eq!(cttz16(100), 2);
        assert_eq!(cttz32(100), 2);
        assert_eq!(cttz64(100), 2);

        assert_eq!(bswap16(0x0A0B), 0x0B0A);
        assert_eq!(bswap32(0x0ABBCC0D), 0x0DCCBB0A);
        assert_eq!(bswap64(0x0122334455667708), 0x0877665544332201);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a test for Issue #2428.<commit_after>// xfail-test

const foo: int = 4 >> 1;
enum bs { thing = foo }
fn main() { assert(thing as int == foo); }
<|endoftext|>


<commit_before><commit_msg>Fix: Also write newlines<commit_after><|endoftext|>


<commit_before><commit_msg>initialize the database<commit_after>#![crate_id="initdb"]
#![crate_type = "bin"]

extern crate sqlite3;

mod init {
    use sqlite3::{open, SqliteResult};

    pub fn main() -> SqliteResult<()> {
        let args = ::std::os::args();

        let db = try!(open(args[1]));

        try!(db.exec("CREATE TABLE Words(Word TEXT);"));
        try!(db.exec("CREATE TABLE Definitions(Definee TEXT, Idx INTEGER, Definer TEXT);"));

        let mut input = ::std::io::stdin();
        for line in input.lines() {
            try!(db.exec(format!("INSERT INTO Words VALUES(\"{}\");", line.unwrap().trim())));
        }
        println!("hello world");
        Ok(())
    }
}

pub fn main() {
    match init::main() {
        Ok(()) => {}
        Err(e) => { println!("error: {}", e) }
    }
}
<|endoftext|>


<commit_before><commit_msg>Change the native_thread module to be thread_local_storage module<commit_after><|endoftext|>


<commit_before><commit_msg>pig-latin: Add empty src/lib.rs (#324)<commit_after><|endoftext|>


<commit_before><commit_msg>rust: Even or Odd (8 kyu)<commit_after><|endoftext|>


<commit_before><commit_msg>Add company.rs<commit_after>use postgres::Connection;
use postgres_array::Array;

#[derive(Debug)]
pub struct Company {
  pub presented_talents: Vec<i32>,
}

impl Company {
  pub fn find(conn: &Connection, id: &i32) -> Option<Company> {
    let response = &conn.query(
      "SELECT * FROM companies
        WHERE id = $1
        LIMIT 1", &[&id]
    ).unwrap();

    let mut results = response.iter().map(|row| {
      let presented_talents: Array<String> = row.get("presented_talents");

      Company {
        presented_talents: presented_talents.iter()
                                            .map(|s| s.parse::<i32>().unwrap())
                                            .collect::<Vec<i32>>(),
      }
    }).collect::<Vec<Company>>();

    results.pop()
  }
}
<|endoftext|>


<commit_before><commit_msg>Enable logging in model tests<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unused variable from Database struct<commit_after><|endoftext|>


<commit_before><commit_msg>Add fanout example<commit_after>// Copyright (c) 2018 Berkus Decker <berkus+github@metta.systems>
//
// 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.

/// This example shows simple packet_fanout processing under linux.
extern crate pnet;
extern crate pnet_datalink;

use pnet::datalink::{self, Config, FanoutOption, FanoutType, NetworkInterface};
use std::env;
use std::io::{self, Write};
use std::process;
use std::thread;

#[cfg(not(target_os = "linux"))]
fn main() {
    writeln!(io::stderr(), "fanout is only supported on Linux").unwrap();
    process::exit(1);
}

#[cfg(target_os = "linux")]
fn main() {
    use pnet::datalink::Channel::Ethernet;

    let iface_name = match env::args().nth(1) {
        Some(n) => n,
        None => {
            writeln!(io::stderr(), "USAGE: fanout <NETWORK INTERFACE> [hash|*round-robin*|cpu|rollover|rnd|qm|cbpf|ebpf] [group-id:123]").unwrap();
            process::exit(1);
        }
    };
    let interface_names_match = |iface: &NetworkInterface| iface.name == iface_name;

    // Find the network interface with the provided name
    let interfaces = datalink::interfaces();
    let interface = interfaces
        .into_iter()
        .filter(interface_names_match)
        .next()
        .unwrap();

    let fanout_type = match env::args().nth(2) {
        Some(n) => match n.to_lowercase().as_str() {
            "hash" => FanoutType::HASH,
            "round-robin" => FanoutType::LB,
            "cpu" => FanoutType::CPU,
            "rollover" => FanoutType::ROLLOVER,
            "rnd" => FanoutType::RND,
            "qm" => FanoutType::QM,
            "cbpf" => FanoutType::CBPF,
            "ebpf" => FanoutType::EBPF,
            _ => panic!("Unsupported fanout type, use one of hash, round-robin, cpu, rollover, rnd, qm, cbpf or ebpf")
        },
        None => FanoutType::LB,
    };

    let group_id = match env::args().nth(3) {
        Some(n) => n.parse::<u16>().unwrap(),
        None => 123,
    };

    let mut config: Config = Default::default();
    config.linux_fanout = Some(FanoutOption {
        group_id: group_id,
        fanout_type: fanout_type,
        defrag: true,
        rollover: false,
    });

    let mut threads = vec![];
    for x in 0..3 {
        let itf = interface.clone();
        let thread = thread::Builder::new()
            .name(format!("thread{}", x))
            .spawn(move || {
                // Create a channel to receive on
                let (_, mut rx) = match datalink::channel(&itf, config) {
                    Ok(Ethernet(tx, rx)) => (tx, rx),
                    Ok(_) => panic!("packetdump: unhandled channel type: {}"),
                    Err(e) => panic!("packetdump: unable to create channel: {}", e),
                };

                let handle = thread::current();

                loop {
                    match rx.next() {
                        Ok(_packet) => {
                            writeln!(
                                io::stdout(),
                                "Received packet on thread {:?}",
                                handle.name()
                            ).unwrap();
                        }
                        Err(e) => panic!("packetdump: unable to receive packet: {}", e),
                    }
                }
            })
            .unwrap();
        threads.push(thread);
    }

    for t in threads {
        t.join().unwrap();
    }
}
<|endoftext|>


<commit_before><commit_msg>Add the example as an example test program.<commit_after>extern crate wasmparser;

use std::io;
use std::io::prelude::*;
use std::fs::File;
use std::str;
use wasmparser::Parser;
use wasmparser::ParserState;

fn get_name(bytes: &[u8]) -> &str {
  str::from_utf8(bytes).ok().unwrap()
}

fn main() {
  let ref buf: Vec<u8> = read_wasm().unwrap();
  let mut parser = Parser::new(buf);
  loop {
    let state = parser.read();
    if state.is_none() {
        break;
    }
    match *state.unwrap() {
        ParserState::BeginWasm(_, _) => {
            println!("====== Module");
        },
        ParserState::ExportSectionEntry(field, ref ty, _) => {
            println!("  Export {} {:?}", get_name(field), ty);
        },
        ParserState::ImportSectionEntry(module, field, _) => {
            println!("  Import {}::{}", get_name(module), get_name(field))
        }
        _ => ( /* println!(" Other {:?}", state); */ )
    }
  }
}

fn read_wasm() -> io::Result<Vec<u8>> {
    let mut data = Vec::new();
    let mut f = File::open("tests/spec.wasm")?;
    f.read_to_end(&mut data)?;
    Ok(data)
}
<|endoftext|>


<commit_before>use binascii;
use serde;
use serde_json;
use std;

use server::Events;

#[derive(Deserialize, Clone, PartialEq)]
pub enum TrackerMode {
    /// In static mode torrents are tracked only if they were added ahead of time.
    #[serde(rename = "static")]
    StaticMode,

    /// In dynamic mode, torrents are tracked being added ahead of time.
    #[serde(rename = "dynamic")]
    DynamicMode,

    /// Tracker will only serve authenticated peers.
    #[serde(rename = "private")]
    PrivateMode,
}

struct TorrentPeer {
    ip: std::net::SocketAddr,
    uploaded: u64,
    downloaded: u64,
    left: u64,
    event: Events,
    updated: std::time::SystemTime,
}

#[derive(Ord, PartialEq, Eq, Clone)]
pub struct InfoHash {
    info_hash: [u8; 20],
}

impl std::cmp::PartialOrd<InfoHash> for InfoHash {
    fn partial_cmp(&self, other: &InfoHash) -> Option<std::cmp::Ordering> {
        self.info_hash.partial_cmp(&other.info_hash)
    }
}

impl std::convert::From<&[u8]> for InfoHash {
    fn from(data: &[u8]) -> InfoHash {
        assert_eq!(data.len(), 20);
        let mut ret = InfoHash{
            info_hash: [0u8; 20],
        };
        ret.info_hash.clone_from_slice(data);
        return ret;
    }
}

impl std::convert::Into<InfoHash> for [u8; 20] {
    fn into(self) -> InfoHash {
        InfoHash { info_hash: self }
    }
}

impl serde::ser::Serialize for InfoHash {
    fn serialize<S: serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        let mut buffer = [0u8; 40];
        let bytes_out = binascii::bin2hex(&self.info_hash, &mut buffer)
            .ok()
            .unwrap();
        let str_out = std::str::from_utf8(bytes_out).unwrap();

        serializer.serialize_str(str_out)
    }
}

struct InfoHashVisitor;

impl<'v> serde::de::Visitor<'v> for InfoHashVisitor {
    type Value = InfoHash;

    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(formatter, "a 40 character long hash")
    }

    fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
        if v.len() != 40 {
            return Err(serde::de::Error::invalid_value(
                serde::de::Unexpected::Str(v),
                &"expected a 40 character long string",
            ));
        }

        let mut res = InfoHash {
            info_hash: [0u8; 20],
        };

        if let Err(_) = binascii::hex2bin(v.as_bytes(), &mut res.info_hash) {
            return Err(serde::de::Error::invalid_value(
                serde::de::Unexpected::Str(v),
                &"expected a hexadecimal string",
            ));
        } else {
            return Ok(res);
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for InfoHash {
    fn deserialize<D: serde::de::Deserializer<'de>>(des: D) -> Result<Self, D::Error> {
        des.deserialize_str(InfoHashVisitor)
    }
}

pub type PeerId = [u8; 20];

#[derive(Serialize, Deserialize)]
pub struct TorrentEntry {
    is_flagged: bool,

    #[serde(skip)]
    peers: std::collections::BTreeMap<PeerId, TorrentPeer>,

    completed: u32,

    #[serde(skip)]
    seeders: u32,
}

impl TorrentEntry {
    pub fn new() -> TorrentEntry {
        TorrentEntry {
            is_flagged: false,
            peers: std::collections::BTreeMap::new(),
            completed: 0,
            seeders: 0,
        }
    }

    pub fn is_flagged(&self) -> bool {
        self.is_flagged
    }

    pub fn update_peer(
        &mut self,
        peer_id: &PeerId,
        remote_address: &std::net::SocketAddr,
        uploaded: u64,
        downloaded: u64,
        left: u64,
        event: Events,
    ) {
        let is_seeder = left == 0 && uploaded > 0;
        let mut was_seeder = false;
        let mut is_completed = left == 0 && (event as u32) == (Events::Complete as u32);
        if let Some(prev) = self.peers.insert(
            *peer_id,
            TorrentPeer {
                updated: std::time::SystemTime::now(),
                left,
                downloaded,
                uploaded,
                ip: *remote_address,
                event,
            },
        ) {
            was_seeder = prev.left == 0 && prev.uploaded > 0;

            if is_completed && (prev.event as u32) == (Events::Complete as u32) {
                // don't update count again. a torrent should only be updated once per peer.
                is_completed = false;
            }
        }

        if is_seeder && !was_seeder {
            self.seeders += 1;
        } else if was_seeder && !is_seeder {
            self.seeders -= 1;
        }

        if is_completed {
            self.completed += 1;
        }
    }

    pub fn get_peers(&self, remote_addr: &std::net::SocketAddr) -> Vec<std::net::SocketAddr> {
        let mut list = Vec::new();
        for (_, peer) in self
            .peers
            .iter()
            .filter(|e| e.1.ip.is_ipv4() == remote_addr.is_ipv4())
            .take(74)
        {
            if peer.ip == *remote_addr {
                continue;
            }

            list.push(peer.ip);
        }
        list
    }

    pub fn get_stats(&self) -> (u32, u32, u32) {
        let leechers = (self.peers.len() as u32) - self.seeders;
        (self.seeders, self.completed, leechers)
    }
}

struct TorrentDatabase {
    torrent_peers: std::sync::RwLock<std::collections::BTreeMap<InfoHash, TorrentEntry>>,
}

impl Default for TorrentDatabase {
    fn default() -> Self {
        TorrentDatabase {
            torrent_peers: std::sync::RwLock::new(std::collections::BTreeMap::new()),
        }
    }
}

pub struct TorrentTracker {
    mode: TrackerMode,
    database: TorrentDatabase,
}

pub enum TorrentStats {
    TorrentFlagged,
    TorrentNotRegistered,
    Stats {
        seeders: u32,
        leechers: u32,
        complete: u32,
    },
}

impl TorrentTracker {
    pub fn new(mode: TrackerMode) -> TorrentTracker {
        TorrentTracker {
            mode,
            database: TorrentDatabase {
                torrent_peers: std::sync::RwLock::new(std::collections::BTreeMap::new()),
            },
        }
    }

    pub fn load_database<R: std::io::Read>(
        mode: TrackerMode,
        reader: &mut R,
    ) -> serde_json::Result<TorrentTracker> {
        use bzip2;
        let decomp_reader = bzip2::read::BzDecoder::new(reader);
        let result: serde_json::Result<std::collections::BTreeMap<InfoHash, TorrentEntry>> =
            serde_json::from_reader(decomp_reader);
        match result {
            Ok(v) => Ok(TorrentTracker {
                mode,
                database: TorrentDatabase {
                    torrent_peers: std::sync::RwLock::new(v),
                },
            }),
            Err(e) => Err(e),
        }
    }

    /// Adding torrents is not relevant to dynamic trackers.
    pub fn add_torrent(&self, info_hash: &InfoHash) -> Result<(), ()> {
        let mut write_lock = self.database.torrent_peers.write().unwrap();
        match write_lock.entry(info_hash.clone()) {
            std::collections::btree_map::Entry::Vacant(ve) => {
                ve.insert(TorrentEntry::new());
                return Ok(());
            }
            std::collections::btree_map::Entry::Occupied(_entry) => {
                return Err(());
            }
        }
    }

    /// If the torrent is flagged, it will not be removed unless force is set to true.
    pub fn remove_torrent(&self, info_hash: &InfoHash, force: bool) -> Result<(), ()> {
        use std::collections::btree_map::Entry;
        let mut entry_lock = self.database.torrent_peers.write().unwrap();
        let torrent_entry = entry_lock.entry(info_hash.clone());
        match torrent_entry {
            Entry::Vacant(_) => {
                // no entry, nothing to do...
                return Err(());
            }
            Entry::Occupied(entry) => {
                if force || !entry.get().is_flagged() {
                    entry.remove();
                    return Ok(());
                }
                return Err(());
            }
        }
    }

    /// flagged torrents will result in a tracking error. This is to allow enforcement against piracy.
    pub fn set_torrent_flag(&self, info_hash: &InfoHash, is_flagged: bool) {
        if let Some(entry) = self
            .database
            .torrent_peers
            .write()
            .unwrap()
            .get_mut(info_hash)
        {
            if is_flagged && !entry.is_flagged {
                // empty peer list.
                entry.peers.clear();
            }
            entry.is_flagged = is_flagged;
        }
    }

    pub fn get_torrent_peers(
        &self,
        info_hash: &InfoHash,
        remote_addr: &std::net::SocketAddr,
    ) -> Option<Vec<std::net::SocketAddr>> {
        let read_lock = self.database.torrent_peers.read().unwrap();
        match read_lock.get(info_hash) {
            None => {
                return None;
            }
            Some(entry) => {
                return Some(entry.get_peers(remote_addr));
            }
        };
    }

    pub fn update_torrent_and_get_stats(
        &self,
        info_hash: &InfoHash,
        peer_id: &PeerId,
        remote_address: &std::net::SocketAddr,
        uploaded: u64,
        downloaded: u64,
        left: u64,
        event: Events,
    ) -> TorrentStats {
        use std::collections::btree_map::Entry;
        let mut torrent_peers = self.database.torrent_peers.write().unwrap();
        let torrent_entry = match torrent_peers.entry(info_hash.clone()) {
            Entry::Vacant(vacant) => match self.mode {
                TrackerMode::DynamicMode => vacant.insert(TorrentEntry::new()),
                _ => {
                    return TorrentStats::TorrentNotRegistered;
                }
            },
            Entry::Occupied(entry) => {
                if entry.get().is_flagged() {
                    return TorrentStats::TorrentFlagged;
                }
                entry.into_mut()
            }
        };

        torrent_entry.update_peer(peer_id, remote_address, uploaded, downloaded, left, event);

        let (seeders, complete, leechers) = torrent_entry.get_stats();

        return TorrentStats::Stats {
            seeders,
            leechers,
            complete,
        };
    }

    pub(crate) fn get_database(
        &self,
    ) -> std::sync::RwLockReadGuard<std::collections::BTreeMap<InfoHash, TorrentEntry>> {
        self.database.torrent_peers.read().unwrap()
    }

    pub fn save_database<W: std::io::Write>(&self, writer: &mut W) -> serde_json::Result<()> {
        use bzip2;

        let compressor = bzip2::write::BzEncoder::new(writer, bzip2::Compression::Best);

        let db_lock = self.database.torrent_peers.read().unwrap();

        let db = &*db_lock;

        serde_json::to_writer(compressor, &db)
    }

    fn cleanup(&self) {
        use std::ops::Add;

        let now = std::time::SystemTime::now();
        match self.database.torrent_peers.write() {
            Err(err) => {
                error!("failed to obtain write lock on database. err: {}", err);
                return;
            }
            Ok(mut db) => {
                let mut torrents_to_remove = Vec::new();

                for (k, v) in db.iter_mut() {
                    // timed-out peers..
                    {
                        let mut peers_to_remove = Vec::new();
                        let torrent_peers = &mut v.peers;

                        for (peer_id, state) in torrent_peers.iter() {
                            if state.updated.add(std::time::Duration::new(3600 * 2, 0)) < now {
                                // over 2 hours past since last update...
                                peers_to_remove.push(*peer_id);
                            }
                        }

                        for peer_id in peers_to_remove.iter() {
                            torrent_peers.remove(peer_id);
                        }
                    }

                    if self.mode == TrackerMode::DynamicMode {
                        // peer-less torrents..
                        if v.peers.len() == 0 {
                            torrents_to_remove.push(k.clone());
                        }
                    }
                }

                for info_hash in torrents_to_remove {
                    db.remove(&info_hash);
                }
            }
        }
    }

    pub fn periodic_task(&self, db_path: &str) {
        // cleanup db
        self.cleanup();

        // save db.
        match std::fs::File::create(db_path) {
            Err(err) => {
                error!("failed to open file '{}': {}", db_path, err);
                return;
            }
            Ok(mut file) => {
                if let Err(err) = self.save_database(&mut file) {
                    error!("failed saving database. {}", err);
                }
            }
        }
    }
}

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

    fn is_sync<T: Sync>() {}
    fn is_send<T: Send>() {}

    #[test]
    fn tracker_send() {
        is_send::<TorrentTracker>();
    }

    #[test]
    fn tracker_sync() {
        is_sync::<TorrentTracker>();
    }

    #[test]
    fn test_save_db() {
        let tracker = TorrentTracker::new(TrackerMode::DynamicMode);
        tracker.add_torrent(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0].into());

        let mut out = Vec::new();

        tracker.save_database(&mut out).unwrap();
        assert!(out.len() > 0);
    }

    #[test]
    fn test_infohash_de() {
        use serde_json;

        let ih: InfoHash = [0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1].into();

        let serialized_ih = serde_json::to_string(&ih).unwrap();

        let de_ih: InfoHash = serde_json::from_str(serialized_ih.as_str()).unwrap();

        assert!(de_ih == ih);
    }
}
<commit_msg>using journal file before overwriting previous db<commit_after>use binascii;
use serde;
use serde_json;
use std;

use server::Events;

#[derive(Deserialize, Clone, PartialEq)]
pub enum TrackerMode {
    /// In static mode torrents are tracked only if they were added ahead of time.
    #[serde(rename = "static")]
    StaticMode,

    /// In dynamic mode, torrents are tracked being added ahead of time.
    #[serde(rename = "dynamic")]
    DynamicMode,

    /// Tracker will only serve authenticated peers.
    #[serde(rename = "private")]
    PrivateMode,
}

struct TorrentPeer {
    ip: std::net::SocketAddr,
    uploaded: u64,
    downloaded: u64,
    left: u64,
    event: Events,
    updated: std::time::SystemTime,
}

#[derive(Ord, PartialEq, Eq, Clone)]
pub struct InfoHash {
    info_hash: [u8; 20],
}

impl std::cmp::PartialOrd<InfoHash> for InfoHash {
    fn partial_cmp(&self, other: &InfoHash) -> Option<std::cmp::Ordering> {
        self.info_hash.partial_cmp(&other.info_hash)
    }
}

impl std::convert::From<&[u8]> for InfoHash {
    fn from(data: &[u8]) -> InfoHash {
        assert_eq!(data.len(), 20);
        let mut ret = InfoHash{
            info_hash: [0u8; 20],
        };
        ret.info_hash.clone_from_slice(data);
        return ret;
    }
}

impl std::convert::Into<InfoHash> for [u8; 20] {
    fn into(self) -> InfoHash {
        InfoHash { info_hash: self }
    }
}

impl serde::ser::Serialize for InfoHash {
    fn serialize<S: serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        let mut buffer = [0u8; 40];
        let bytes_out = binascii::bin2hex(&self.info_hash, &mut buffer)
            .ok()
            .unwrap();
        let str_out = std::str::from_utf8(bytes_out).unwrap();

        serializer.serialize_str(str_out)
    }
}

struct InfoHashVisitor;

impl<'v> serde::de::Visitor<'v> for InfoHashVisitor {
    type Value = InfoHash;

    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(formatter, "a 40 character long hash")
    }

    fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
        if v.len() != 40 {
            return Err(serde::de::Error::invalid_value(
                serde::de::Unexpected::Str(v),
                &"expected a 40 character long string",
            ));
        }

        let mut res = InfoHash {
            info_hash: [0u8; 20],
        };

        if let Err(_) = binascii::hex2bin(v.as_bytes(), &mut res.info_hash) {
            return Err(serde::de::Error::invalid_value(
                serde::de::Unexpected::Str(v),
                &"expected a hexadecimal string",
            ));
        } else {
            return Ok(res);
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for InfoHash {
    fn deserialize<D: serde::de::Deserializer<'de>>(des: D) -> Result<Self, D::Error> {
        des.deserialize_str(InfoHashVisitor)
    }
}

pub type PeerId = [u8; 20];

#[derive(Serialize, Deserialize)]
pub struct TorrentEntry {
    is_flagged: bool,

    #[serde(skip)]
    peers: std::collections::BTreeMap<PeerId, TorrentPeer>,

    completed: u32,

    #[serde(skip)]
    seeders: u32,
}

impl TorrentEntry {
    pub fn new() -> TorrentEntry {
        TorrentEntry {
            is_flagged: false,
            peers: std::collections::BTreeMap::new(),
            completed: 0,
            seeders: 0,
        }
    }

    pub fn is_flagged(&self) -> bool {
        self.is_flagged
    }

    pub fn update_peer(
        &mut self,
        peer_id: &PeerId,
        remote_address: &std::net::SocketAddr,
        uploaded: u64,
        downloaded: u64,
        left: u64,
        event: Events,
    ) {
        let is_seeder = left == 0 && uploaded > 0;
        let mut was_seeder = false;
        let mut is_completed = left == 0 && (event as u32) == (Events::Complete as u32);
        if let Some(prev) = self.peers.insert(
            *peer_id,
            TorrentPeer {
                updated: std::time::SystemTime::now(),
                left,
                downloaded,
                uploaded,
                ip: *remote_address,
                event,
            },
        ) {
            was_seeder = prev.left == 0 && prev.uploaded > 0;

            if is_completed && (prev.event as u32) == (Events::Complete as u32) {
                // don't update count again. a torrent should only be updated once per peer.
                is_completed = false;
            }
        }

        if is_seeder && !was_seeder {
            self.seeders += 1;
        } else if was_seeder && !is_seeder {
            self.seeders -= 1;
        }

        if is_completed {
            self.completed += 1;
        }
    }

    pub fn get_peers(&self, remote_addr: &std::net::SocketAddr) -> Vec<std::net::SocketAddr> {
        let mut list = Vec::new();
        for (_, peer) in self
            .peers
            .iter()
            .filter(|e| e.1.ip.is_ipv4() == remote_addr.is_ipv4())
            .take(74)
        {
            if peer.ip == *remote_addr {
                continue;
            }

            list.push(peer.ip);
        }
        list
    }

    pub fn get_stats(&self) -> (u32, u32, u32) {
        let leechers = (self.peers.len() as u32) - self.seeders;
        (self.seeders, self.completed, leechers)
    }
}

struct TorrentDatabase {
    torrent_peers: std::sync::RwLock<std::collections::BTreeMap<InfoHash, TorrentEntry>>,
}

impl Default for TorrentDatabase {
    fn default() -> Self {
        TorrentDatabase {
            torrent_peers: std::sync::RwLock::new(std::collections::BTreeMap::new()),
        }
    }
}

pub struct TorrentTracker {
    mode: TrackerMode,
    database: TorrentDatabase,
}

pub enum TorrentStats {
    TorrentFlagged,
    TorrentNotRegistered,
    Stats {
        seeders: u32,
        leechers: u32,
        complete: u32,
    },
}

impl TorrentTracker {
    pub fn new(mode: TrackerMode) -> TorrentTracker {
        TorrentTracker {
            mode,
            database: TorrentDatabase {
                torrent_peers: std::sync::RwLock::new(std::collections::BTreeMap::new()),
            },
        }
    }

    pub fn load_database<R: std::io::Read>(
        mode: TrackerMode,
        reader: &mut R,
    ) -> serde_json::Result<TorrentTracker> {
        use bzip2;
        let decomp_reader = bzip2::read::BzDecoder::new(reader);
        let result: serde_json::Result<std::collections::BTreeMap<InfoHash, TorrentEntry>> =
            serde_json::from_reader(decomp_reader);
        match result {
            Ok(v) => Ok(TorrentTracker {
                mode,
                database: TorrentDatabase {
                    torrent_peers: std::sync::RwLock::new(v),
                },
            }),
            Err(e) => Err(e),
        }
    }

    /// Adding torrents is not relevant to dynamic trackers.
    pub fn add_torrent(&self, info_hash: &InfoHash) -> Result<(), ()> {
        let mut write_lock = self.database.torrent_peers.write().unwrap();
        match write_lock.entry(info_hash.clone()) {
            std::collections::btree_map::Entry::Vacant(ve) => {
                ve.insert(TorrentEntry::new());
                return Ok(());
            }
            std::collections::btree_map::Entry::Occupied(_entry) => {
                return Err(());
            }
        }
    }

    /// If the torrent is flagged, it will not be removed unless force is set to true.
    pub fn remove_torrent(&self, info_hash: &InfoHash, force: bool) -> Result<(), ()> {
        use std::collections::btree_map::Entry;
        let mut entry_lock = self.database.torrent_peers.write().unwrap();
        let torrent_entry = entry_lock.entry(info_hash.clone());
        match torrent_entry {
            Entry::Vacant(_) => {
                // no entry, nothing to do...
                return Err(());
            }
            Entry::Occupied(entry) => {
                if force || !entry.get().is_flagged() {
                    entry.remove();
                    return Ok(());
                }
                return Err(());
            }
        }
    }

    /// flagged torrents will result in a tracking error. This is to allow enforcement against piracy.
    pub fn set_torrent_flag(&self, info_hash: &InfoHash, is_flagged: bool) {
        if let Some(entry) = self
            .database
            .torrent_peers
            .write()
            .unwrap()
            .get_mut(info_hash)
        {
            if is_flagged && !entry.is_flagged {
                // empty peer list.
                entry.peers.clear();
            }
            entry.is_flagged = is_flagged;
        }
    }

    pub fn get_torrent_peers(
        &self,
        info_hash: &InfoHash,
        remote_addr: &std::net::SocketAddr,
    ) -> Option<Vec<std::net::SocketAddr>> {
        let read_lock = self.database.torrent_peers.read().unwrap();
        match read_lock.get(info_hash) {
            None => {
                return None;
            }
            Some(entry) => {
                return Some(entry.get_peers(remote_addr));
            }
        };
    }

    pub fn update_torrent_and_get_stats(
        &self,
        info_hash: &InfoHash,
        peer_id: &PeerId,
        remote_address: &std::net::SocketAddr,
        uploaded: u64,
        downloaded: u64,
        left: u64,
        event: Events,
    ) -> TorrentStats {
        use std::collections::btree_map::Entry;
        let mut torrent_peers = self.database.torrent_peers.write().unwrap();
        let torrent_entry = match torrent_peers.entry(info_hash.clone()) {
            Entry::Vacant(vacant) => match self.mode {
                TrackerMode::DynamicMode => vacant.insert(TorrentEntry::new()),
                _ => {
                    return TorrentStats::TorrentNotRegistered;
                }
            },
            Entry::Occupied(entry) => {
                if entry.get().is_flagged() {
                    return TorrentStats::TorrentFlagged;
                }
                entry.into_mut()
            }
        };

        torrent_entry.update_peer(peer_id, remote_address, uploaded, downloaded, left, event);

        let (seeders, complete, leechers) = torrent_entry.get_stats();

        return TorrentStats::Stats {
            seeders,
            leechers,
            complete,
        };
    }

    pub(crate) fn get_database(
        &self,
    ) -> std::sync::RwLockReadGuard<std::collections::BTreeMap<InfoHash, TorrentEntry>> {
        self.database.torrent_peers.read().unwrap()
    }

    pub fn save_database<W: std::io::Write>(&self, writer: &mut W) -> serde_json::Result<()> {
        use bzip2;

        let compressor = bzip2::write::BzEncoder::new(writer, bzip2::Compression::Best);

        let db_lock = self.database.torrent_peers.read().unwrap();

        let db = &*db_lock;

        serde_json::to_writer(compressor, &db)
    }

    fn cleanup(&self) {
        use std::ops::Add;

        let now = std::time::SystemTime::now();
        match self.database.torrent_peers.write() {
            Err(err) => {
                error!("failed to obtain write lock on database. err: {}", err);
                return;
            }
            Ok(mut db) => {
                let mut torrents_to_remove = Vec::new();

                for (k, v) in db.iter_mut() {
                    // timed-out peers..
                    {
                        let mut peers_to_remove = Vec::new();
                        let torrent_peers = &mut v.peers;

                        for (peer_id, state) in torrent_peers.iter() {
                            if state.updated.add(std::time::Duration::new(3600 * 2, 0)) < now {
                                // over 2 hours past since last update...
                                peers_to_remove.push(*peer_id);
                            }
                        }

                        for peer_id in peers_to_remove.iter() {
                            torrent_peers.remove(peer_id);
                        }
                    }

                    if self.mode == TrackerMode::DynamicMode {
                        // peer-less torrents..
                        if v.peers.len() == 0 {
                            torrents_to_remove.push(k.clone());
                        }
                    }
                }

                for info_hash in torrents_to_remove {
                    db.remove(&info_hash);
                }
            }
        }
    }

    pub fn periodic_task(&self, db_path: &str) {
        // cleanup db
        self.cleanup();

        // save journal db.
        let mut journal_path = std::path::PathBuf::from(db_path);

        let mut filename = String::from(journal_path.file_name().unwrap().to_str().unwrap());
        filename.push_str("-journal");

        journal_path.set_file_name(filename.as_str());
        let jp_str = journal_path.as_path().to_str().unwrap();

        // scope to make sure backup file is dropped/closed.
        {
            let mut file = match std::fs::File::create(jp_str) {
                Err(err) => {
                    error!("failed to open file '{}': {}", db_path, err);
                    return;
                }
                Ok(v) => v,
            };
            trace!("writing database to {}", jp_str);
            if let Err(err) = self.save_database(&mut file) {
                error!("failed saving database. {}", err);
                return;
            }
        }

        // overwrite previous db
        trace!("renaming '{}' to '{}'", jp_str, db_path);
        if let Err(err) = std::fs::rename(jp_str, db_path) {
            error!("failed to move db backup. {}", err);
        }
    }
}

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

    fn is_sync<T: Sync>() {}
    fn is_send<T: Send>() {}

    #[test]
    fn tracker_send() {
        is_send::<TorrentTracker>();
    }

    #[test]
    fn tracker_sync() {
        is_sync::<TorrentTracker>();
    }

    #[test]
    fn test_save_db() {
        let tracker = TorrentTracker::new(TrackerMode::DynamicMode);
        tracker.add_torrent(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0].into());

        let mut out = Vec::new();

        tracker.save_database(&mut out).unwrap();
        assert!(out.len() > 0);
    }

    #[test]
    fn test_infohash_de() {
        use serde_json;

        let ih: InfoHash = [0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1].into();

        let serialized_ih = serde_json::to_string(&ih).unwrap();

        let de_ih: InfoHash = serde_json::from_str(serialized_ih.as_str()).unwrap();

        assert!(de_ih == ih);
    }
}
<|endoftext|>


<commit_before><commit_msg>update !emotes command and might remove bot ping command<commit_after><|endoftext|>


<commit_before><commit_msg>Update 'Fairing' example to reflect doc's content.<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for discriminant_value results<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

extern crate core;
use core::intrinsics::discriminant_value;

enum CLike1 {
    A,
    B,
    C,
    D
}

enum CLike2 {
    A = 5,
    B = 2,
    C = 19,
    D
}

enum ADT {
    First(u32, u32),
    Second(u64)
}

enum NullablePointer {
    Something(&'static u32),
    Nothing
}

static CONST : u32 = 0xBEEF;

pub fn main() {
    unsafe {

        assert_eq!(discriminant_value(&CLike1::A), 0);
        assert_eq!(discriminant_value(&CLike1::B), 1);
        assert_eq!(discriminant_value(&CLike1::C), 2);
        assert_eq!(discriminant_value(&CLike1::D), 3);

        assert_eq!(discriminant_value(&CLike2::A), 5);
        assert_eq!(discriminant_value(&CLike2::B), 2);
        assert_eq!(discriminant_value(&CLike2::C), 19);
        assert_eq!(discriminant_value(&CLike2::D), 20);

        assert_eq!(discriminant_value(&ADT::First(0,0)), 0);
        assert_eq!(discriminant_value(&ADT::Second(5)), 1);

        assert_eq!(discriminant_value(&NullablePointer::Nothing), 1);
        assert_eq!(discriminant_value(&NullablePointer::Something(&CONST)), 0);

        assert_eq!(discriminant_value(&10), 0);
        assert_eq!(discriminant_value(&"test"), 0);
    }
}
<|endoftext|>


<commit_before><commit_msg>Use two sets of Vertex Buffers on Vulkan, one set for each swapchain image<commit_after><|endoftext|>


<commit_before><commit_msg>Add basic game data types<commit_after>pub struct Game {
    name: String,
    original_platforms: Vec<String>
}

pub struct GameEdition {
    game: Game,
    name: String,
    platform: String
}

pub struct GameContent {
    game: Game,
    name: String,
}

pub struct ContentEdition {
    content: GameContent,
    edition: GameEdition
}
<|endoftext|>


<commit_before><commit_msg>the binary<commit_after>extern crate sendgrid;
extern crate time;

use sendgrid::mail::Mail;
use sendgrid::sg_client::SGClient;

fn main() {
    let mut env_vars = std::env::vars();
    let api_key_check = env_vars.find(|var| var.0 == "SENDGRID_API_KEY");
    let api_key: String;
    match api_key_check {
        Some(key) => api_key = key.1,
        None => panic!("Must supply API key in environment variables to use!"),
    }

    let sg = SGClient::new(api_key);

    let mut mail_info = Mail::new();
    mail_info.add_to("garrettsquire@gmail.com");
    mail_info.add_from("garrett.squire@sendgrid.net");
    mail_info.add_subject("Rust is rad");
    mail_info.add_text("What's up?");

    let mut x_smtpapi = String::new();
    x_smtpapi.push_str("{\"unique_args\":{\"test\":7}}");
    mail_info.add_x_smtpapi(x_smtpapi);

    sg.send(mail_info);
}
<|endoftext|>


<commit_before><commit_msg>Code refractoring<commit_after><|endoftext|>


<commit_before><commit_msg>Added ability to parge "-g" command-line option. Previously tspga could only run a fixed number of generations once compiled. Now the user can supply any number.<commit_after><|endoftext|>


<commit_before><commit_msg>Added logging<commit_after><|endoftext|>


<commit_before><commit_msg>ルーティングの仕組みを追加<commit_after><|endoftext|>


<commit_before><commit_msg>Add text<commit_after><|endoftext|>


<commit_before><commit_msg>Adding abstract template<commit_after>
namespace MyProject

class MyClass inherits Object implements Object

	properties:

		class:

		public:

		protected:

		private:

	methods:

		class:

		public:

		protected:

		private:

<|endoftext|>


<commit_before><commit_msg>rust: The Feast of Many Beasts<commit_after><|endoftext|>


<commit_before>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

//! Interfaces to the operating system provided random number
//! generators.

pub use self::imp::OsRng;

#[cfg(all(unix, not(target_os = "ios")))]
mod imp {
    extern crate libc;

    use self::OsRngInner::*;

    use io::{IoResult, File};
    use path::Path;
    use rand::Rng;
    use rand::reader::ReaderRng;
    use result::Result::{Ok, Err};
    use slice::SliceExt;
    use mem;
    use os::errno;

    #[cfg(all(target_os = "linux",
              any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))]
    fn getrandom(buf: &mut [u8]) -> libc::c_long {
        extern "C" {
            fn syscall(number: libc::c_long, ...) -> libc::c_long;
        }

        #[cfg(target_arch = "x86_64")]
        const NR_GETRANDOM: libc::c_long = 318;
        #[cfg(target_arch = "x86")]
        const NR_GETRANDOM: libc::c_long = 355;
        #[cfg(target_arch = "arm")]
        const NR_GETRANDOM: libc::c_long = 384;

        unsafe {
            syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0u)
        }
    }

    #[cfg(not(all(target_os = "linux",
                  any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm"))))]
    fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }

    fn getrandom_fill_bytes(v: &mut [u8]) {
        let mut read = 0;
        let len = v.len();
        while read < len {
            let result = getrandom(v.slice_from_mut(read));
            if result == -1 {
                let err = errno() as libc::c_int;
                if err == libc::EINTR {
                    continue;
                } else {
                    panic!("unexpected getrandom error: {}", err);
                }
            } else {
                read += result as uint;
            }
        }
    }

    fn getrandom_next_u32() -> u32 {
        let mut buf: [u8, ..4] = [0u8, ..4];
        getrandom_fill_bytes(&mut buf);
        unsafe { mem::transmute::<[u8, ..4], u32>(buf) }
    }

    fn getrandom_next_u64() -> u64 {
        let mut buf: [u8, ..8] = [0u8, ..8];
        getrandom_fill_bytes(&mut buf);
        unsafe { mem::transmute::<[u8, ..8], u64>(buf) }
    }

    #[cfg(all(target_os = "linux",
              any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))]
    fn is_getrandom_available() -> bool {
        use sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, Relaxed};

        static GETRANDOM_CHECKED: AtomicBool = INIT_ATOMIC_BOOL;
        static GETRANDOM_AVAILABLE: AtomicBool = INIT_ATOMIC_BOOL;

        if !GETRANDOM_CHECKED.load(Relaxed) {
            let mut buf: [u8, ..0] = [];
            let result = getrandom(&mut buf);
            let available = if result == -1 {
                let err = errno() as libc::c_int;
                err != libc::ENOSYS
            } else {
                true
            };
            GETRANDOM_AVAILABLE.store(available, Relaxed);
            GETRANDOM_CHECKED.store(true, Relaxed);
            available
        } else {
            GETRANDOM_AVAILABLE.load(Relaxed)
        }
    }

    #[cfg(not(all(target_os = "linux",
                  any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm"))))]
    fn is_getrandom_available() -> bool { false }

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
    ///
    /// This does not block.
    pub struct OsRng {
        inner: OsRngInner,
    }

    enum OsRngInner {
        OsGetrandomRng,
        OsReaderRng(ReaderRng<File>),
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> IoResult<OsRng> {
            if is_getrandom_available() {
                return Ok(OsRng { inner: OsGetrandomRng });
            }

            let reader = try!(File::open(&Path::new("/dev/urandom")));
            let reader_rng = ReaderRng::new(reader);

            Ok(OsRng { inner: OsReaderRng(reader_rng) })
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            match self.inner {
                OsGetrandomRng => getrandom_next_u32(),
                OsReaderRng(ref mut rng) => rng.next_u32(),
            }
        }
        fn next_u64(&mut self) -> u64 {
            match self.inner {
                OsGetrandomRng => getrandom_next_u64(),
                OsReaderRng(ref mut rng) => rng.next_u64(),
            }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            match self.inner {
                OsGetrandomRng => getrandom_fill_bytes(v),
                OsReaderRng(ref mut rng) => rng.fill_bytes(v)
            }
        }
    }
}

#[cfg(target_os = "ios")]
mod imp {
    extern crate libc;

    use io::{IoResult};
    use mem;
    use os;
    use rand::Rng;
    use result::Result::{Ok};
    use self::libc::{c_int, size_t};
    use slice::SliceExt;

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
    ///
    /// This does not block.
    #[allow(missing_copy_implementations)]
    pub struct OsRng {
        // dummy field to ensure that this struct cannot be constructed outside of this module
        _dummy: (),
    }

    #[repr(C)]
    struct SecRandom;

    #[allow(non_upper_case_globals)]
    static kSecRandomDefault: *const SecRandom = 0 as *const SecRandom;

    #[link(name = "Security", kind = "framework")]
    extern "C" {
        fn SecRandomCopyBytes(rnd: *const SecRandom,
                              count: size_t, bytes: *mut u8) -> c_int;
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> IoResult<OsRng> {
            Ok(OsRng { _dummy: () })
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            let mut v = [0u8, .. 4];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn next_u64(&mut self) -> u64 {
            let mut v = [0u8, .. 8];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            let ret = unsafe {
                SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t, v.as_mut_ptr())
            };
            if ret == -1 {
                panic!("couldn't generate random bytes: {}", os::last_os_error());
            }
        }
    }
}

#[cfg(windows)]
mod imp {
    extern crate libc;

    use io::{IoResult, IoError};
    use mem;
    use ops::Drop;
    use os;
    use rand::Rng;
    use result::Result::{Ok, Err};
    use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
    use self::libc::types::os::arch::extra::{LONG_PTR};
    use slice::SliceExt;

    type HCRYPTPROV = LONG_PTR;

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
    ///
    /// This does not block.
    pub struct OsRng {
        hcryptprov: HCRYPTPROV
    }

    static PROV_RSA_FULL: DWORD = 1;
    static CRYPT_SILENT: DWORD = 64;
    static CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;

    #[allow(non_snake_case)]
    extern "system" {
        fn CryptAcquireContextA(phProv: *mut HCRYPTPROV,
                                pszContainer: LPCSTR,
                                pszProvider: LPCSTR,
                                dwProvType: DWORD,
                                dwFlags: DWORD) -> BOOL;
        fn CryptGenRandom(hProv: HCRYPTPROV,
                          dwLen: DWORD,
                          pbBuffer: *mut BYTE) -> BOOL;
        fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> IoResult<OsRng> {
            let mut hcp = 0;
            let ret = unsafe {
                CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
                                     PROV_RSA_FULL,
                                     CRYPT_VERIFYCONTEXT | CRYPT_SILENT)
            };

            if ret == 0 {
                Err(IoError::last_error())
            } else {
                Ok(OsRng { hcryptprov: hcp })
            }
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            let mut v = [0u8, .. 4];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn next_u64(&mut self) -> u64 {
            let mut v = [0u8, .. 8];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            let ret = unsafe {
                CryptGenRandom(self.hcryptprov, v.len() as DWORD,
                               v.as_mut_ptr())
            };
            if ret == 0 {
                panic!("couldn't generate random bytes: {}", os::last_os_error());
            }
        }
    }

    impl Drop for OsRng {
        fn drop(&mut self) {
            let ret = unsafe {
                CryptReleaseContext(self.hcryptprov, 0)
            };
            if ret == 0 {
                panic!("couldn't release context: {}", os::last_os_error());
            }
        }
    }
}

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

    use super::OsRng;
    use rand::Rng;
    use thread::Thread;

    #[test]
    fn test_os_rng() {
        let mut r = OsRng::new().unwrap();

        r.next_u32();
        r.next_u64();

        let mut v = [0u8, .. 1000];
        r.fill_bytes(&mut v);
    }

    #[test]
    fn test_os_rng_tasks() {

        let mut txs = vec!();
        for _ in range(0u, 20) {
            let (tx, rx) = channel();
            txs.push(tx);

            Thread::spawn(move|| {
                // wait until all the tasks are ready to go.
                rx.recv();

                // deschedule to attempt to interleave things as much
                // as possible (XXX: is this a good test?)
                let mut r = OsRng::new().unwrap();
                Thread::yield_now();
                let mut v = [0u8, .. 1000];

                for _ in range(0u, 100) {
                    r.next_u32();
                    Thread::yield_now();
                    r.next_u64();
                    Thread::yield_now();
                    r.fill_bytes(&mut v);
                    Thread::yield_now();
                }
            }).detach();
        }

        // start all the tasks
        for tx in txs.iter() {
            tx.send(())
        }
    }
}
<commit_msg>rollup merge of #20329: vhbit/ios-rand-fix<commit_after>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

//! Interfaces to the operating system provided random number
//! generators.

pub use self::imp::OsRng;

#[cfg(all(unix, not(target_os = "ios")))]
mod imp {
    extern crate libc;

    use self::OsRngInner::*;

    use io::{IoResult, File};
    use path::Path;
    use rand::Rng;
    use rand::reader::ReaderRng;
    use result::Result::{Ok, Err};
    use slice::SliceExt;
    use mem;
    use os::errno;

    #[cfg(all(target_os = "linux",
              any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))]
    fn getrandom(buf: &mut [u8]) -> libc::c_long {
        extern "C" {
            fn syscall(number: libc::c_long, ...) -> libc::c_long;
        }

        #[cfg(target_arch = "x86_64")]
        const NR_GETRANDOM: libc::c_long = 318;
        #[cfg(target_arch = "x86")]
        const NR_GETRANDOM: libc::c_long = 355;
        #[cfg(target_arch = "arm")]
        const NR_GETRANDOM: libc::c_long = 384;

        unsafe {
            syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0u)
        }
    }

    #[cfg(not(all(target_os = "linux",
                  any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm"))))]
    fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }

    fn getrandom_fill_bytes(v: &mut [u8]) {
        let mut read = 0;
        let len = v.len();
        while read < len {
            let result = getrandom(v.slice_from_mut(read));
            if result == -1 {
                let err = errno() as libc::c_int;
                if err == libc::EINTR {
                    continue;
                } else {
                    panic!("unexpected getrandom error: {}", err);
                }
            } else {
                read += result as uint;
            }
        }
    }

    fn getrandom_next_u32() -> u32 {
        let mut buf: [u8, ..4] = [0u8, ..4];
        getrandom_fill_bytes(&mut buf);
        unsafe { mem::transmute::<[u8, ..4], u32>(buf) }
    }

    fn getrandom_next_u64() -> u64 {
        let mut buf: [u8, ..8] = [0u8, ..8];
        getrandom_fill_bytes(&mut buf);
        unsafe { mem::transmute::<[u8, ..8], u64>(buf) }
    }

    #[cfg(all(target_os = "linux",
              any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))]
    fn is_getrandom_available() -> bool {
        use sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, Relaxed};

        static GETRANDOM_CHECKED: AtomicBool = INIT_ATOMIC_BOOL;
        static GETRANDOM_AVAILABLE: AtomicBool = INIT_ATOMIC_BOOL;

        if !GETRANDOM_CHECKED.load(Relaxed) {
            let mut buf: [u8, ..0] = [];
            let result = getrandom(&mut buf);
            let available = if result == -1 {
                let err = errno() as libc::c_int;
                err != libc::ENOSYS
            } else {
                true
            };
            GETRANDOM_AVAILABLE.store(available, Relaxed);
            GETRANDOM_CHECKED.store(true, Relaxed);
            available
        } else {
            GETRANDOM_AVAILABLE.load(Relaxed)
        }
    }

    #[cfg(not(all(target_os = "linux",
                  any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm"))))]
    fn is_getrandom_available() -> bool { false }

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
    ///
    /// This does not block.
    pub struct OsRng {
        inner: OsRngInner,
    }

    enum OsRngInner {
        OsGetrandomRng,
        OsReaderRng(ReaderRng<File>),
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> IoResult<OsRng> {
            if is_getrandom_available() {
                return Ok(OsRng { inner: OsGetrandomRng });
            }

            let reader = try!(File::open(&Path::new("/dev/urandom")));
            let reader_rng = ReaderRng::new(reader);

            Ok(OsRng { inner: OsReaderRng(reader_rng) })
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            match self.inner {
                OsGetrandomRng => getrandom_next_u32(),
                OsReaderRng(ref mut rng) => rng.next_u32(),
            }
        }
        fn next_u64(&mut self) -> u64 {
            match self.inner {
                OsGetrandomRng => getrandom_next_u64(),
                OsReaderRng(ref mut rng) => rng.next_u64(),
            }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            match self.inner {
                OsGetrandomRng => getrandom_fill_bytes(v),
                OsReaderRng(ref mut rng) => rng.fill_bytes(v)
            }
        }
    }
}

#[cfg(target_os = "ios")]
mod imp {
    extern crate libc;

    use io::{IoResult};
    use kinds::Sync;
    use mem;
    use os;
    use rand::Rng;
    use result::Result::{Ok};
    use self::libc::{c_int, size_t};
    use slice::SliceExt;

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
    ///
    /// This does not block.
    #[allow(missing_copy_implementations)]
    pub struct OsRng {
        // dummy field to ensure that this struct cannot be constructed outside of this module
        _dummy: (),
    }

    #[repr(C)]
    struct SecRandom;

    unsafe impl Sync for *const SecRandom {}

    #[allow(non_upper_case_globals)]
    static kSecRandomDefault: *const SecRandom = 0 as *const SecRandom;

    #[link(name = "Security", kind = "framework")]
    extern "C" {
        fn SecRandomCopyBytes(rnd: *const SecRandom,
                              count: size_t, bytes: *mut u8) -> c_int;
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> IoResult<OsRng> {
            Ok(OsRng { _dummy: () })
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            let mut v = [0u8, .. 4];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn next_u64(&mut self) -> u64 {
            let mut v = [0u8, .. 8];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            let ret = unsafe {
                SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t, v.as_mut_ptr())
            };
            if ret == -1 {
                panic!("couldn't generate random bytes: {}", os::last_os_error());
            }
        }
    }
}

#[cfg(windows)]
mod imp {
    extern crate libc;

    use io::{IoResult, IoError};
    use mem;
    use ops::Drop;
    use os;
    use rand::Rng;
    use result::Result::{Ok, Err};
    use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
    use self::libc::types::os::arch::extra::{LONG_PTR};
    use slice::SliceExt;

    type HCRYPTPROV = LONG_PTR;

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
    ///
    /// This does not block.
    pub struct OsRng {
        hcryptprov: HCRYPTPROV
    }

    static PROV_RSA_FULL: DWORD = 1;
    static CRYPT_SILENT: DWORD = 64;
    static CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;

    #[allow(non_snake_case)]
    extern "system" {
        fn CryptAcquireContextA(phProv: *mut HCRYPTPROV,
                                pszContainer: LPCSTR,
                                pszProvider: LPCSTR,
                                dwProvType: DWORD,
                                dwFlags: DWORD) -> BOOL;
        fn CryptGenRandom(hProv: HCRYPTPROV,
                          dwLen: DWORD,
                          pbBuffer: *mut BYTE) -> BOOL;
        fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> IoResult<OsRng> {
            let mut hcp = 0;
            let ret = unsafe {
                CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
                                     PROV_RSA_FULL,
                                     CRYPT_VERIFYCONTEXT | CRYPT_SILENT)
            };

            if ret == 0 {
                Err(IoError::last_error())
            } else {
                Ok(OsRng { hcryptprov: hcp })
            }
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            let mut v = [0u8, .. 4];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn next_u64(&mut self) -> u64 {
            let mut v = [0u8, .. 8];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            let ret = unsafe {
                CryptGenRandom(self.hcryptprov, v.len() as DWORD,
                               v.as_mut_ptr())
            };
            if ret == 0 {
                panic!("couldn't generate random bytes: {}", os::last_os_error());
            }
        }
    }

    impl Drop for OsRng {
        fn drop(&mut self) {
            let ret = unsafe {
                CryptReleaseContext(self.hcryptprov, 0)
            };
            if ret == 0 {
                panic!("couldn't release context: {}", os::last_os_error());
            }
        }
    }
}

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

    use super::OsRng;
    use rand::Rng;
    use thread::Thread;

    #[test]
    fn test_os_rng() {
        let mut r = OsRng::new().unwrap();

        r.next_u32();
        r.next_u64();

        let mut v = [0u8, .. 1000];
        r.fill_bytes(&mut v);
    }

    #[test]
    fn test_os_rng_tasks() {

        let mut txs = vec!();
        for _ in range(0u, 20) {
            let (tx, rx) = channel();
            txs.push(tx);

            Thread::spawn(move|| {
                // wait until all the tasks are ready to go.
                rx.recv();

                // deschedule to attempt to interleave things as much
                // as possible (XXX: is this a good test?)
                let mut r = OsRng::new().unwrap();
                Thread::yield_now();
                let mut v = [0u8, .. 1000];

                for _ in range(0u, 100) {
                    r.next_u32();
                    Thread::yield_now();
                    r.next_u64();
                    Thread::yield_now();
                    r.fill_bytes(&mut v);
                    Thread::yield_now();
                }
            }).detach();
        }

        // start all the tasks
        for tx in txs.iter() {
            tx.send(())
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Move to https://github.com/huonw/rust-malloc/blob/master/zero.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Update sync endpoint<commit_after><|endoftext|>