<commit_before>#[macro_use]
extern crate clap;
#[macro_use]
extern crate log;
extern crate bitcrust_net;
extern crate simple_logger;
extern crate multiqueue;
extern crate ring;
extern crate rusqlite;
#[macro_use] extern crate serde_derive;
extern crate serde;
extern crate toml;

use std::thread;
use std::time::Duration;

use bitcrust_net::{BitcoinNetworkConnection, BitcoinNetworkError, Message, AuthenticatedBitcrustMessage};

use clap::{App, Arg, ArgMatches, SubCommand};

mod client_message;
mod config;
mod peer_manager;
mod peer;

use config::Config;
use peer_manager::PeerManager;

fn main() {
    let matches = App::new("bitcrustd")
        .version(crate_version!())
        .author("Chris M., Tomas W.")
        .arg(Arg::with_name("config")
            .short("c")
            .takes_value(true)
            .help("Location of the Bitcrust Config File, default: $HOME/.bitcrust.toml"))
        .arg(Arg::with_name("debug")
            .short("d")
            .multiple(true)
            .help("Turn debugging information on"))
        .subcommand(SubCommand::with_name("node").about("Bitcrust peer node"))
        .subcommand(SubCommand::with_name("stats")
            .about("Get stats from a running Bitcrust node")
            .arg(Arg::with_name("host")
                .short("h")
                .takes_value(true))
            .subcommand(SubCommand::with_name("peers"))
        )
        .subcommand(SubCommand::with_name("balance")
            .about("Get balance for address")
            .arg(Arg::with_name("address")
                .short("a")
                .help("Address to get balance for")
                .takes_value(true)
                .required(true))
        )
        .get_matches();

    let config = Config::from_args(&matches);

    match matches.subcommand() {
        ("node", Some(node_matches)) => {
            simple_logger::init_with_level(config.log_level).expect("Couldn't initialize logger");
            node(node_matches, &config);
        }
        ("balance", Some(balance_matches)) => {
            balance(balance_matches, &config);
        }
        ("stats", Some(stats_matches)) => {
            stats(stats_matches, &config);
        }
        ("", None) => println!("No subcommand was used"), // If no subcommand was usd it'll match the tuple ("", None)
        _ => unreachable!(), // If all subcommands are defined above, anything else is unreachabe!()
    }
}

fn node(_matches: &ArgMatches, config: &Config) {
    let mut client = PeerManager::new(config);
    client.execute();
}

fn balance(matches: &ArgMatches, _config: &Config) {
    // This unwrap is safe because we require it above
    let address = matches.value_of("address").unwrap();
    println!("I'd love to get your balance on '{}' but it's not yet implemented!", address);
}

fn stats(matches: &ArgMatches, config: &Config) {
    let host = matches.value_of("host").unwrap_or("127.0.0.1:8333").to_string();
    match matches.subcommand() {
        ("peers", Some(peer_matches)) => {
            connected_peers(peer_matches, config, host);
        }
        ("", None) => println!("No subcommand was used"), // If no subcommand was usd it'll match the tuple ("", None)
        _ => unreachable!(), // If all subcommands are defined above, anything else is unreachabe!()
    }
}

fn connected_peers(_matches: &ArgMatches, config: &Config, host: String) {
    let connection = BitcoinNetworkConnection::new(host.clone())
        .expect(&format!("Couldn't connect to a node running on {}", host));
    let _ = connection.try_send(peer::Peer::version());
    loop {
        if let Some(msg) = connection.try_recv() {
            match msg {
                Ok(msg) => match msg {
                    Message::Version(_version) => {
                        let _ = connection.try_send(Message::Verack);
                        break;
                    }
                    _ => {}
                },
                Err(BitcoinNetworkError::ReadTimeout) => thread::sleep(Duration::from_millis(200)),
                Err(BitcoinNetworkError::Closed) => {
                    println!("Remote server closed the connection");
                    return
                }
                Err(BitcoinNetworkError::BadBytes) => return
            }
        }
    }
    let auth = AuthenticatedBitcrustMessage::create(config.key());
    println!("About to send {:?}", auth);
    match connection.try_send(Message::BitcrustPeerCountRequest(auth)) {
        Ok(_) => {},
        Err(e) => warn!("Error sending request: {:?}", e),
    }
    loop {
        if let Some(msg) = connection.try_recv() {
            match msg {
                Ok(msg) => match msg {
                    Message::BitcrustPeerCount(count) => {
                        println!("There are {} peers currently connected to {}", count, host);
                        break;
                    }
                    _ => {}
                },
                Err(BitcoinNetworkError::ReadTimeout) => thread::sleep(Duration::from_millis(200)),
                Err(BitcoinNetworkError::Closed) => {
                    println!("Remote server closed the connection");
                    return
                }
                Err(BitcoinNetworkError::BadBytes) => return
            }
        }
    }
}<commit_msg>remove erroneous print<commit_after>#[macro_use]
extern crate clap;
#[macro_use]
extern crate log;
extern crate bitcrust_net;
extern crate simple_logger;
extern crate multiqueue;
extern crate ring;
extern crate rusqlite;
#[macro_use] extern crate serde_derive;
extern crate serde;
extern crate toml;

use std::thread;
use std::time::Duration;

use bitcrust_net::{BitcoinNetworkConnection, BitcoinNetworkError, Message, AuthenticatedBitcrustMessage};

use clap::{App, Arg, ArgMatches, SubCommand};

mod client_message;
mod config;
mod peer_manager;
mod peer;

use config::Config;
use peer_manager::PeerManager;

fn main() {
    let matches = App::new("bitcrustd")
        .version(crate_version!())
        .author("Chris M., Tomas W.")
        .arg(Arg::with_name("config")
            .short("c")
            .takes_value(true)
            .help("Location of the Bitcrust Config File, default: $HOME/.bitcrust.toml"))
        .arg(Arg::with_name("debug")
            .short("d")
            .multiple(true)
            .help("Turn debugging information on"))
        .subcommand(SubCommand::with_name("node").about("Bitcrust peer node"))
        .subcommand(SubCommand::with_name("stats")
            .about("Get stats from a running Bitcrust node")
            .arg(Arg::with_name("host")
                .short("h")
                .takes_value(true))
            .subcommand(SubCommand::with_name("peers"))
        )
        .subcommand(SubCommand::with_name("balance")
            .about("Get balance for address")
            .arg(Arg::with_name("address")
                .short("a")
                .help("Address to get balance for")
                .takes_value(true)
                .required(true))
        )
        .get_matches();

    let config = Config::from_args(&matches);

    match matches.subcommand() {
        ("node", Some(node_matches)) => {
            simple_logger::init_with_level(config.log_level).expect("Couldn't initialize logger");
            node(node_matches, &config);
        }
        ("balance", Some(balance_matches)) => {
            balance(balance_matches, &config);
        }
        ("stats", Some(stats_matches)) => {
            stats(stats_matches, &config);
        }
        ("", None) => println!("No subcommand was used"), // If no subcommand was usd it'll match the tuple ("", None)
        _ => unreachable!(), // If all subcommands are defined above, anything else is unreachabe!()
    }
}

fn node(_matches: &ArgMatches, config: &Config) {
    let mut client = PeerManager::new(config);
    client.execute();
}

fn balance(matches: &ArgMatches, _config: &Config) {
    // This unwrap is safe because we require it above
    let address = matches.value_of("address").unwrap();
    println!("I'd love to get your balance on '{}' but it's not yet implemented!", address);
}

fn stats(matches: &ArgMatches, config: &Config) {
    let host = matches.value_of("host").unwrap_or("127.0.0.1:8333").to_string();
    match matches.subcommand() {
        ("peers", Some(peer_matches)) => {
            connected_peers(peer_matches, config, host);
        }
        ("", None) => println!("No subcommand was used"), // If no subcommand was usd it'll match the tuple ("", None)
        _ => unreachable!(), // If all subcommands are defined above, anything else is unreachabe!()
    }
}

fn connected_peers(_matches: &ArgMatches, config: &Config, host: String) {
    let connection = BitcoinNetworkConnection::new(host.clone())
        .expect(&format!("Couldn't connect to a node running on {}", host));
    let _ = connection.try_send(peer::Peer::version());
    loop {
        if let Some(msg) = connection.try_recv() {
            match msg {
                Ok(msg) => match msg {
                    Message::Version(_version) => {
                        let _ = connection.try_send(Message::Verack);
                        break;
                    }
                    _ => {}
                },
                Err(BitcoinNetworkError::ReadTimeout) => thread::sleep(Duration::from_millis(200)),
                Err(BitcoinNetworkError::Closed) => {
                    println!("Remote server closed the connection");
                    return
                }
                Err(BitcoinNetworkError::BadBytes) => return
            }
        }
    }
    let auth = AuthenticatedBitcrustMessage::create(config.key());
    match connection.try_send(Message::BitcrustPeerCountRequest(auth)) {
        Ok(_) => {},
        Err(e) => warn!("Error sending request: {:?}", e),
    }
    loop {
        if let Some(msg) = connection.try_recv() {
            match msg {
                Ok(msg) => match msg {
                    Message::BitcrustPeerCount(count) => {
                        println!("There are {} peers currently connected to {}", count, host);
                        break;
                    }
                    _ => {}
                },
                Err(BitcoinNetworkError::ReadTimeout) => thread::sleep(Duration::from_millis(200)),
                Err(BitcoinNetworkError::Closed) => {
                    println!("Remote server closed the connection");
                    return
                }
                Err(BitcoinNetworkError::BadBytes) => return
            }
        }
    }
}<|endoftext|>


<commit_before>use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};

use serde_yaml;
use chrono::{DateTime, Local};

use errors::{Error, Result};
use utils::markdown_to_html;

/// blog post headers
///
/// the blog post headers is parsed using yaml format.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PostHeaders {
    /// post created local time, `created: 1970-01-01T00:00:00+08:00`
    pub created: DateTime<Local>,
    /// post hidden flag, `hidden: true`, default `false`
    #[serde(default)]
    pub hidden: bool,
    /// post tags, `tags: [hello, world]`, default `[]`
    #[serde(default)]
    pub tags: Vec<String>,
}

/// blog post
///
/// every blog post is composed of `head` part and `body` part.
/// the two part is separated by the first blank line.
#[derive(Serialize)]
pub struct Post {
    /// blog root path
    root: PathBuf,
    /// post path from relative root directory
    pub path: PathBuf,
    /// the post title
    pub title: String,
    /// the post url
    pub url: PathBuf,
    /// post headers
    pub headers: PostHeaders,
    /// post html body
    pub content: String,
}

impl Post {
    pub fn new<P: AsRef<Path>>(root: P, path: P) -> Result<Post> {
        let root = root.as_ref();
        let path = path.as_ref();
        debug!("loading post: {}", path.display());

        let fp = root.join(&path);
        let mut fo = File::open(fp)?;
        let mut content = String::new();
        fo.read_to_string(&mut content)?;

        let v: Vec<&str> = content.splitn(2, "\n\n").collect();
        if v.len() != 2 {
            return Err(Error::PostOnlyOnePart(path.into()));
        }
        let head = v[0].trim();
        let body = v[1].trim();
        if head.is_empty() {
            return Err(Error::PostNoHead(path.into()));
        }
        if head.is_empty() {
            return Err(Error::PostNoBody(path.into()));
        }

        let title = path.file_stem()
                        .and_then(|x| x.to_str())
                        .expect(&format!("post filename format error: {}", path.display()));
        let url = Path::new("/").join(path).with_extension("html");
        let headers: PostHeaders = serde_yaml::from_str(head)?;
        let content = markdown_to_html(body);

        Ok(Post {
            root: root.to_owned(),
            path: path.to_owned(),
            title: title.to_owned(),
            url: url,
            headers: headers,
            content: content,
        })
    }

    /// the absolute path of blog post markdown file.
    pub fn src(&self) -> PathBuf {
        self.root.join(&self.path)
    }

    /// the absolute path of blog post html file.
    pub fn dest(&self) -> PathBuf {
        self.path.with_extension("html")
    }
}
<commit_msg>fix #20: add `description` blog header<commit_after>use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};

use serde_yaml;
use chrono::{DateTime, Local};

use errors::{Error, Result};
use utils::markdown_to_html;

/// blog post headers
///
/// the blog post headers is parsed using yaml format.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PostHeaders {
    /// post created local time, `created: 1970-01-01T00:00:00+08:00`
    pub created: DateTime<Local>,
    /// post hidden flag, `hidden: true`, default `false`
    #[serde(default)]
    pub hidden: bool,
    /// post tags, `tags: [hello, world]`, default `[]`
    #[serde(default)]
    pub tags: Vec<String>,
    /// post description
    #[serde(default)]
    pub description: String,
}

/// blog post
///
/// every blog post is composed of `head` part and `body` part.
/// the two part is separated by the first blank line.
#[derive(Serialize)]
pub struct Post {
    /// blog root path
    root: PathBuf,
    /// post path from relative root directory
    pub path: PathBuf,
    /// the post title
    pub title: String,
    /// the post url
    pub url: PathBuf,
    /// post headers
    pub headers: PostHeaders,
    /// post html body
    pub content: String,
}

impl Post {
    pub fn new<P: AsRef<Path>>(root: P, path: P) -> Result<Post> {
        let root = root.as_ref();
        let path = path.as_ref();
        debug!("loading post: {}", path.display());

        let fp = root.join(&path);
        let mut fo = File::open(fp)?;
        let mut content = String::new();
        fo.read_to_string(&mut content)?;

        let v: Vec<&str> = content.splitn(2, "\n\n").collect();
        if v.len() != 2 {
            return Err(Error::PostOnlyOnePart(path.into()));
        }
        let head = v[0].trim();
        let body = v[1].trim();
        if head.is_empty() {
            return Err(Error::PostNoHead(path.into()));
        }
        if head.is_empty() {
            return Err(Error::PostNoBody(path.into()));
        }

        let title = path.file_stem()
                        .and_then(|x| x.to_str())
                        .expect(&format!("post filename format error: {}", path.display()));
        let url = Path::new("/").join(path).with_extension("html");
        let mut headers: PostHeaders = serde_yaml::from_str(head)?;
        if headers.description.is_empty() {
            let desc = body.split("\n\n").take(1).next().unwrap_or("")
                           .split_whitespace().take(100).collect::<Vec<_>>()
                           .join(" ");
            headers.description.push_str(&desc);
            if !headers.description.is_empty() {
                headers.description.push_str("...");
            }
        }
        let content = markdown_to_html(body);

        Ok(Post {
            root: root.to_owned(),
            path: path.to_owned(),
            title: title.to_owned(),
            url: url,
            headers: headers,
            content: content,
        })
    }

    /// the absolute path of blog post markdown file.
    pub fn src(&self) -> PathBuf {
        self.root.join(&self.path)
    }

    /// the absolute path of blog post html file.
    pub fn dest(&self) -> PathBuf {
        self.path.with_extension("html")
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// 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.

use decode::{Decode, Decoded};

use std::cmp::min;
use std::io;
use std::io::{Read, BufRead};
use std::slice::bytes;
use std::str;

pub struct Reader<R, D> {
    reader: R,
    decoder: D,
    state: BufState
}

#[derive(Copy, Eq, PartialEq)]
enum BufState {
    Empty,
    Decoded { pos: usize },
    InPlace { len: usize }
}

impl<R, D> Reader<R, D> where R: BufRead, D: Decode {
    pub fn new(reader: R, decoder: D) -> Reader<R, D> {
        Reader { reader: reader, decoder: decoder, state: BufState::Empty }
    }

    fn read_to_end_fast_with<F>(&mut self, mut process: F) -> io::Result<()>
        where F: FnMut(&str)
    {
        debug_assert!(self.state == BufState::Empty);

        // Fast-pace trough the output, no need to change states
        loop {
            let (in_consumed, amt_read) = {
                let read_buf = try!(self.reader.fill_buf());
                let decoded = try!(self.decoder.decode(read_buf));
                match decoded {
                    Decoded::Some(in_consumed, out) => {
                        process(out);
                        (in_consumed, out.len())
                    }
                    Decoded::InPlace(s) => {
                        debug_assert!(s.as_ptr() == read_buf.as_ptr(),
                            "decoder returned in-place data not at the start of the input buffer");
                        process(s);
                        let in_len = s.len();
                        (in_len, in_len)
                    }
                }
            };
            self.reader.consume(in_consumed);
            self.decoder.consume();
            if amt_read == 0 {
                break;
            }
        }
        Ok(())
    }
}

impl<R, D> Read for Reader<R, D> where R: BufRead, D: Decode {

    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let amt = {
            let decoded_buf = try!(self.fill_buf());
            let amt = min(buf.len(), decoded_buf.len());
            bytes::copy_memory(&mut buf[0 .. amt], &decoded_buf[0 .. amt]);
            amt
        };
        self.consume(amt);
        Ok(amt)
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
        // Deal with possible partially read input
        let read_len = {
            let read_buf = try!(self.fill_buf());
            buf.extend(read_buf.iter().cloned());
            read_buf.len()
        };
        self.consume(read_len);
        self.read_to_end_fast_with(|s| { buf.extend(s.bytes()) })
    }

    fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
        // The reader might have been partially read from. Deal with it.
        {
            let partial_input: &[u8] = match self.state {
                BufState::Empty => &[],
                BufState::Decoded { pos } => {
                    &self.decoder.output().as_bytes()[pos ..]
                }
                BufState::InPlace { len } => {
                    let read_buf = try!(self.reader.fill_buf());
                    &read_buf[0 .. len]
                }
            };
            match str::from_utf8(partial_input) {
                Ok(s) => {
                    buf.push_str(s);
                }
                Err(_) => {
                    return Err(io::Error::new(io::ErrorKind::InvalidInput,
                        "cannot read a complete UTF-8 string due to preceding reads",
                        None));
                }
            }
        }
        self.decoder.consume();
        self.state = BufState::Empty;
        self.read_to_end_fast_with(|s| { buf.push_str(s) })
    }
}

impl<R, D> BufRead for Reader<R, D> where R: BufRead, D: Decode {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        loop {
            match self.state {
                BufState::Empty => { }
                BufState::Decoded { pos } => {
                    let out = self.decoder.output();
                    return Ok(&out.as_bytes()[pos ..]);
                }
                BufState::InPlace { len } => {
                    // We had some validated UTF-8 in the input,
                    // and we should get the remaining part of it again
                    // from the buffered reader.
                    let buf = try!(self.reader.fill_buf());
                    return Ok(&buf[0 .. len]);
                }
            }
            let in_consumed = {
                let buf = try!(self.reader.fill_buf());
                let decoded = try!(self.decoder.decode(buf));
                match decoded {
                    Decoded::Some(in_consumed, _) => {
                        self.state = BufState::Decoded { pos: 0 };
                        in_consumed
                    }
                    Decoded::InPlace(s) => {
                        self.state = BufState::InPlace { len: s.len() };
                        0
                    }
                }
            };
            self.reader.consume(in_consumed);
        }
    }

    fn consume(&mut self, amt: usize) {
        match self.state {
            BufState::Empty => {
                debug_assert!(amt == 0,
                    "request to consume exceeds the output");
            }
            BufState::Decoded { pos } => {
                let new_pos = pos + amt;
                let buf_len = self.decoder.output().len();
                debug_assert!(new_pos <= buf_len,
                    "request to consume exceeds the output");
                if new_pos == buf_len {
                    self.decoder.consume();
                    self.state = BufState::Empty;
                } else {
                    self.state = BufState::Decoded { pos: new_pos };
                }
            }
            BufState::InPlace { len } => {
                debug_assert!(amt <= len,
                    "request to consume exceeds the output");
                self.reader.consume(amt);
                let new_len = len - amt;
                self.state =
                    if new_len == 0 {
                        BufState::Empty
                    } else {
                        BufState::InPlace { len: new_len }
                    };
            }
        }
    }
}
<commit_msg>One more debug assertion for Decoded::InPlace<commit_after>// Copyright 2015 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// 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.

use decode::{Decode, Decoded};

use std::cmp::min;
use std::io;
use std::io::{Read, BufRead};
use std::slice::bytes;
use std::str;

pub struct Reader<R, D> {
    reader: R,
    decoder: D,
    state: BufState
}

#[derive(Copy, Eq, PartialEq)]
enum BufState {
    Empty,
    Decoded { pos: usize },
    InPlace { len: usize }
}

impl<R, D> Reader<R, D> where R: BufRead, D: Decode {
    pub fn new(reader: R, decoder: D) -> Reader<R, D> {
        Reader { reader: reader, decoder: decoder, state: BufState::Empty }
    }

    fn read_to_end_fast_with<F>(&mut self, mut process: F) -> io::Result<()>
        where F: FnMut(&str)
    {
        debug_assert!(self.state == BufState::Empty);

        // Fast-pace trough the output, no need to change states
        loop {
            let (in_consumed, amt_read) = {
                let read_buf = try!(self.reader.fill_buf());
                let decoded = try!(self.decoder.decode(read_buf));
                match decoded {
                    Decoded::Some(in_consumed, out) => {
                        process(out);
                        (in_consumed, out.len())
                    }
                    Decoded::InPlace(s) => {
                        debug_assert!(s.as_ptr() == read_buf.as_ptr(),
                            "decoder returned in-place data not at the start of the input buffer");
                        process(s);
                        let in_len = s.len();
                        (in_len, in_len)
                    }
                }
            };
            self.reader.consume(in_consumed);
            self.decoder.consume();
            if amt_read == 0 {
                break;
            }
        }
        Ok(())
    }
}

impl<R, D> Read for Reader<R, D> where R: BufRead, D: Decode {

    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let amt = {
            let decoded_buf = try!(self.fill_buf());
            let amt = min(buf.len(), decoded_buf.len());
            bytes::copy_memory(&mut buf[0 .. amt], &decoded_buf[0 .. amt]);
            amt
        };
        self.consume(amt);
        Ok(amt)
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
        // Deal with possible partially read input
        let read_len = {
            let read_buf = try!(self.fill_buf());
            buf.extend(read_buf.iter().cloned());
            read_buf.len()
        };
        self.consume(read_len);
        self.read_to_end_fast_with(|s| { buf.extend(s.bytes()) })
    }

    fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
        // The reader might have been partially read from. Deal with it.
        {
            let partial_input: &[u8] = match self.state {
                BufState::Empty => &[],
                BufState::Decoded { pos } => {
                    &self.decoder.output().as_bytes()[pos ..]
                }
                BufState::InPlace { len } => {
                    let read_buf = try!(self.reader.fill_buf());
                    &read_buf[0 .. len]
                }
            };
            match str::from_utf8(partial_input) {
                Ok(s) => {
                    buf.push_str(s);
                }
                Err(_) => {
                    return Err(io::Error::new(io::ErrorKind::InvalidInput,
                        "cannot read a complete UTF-8 string due to preceding reads",
                        None));
                }
            }
        }
        self.decoder.consume();
        self.state = BufState::Empty;
        self.read_to_end_fast_with(|s| { buf.push_str(s) })
    }
}

impl<R, D> BufRead for Reader<R, D> where R: BufRead, D: Decode {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        loop {
            match self.state {
                BufState::Empty => { }
                BufState::Decoded { pos } => {
                    let out = self.decoder.output();
                    return Ok(&out.as_bytes()[pos ..]);
                }
                BufState::InPlace { len } => {
                    // We had some validated UTF-8 in the input,
                    // and we should get the remaining part of it again
                    // from the buffered reader.
                    let buf = try!(self.reader.fill_buf());
                    return Ok(&buf[0 .. len]);
                }
            }
            let in_consumed = {
                let read_buf = try!(self.reader.fill_buf());
                let decoded = try!(self.decoder.decode(read_buf));
                match decoded {
                    Decoded::Some(in_consumed, _) => {
                        self.state = BufState::Decoded { pos: 0 };
                        in_consumed
                    }
                    Decoded::InPlace(s) => {
                        debug_assert!(s.as_ptr() == read_buf.as_ptr(),
                            "decoder returned in-place data not at the start of the input buffer");
                        self.state = BufState::InPlace { len: s.len() };
                        0
                    }
                }
            };
            self.reader.consume(in_consumed);
        }
    }

    fn consume(&mut self, amt: usize) {
        match self.state {
            BufState::Empty => {
                debug_assert!(amt == 0,
                    "request to consume exceeds the output");
            }
            BufState::Decoded { pos } => {
                let new_pos = pos + amt;
                let buf_len = self.decoder.output().len();
                debug_assert!(new_pos <= buf_len,
                    "request to consume exceeds the output");
                if new_pos == buf_len {
                    self.decoder.consume();
                    self.state = BufState::Empty;
                } else {
                    self.state = BufState::Decoded { pos: new_pos };
                }
            }
            BufState::InPlace { len } => {
                debug_assert!(amt <= len,
                    "request to consume exceeds the output");
                self.reader.consume(amt);
                let new_len = len - amt;
                self.state =
                    if new_len == 0 {
                        BufState::Empty
                    } else {
                        BufState::InPlace { len: new_len }
                    };
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// 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.

use decode::{Decode, Decoded};

use std::cmp::min;
use std::io;
use std::io::{Read, BufRead};
use std::slice::bytes;
use std::str;

pub struct Reader<R, D> {
    reader: R,
    decoder: D,
    state: BufState
}

#[derive(Copy, Eq, PartialEq)]
enum BufState {
    Empty,
    Decoded { pos: usize },
    InPlace { len: usize }
}

impl<R, D> Reader<R, D> where R: BufRead, D: Decode {
    pub fn new(reader: R, decoder: D) -> Reader<R, D> {
        Reader { reader: reader, decoder: decoder, state: BufState::Empty }
    }

    fn read_to_end_fast_with<F>(&mut self, mut process: F) -> io::Result<()>
        where F: FnMut(&str)
    {
        debug_assert!(self.state == BufState::Empty);

        // Fast-pace trough the output, no need to change states
        loop {
            let (in_consumed, amt_read) = {
                let read_buf = try!(self.reader.fill_buf());
                let decoded = try!(self.decoder.decode(read_buf));
                match decoded {
                    Decoded::Some(in_consumed, out) => {
                        process(out);
                        (in_consumed, out.len())
                    }
                    Decoded::InPlace(s) => {
                        debug_assert!(s.as_ptr() == read_buf.as_ptr(),
                            "decoder returned in-place data not at the start of the input buffer");
                        process(s);
                        let in_len = s.len();
                        (in_len, in_len)
                    }
                }
            };
            self.reader.consume(in_consumed);
            self.decoder.consume();
            if amt_read == 0 {
                break;
            }
        }
        Ok(())
    }
}

impl<R, D> Read for Reader<R, D> where R: BufRead, D: Decode {

    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let amt = {
            let decoded_buf = try!(self.fill_buf());
            let amt = min(buf.len(), decoded_buf.len());
            bytes::copy_memory(&mut buf[0 .. amt], &decoded_buf[0 .. amt]);
            amt
        };
        self.consume(amt);
        Ok(amt)
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
        // Deal with possible partially read input
        let read_len = {
            let read_buf = try!(self.fill_buf());
            buf.extend(read_buf.iter().cloned());
            read_buf.len()
        };
        self.consume(read_len);
        self.read_to_end_fast_with(|s| { buf.extend(s.bytes()) })
    }

    fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
        // The reader might have been partially read from. Deal with it.
        {
            let partial_input: &[u8] = match self.state {
                BufState::Empty => &[],
                BufState::Decoded { pos } => {
                    &self.decoder.output().as_bytes()[pos ..]
                }
                BufState::InPlace { len } => {
                    let read_buf = try!(self.reader.fill_buf());
                    &read_buf[0 .. len]
                }
            };
            match str::from_utf8(partial_input) {
                Ok(s) => {
                    buf.push_str(s);
                }
                Err(_) => {
                    return Err(io::Error::new(io::ErrorKind::InvalidInput,
                        "cannot read a complete UTF-8 string due to preceding reads",
                        None));
                }
            }
        }
        self.decoder.consume();
        self.state = BufState::Empty;
        self.read_to_end_fast_with(|s| { buf.push_str(s) })
    }
}

impl<R, D> BufRead for Reader<R, D> where R: BufRead, D: Decode {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        loop {
            match self.state {
                BufState::Empty => { }
                BufState::Decoded { pos } => {
                    let out = self.decoder.output();
                    return Ok(&out.as_bytes()[pos ..]);
                }
                BufState::InPlace { len } => {
                    // We had some validated UTF-8 in the input,
                    // and we should get the remaining part of it again
                    // from the buffered reader.
                    let buf = try!(self.reader.fill_buf());
                    return Ok(&buf[0 .. len]);
                }
            }
            let in_consumed = {
                let read_buf = try!(self.reader.fill_buf());
                let decoded = try!(self.decoder.decode(read_buf));
                match decoded {
                    Decoded::Some(in_consumed, _) => {
                        self.state = BufState::Decoded { pos: 0 };
                        in_consumed
                    }
                    Decoded::InPlace(s) => {
                        debug_assert!(s.as_ptr() == read_buf.as_ptr(),
                            "decoder returned in-place data not at the start of the input buffer");
                        self.state = BufState::InPlace { len: s.len() };
                        0
                    }
                }
            };
            self.reader.consume(in_consumed);
        }
    }

    fn consume(&mut self, amt: usize) {
        match self.state {
            BufState::Empty => {
                debug_assert!(amt == 0,
                    "request to consume exceeds the output");
            }
            BufState::Decoded { pos } => {
                let new_pos = pos + amt;
                let buf_len = self.decoder.output().len();
                debug_assert!(new_pos <= buf_len,
                    "request to consume exceeds the output");
                if new_pos == buf_len {
                    self.decoder.consume();
                    self.state = BufState::Empty;
                } else {
                    self.state = BufState::Decoded { pos: new_pos };
                }
            }
            BufState::InPlace { len } => {
                debug_assert!(amt <= len,
                    "request to consume exceeds the output");
                self.reader.consume(amt);
                let new_len = len - amt;
                self.state =
                    if new_len == 0 {
                        BufState::Empty
                    } else {
                        BufState::InPlace { len: new_len }
                    };
            }
        }
    }
}
<commit_msg>Adapt to the changed return type of read_to_end and read_to_string<commit_after>// Copyright 2015 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// 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.

use decode::{Decode, Decoded};

use std::cmp::min;
use std::io;
use std::io::{Read, BufRead};
use std::slice::bytes;
use std::str;

pub struct Reader<R, D> {
    reader: R,
    decoder: D,
    state: BufState
}

#[derive(Copy, Eq, PartialEq)]
enum BufState {
    Empty,
    Decoded { pos: usize },
    InPlace { len: usize }
}

impl<R, D> Reader<R, D> where R: BufRead, D: Decode {
    pub fn new(reader: R, decoder: D) -> Reader<R, D> {
        Reader { reader: reader, decoder: decoder, state: BufState::Empty }
    }

    fn read_to_end_fast_with<F>(&mut self, mut process: F) -> io::Result<()>
        where F: FnMut(&str)
    {
        debug_assert!(self.state == BufState::Empty);

        // Fast-pace trough the output, no need to change states
        loop {
            let (in_consumed, amt_read) = {
                let read_buf = try!(self.reader.fill_buf());
                let decoded = try!(self.decoder.decode(read_buf));
                match decoded {
                    Decoded::Some(in_consumed, out) => {
                        process(out);
                        (in_consumed, out.len())
                    }
                    Decoded::InPlace(s) => {
                        debug_assert!(s.as_ptr() == read_buf.as_ptr(),
                            "decoder returned in-place data not at the start of the input buffer");
                        process(s);
                        let in_len = s.len();
                        (in_len, in_len)
                    }
                }
            };
            self.reader.consume(in_consumed);
            self.decoder.consume();
            if amt_read == 0 {
                break;
            }
        }
        Ok(())
    }
}

impl<R, D> Read for Reader<R, D> where R: BufRead, D: Decode {

    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let amt = {
            let decoded_buf = try!(self.fill_buf());
            let amt = min(buf.len(), decoded_buf.len());
            bytes::copy_memory(&mut buf[0 .. amt], &decoded_buf[0 .. amt]);
            amt
        };
        self.consume(amt);
        Ok(amt)
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        let pre_len = buf.len();
        // Deal with possible partially read input
        let read_len = {
            let read_buf = try!(self.fill_buf());
            buf.extend(read_buf.iter().cloned());
            read_buf.len()
        };
        self.consume(read_len);
        try!(self.read_to_end_fast_with(|s| { buf.extend(s.bytes()) }));
        Ok(buf.len() - pre_len)
    }

    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
        let pre_len = buf.len();
        // The reader might have been partially read from. Deal with it.
        {
            let partial_input: &[u8] = match self.state {
                BufState::Empty => &[],
                BufState::Decoded { pos } => {
                    &self.decoder.output().as_bytes()[pos ..]
                }
                BufState::InPlace { len } => {
                    let read_buf = try!(self.reader.fill_buf());
                    &read_buf[0 .. len]
                }
            };
            match str::from_utf8(partial_input) {
                Ok(s) => {
                    buf.push_str(s);
                }
                Err(_) => {
                    return Err(io::Error::new(io::ErrorKind::InvalidInput,
                        "cannot read a complete UTF-8 string due to preceding reads",
                        None));
                }
            }
        }
        self.decoder.consume();
        self.state = BufState::Empty;
        try!(self.read_to_end_fast_with(|s| { buf.push_str(s) }));
        Ok(buf.len() - pre_len)
    }
}

impl<R, D> BufRead for Reader<R, D> where R: BufRead, D: Decode {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        loop {
            match self.state {
                BufState::Empty => { }
                BufState::Decoded { pos } => {
                    let out = self.decoder.output();
                    return Ok(&out.as_bytes()[pos ..]);
                }
                BufState::InPlace { len } => {
                    // We had some validated UTF-8 in the input,
                    // and we should get the remaining part of it again
                    // from the buffered reader.
                    let buf = try!(self.reader.fill_buf());
                    return Ok(&buf[0 .. len]);
                }
            }
            let in_consumed = {
                let read_buf = try!(self.reader.fill_buf());
                let decoded = try!(self.decoder.decode(read_buf));
                match decoded {
                    Decoded::Some(in_consumed, _) => {
                        self.state = BufState::Decoded { pos: 0 };
                        in_consumed
                    }
                    Decoded::InPlace(s) => {
                        debug_assert!(s.as_ptr() == read_buf.as_ptr(),
                            "decoder returned in-place data not at the start of the input buffer");
                        self.state = BufState::InPlace { len: s.len() };
                        0
                    }
                }
            };
            self.reader.consume(in_consumed);
        }
    }

    fn consume(&mut self, amt: usize) {
        match self.state {
            BufState::Empty => {
                debug_assert!(amt == 0,
                    "request to consume exceeds the output");
            }
            BufState::Decoded { pos } => {
                let new_pos = pos + amt;
                let buf_len = self.decoder.output().len();
                debug_assert!(new_pos <= buf_len,
                    "request to consume exceeds the output");
                if new_pos == buf_len {
                    self.decoder.consume();
                    self.state = BufState::Empty;
                } else {
                    self.state = BufState::Decoded { pos: new_pos };
                }
            }
            BufState::InPlace { len } => {
                debug_assert!(amt <= len,
                    "request to consume exceeds the output");
                self.reader.consume(amt);
                let new_len = len - amt;
                self.state =
                    if new_len == 0 {
                        BufState::Empty
                    } else {
                        BufState::InPlace { len: new_len }
                    };
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Types for rectangles.

#[allow(clippy::module_inception)]
mod rect {
    use crate::float_eq_cairo::ApproxEqCairo;
    use core::ops::{Add, Range, Sub};
    use num_traits::Zero;

    // Use our own min() and max() that are acceptable for floating point

    fn min<T: PartialOrd>(x: T, y: T) -> T {
        if x <= y {
            x
        } else {
            y
        }
    }

    fn max<T: PartialOrd>(x: T, y: T) -> T {
        if x >= y {
            x
        } else {
            y
        }
    }

    #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
    pub struct Rect<T> {
        pub x0: T,
        pub y0: T,
        pub x1: T,
        pub y1: T,
    }

    impl<T> Rect<T> {
        #[inline]
        pub fn new(x0: T, y0: T, x1: T, y1: T) -> Self {
            Self { x0, y0, x1, y1 }
        }
    }

    impl<T> Rect<T>
    where
        T: Copy + PartialOrd + PartialEq + Add<T, Output = T> + Sub<T, Output = T> + Zero,
    {
        #[inline]
        pub fn from_size(w: T, h: T) -> Self {
            Self {
                x0: Zero::zero(),
                y0: Zero::zero(),
                x1: w,
                y1: h,
            }
        }

        #[inline]
        pub fn width(&self) -> T {
            self.x1 - self.x0
        }

        #[inline]
        pub fn height(&self) -> T {
            self.y1 - self.y0
        }

        #[inline]
        pub fn size(&self) -> (T, T) {
            (self.width(), self.height())
        }

        #[inline]
        pub fn x_range(&self) -> Range<T> {
            self.x0..self.x1
        }

        #[inline]
        pub fn y_range(&self) -> Range<T> {
            self.y0..self.y1
        }

        #[inline]
        pub fn contains(self, x: T, y: T) -> bool {
            x >= self.x0 && x < self.x1 && y >= self.y0 && y < self.y1
        }

        #[inline]
        pub fn translate(&self, by: (T, T)) -> Self {
            Self {
                x0: self.x0 + by.0,
                y0: self.y0 + by.1,
                x1: self.x1 + by.0,
                y1: self.y1 + by.1,
            }
        }

        #[inline]
        pub fn intersection(&self, rect: &Self) -> Option<Self> {
            let (x0, y0, x1, y1) = (
                max(self.x0, rect.x0),
                max(self.y0, rect.y0),
                min(self.x1, rect.x1),
                min(self.y1, rect.y1),
            );

            if x1 > x0 && y1 > y0 {
                Some(Self { x0, y0, x1, y1 })
            } else {
                None
            }
        }

        #[inline]
        pub fn union(&self, rect: &Self) -> Self {
            Self {
                x0: min(self.x0, rect.x0),
                y0: min(self.y0, rect.y0),
                x1: max(self.x1, rect.x1),
                y1: max(self.y1, rect.y1),
            }
        }
    }

    impl Rect<i32> {
        #[inline]
        pub fn is_empty(&self) -> bool {
            self.width() == Zero::zero() || self.height() == Zero::zero()
        }

        #[inline]
        pub fn scale(self, x: f64, y: f64) -> Self {
            Self {
                x0: (f64::from(self.x0) * x).floor() as i32,
                y0: (f64::from(self.y0) * y).floor() as i32,
                x1: (f64::from(self.x1) * x).ceil() as i32,
                y1: (f64::from(self.y1) * y).ceil() as i32,
            }
        }
    }

    impl Rect<f64> {
        #[inline]
        pub fn is_empty(&self) -> bool {
            self.width().approx_eq_cairo(0.0) || self.height().approx_eq_cairo(0.0)
        }

        #[inline]
        pub fn scale(self, x: f64, y: f64) -> Self {
            Self {
                x0: self.x0 * x,
                y0: self.y0 * y,
                x1: self.x1 * x,
                y1: self.y1 * y,
            }
        }
    }
}

pub type Rect = rect::Rect<f64>;

impl From<Rect> for IRect {
    #[inline]
    fn from(r: Rect) -> Self {
        Self {
            x0: r.x0.floor() as i32,
            y0: r.y0.floor() as i32,
            x1: r.x1.ceil() as i32,
            y1: r.y1.ceil() as i32,
        }
    }
}

impl From<cairo::Rectangle> for Rect {
    #[inline]
    fn from(r: cairo::Rectangle) -> Self {
        Self {
            x0: r.x,
            y0: r.y,
            x1: r.x + r.width,
            y1: r.y + r.height,
        }
    }
}

impl From<Rect> for cairo::Rectangle {
    #[inline]
    fn from(r: Rect) -> Self {
        Self {
            x: r.x0,
            y: r.y0,
            width: r.x1 - r.x0,
            height: r.y1 - r.y0,
        }
    }
}

pub type IRect = rect::Rect<i32>;

impl From<IRect> for Rect {
    #[inline]
    fn from(r: IRect) -> Self {
        Self {
            x0: f64::from(r.x0),
            y0: f64::from(r.y0),
            x1: f64::from(r.x1),
            y1: f64::from(r.y1),
        }
    }
}

impl From<cairo::Rectangle> for IRect {
    #[inline]
    fn from(r: cairo::Rectangle) -> Self {
        Self {
            x0: r.x.floor() as i32,
            y0: r.y.floor() as i32,
            x1: (r.x + r.width).ceil() as i32,
            y1: (r.y + r.height).ceil() as i32,
        }
    }
}

impl From<IRect> for cairo::Rectangle {
    #[inline]
    fn from(r: IRect) -> Self {
        Self {
            x: f64::from(r.x0),
            y: f64::from(r.y0),
            width: f64::from(r.x1 - r.x0),
            height: f64::from(r.y1 - r.y0),
        }
    }
}
<commit_msg>(#757): Hack (?) to fix type inference on 32-bit builds<commit_after>//! Types for rectangles.

#[allow(clippy::module_inception)]
mod rect {
    use crate::float_eq_cairo::ApproxEqCairo;
    use core::ops::{Add, Range, Sub};
    use num_traits::Zero;

    // Use our own min() and max() that are acceptable for floating point

    fn min<T: PartialOrd>(x: T, y: T) -> T {
        if x <= y {
            x
        } else {
            y
        }
    }

    fn max<T: PartialOrd>(x: T, y: T) -> T {
        if x >= y {
            x
        } else {
            y
        }
    }

    #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
    pub struct Rect<T> {
        pub x0: T,
        pub y0: T,
        pub x1: T,
        pub y1: T,
    }

    impl<T> Rect<T> {
        #[inline]
        pub fn new(x0: T, y0: T, x1: T, y1: T) -> Self {
            Self { x0, y0, x1, y1 }
        }
    }

    impl<T> Rect<T>
    where
        T: Copy + PartialOrd + PartialEq + Add<T, Output = T> + Sub<T, Output = T> + Zero,
    {
        #[inline]
        pub fn from_size(w: T, h: T) -> Self {
            Self {
                x0: Zero::zero(),
                y0: Zero::zero(),
                x1: w,
                y1: h,
            }
        }

        #[inline]
        pub fn width(&self) -> T {
            self.x1 - self.x0
        }

        #[inline]
        pub fn height(&self) -> T {
            self.y1 - self.y0
        }

        #[inline]
        pub fn size(&self) -> (T, T) {
            (self.width(), self.height())
        }

        #[inline]
        pub fn x_range(&self) -> Range<T> {
            self.x0..self.x1
        }

        #[inline]
        pub fn y_range(&self) -> Range<T> {
            self.y0..self.y1
        }

        #[inline]
        pub fn contains(self, x: T, y: T) -> bool {
            x >= self.x0 && x < self.x1 && y >= self.y0 && y < self.y1
        }

        #[inline]
        pub fn translate(&self, by: (T, T)) -> Self {
            Self {
                x0: self.x0 + by.0,
                y0: self.y0 + by.1,
                x1: self.x1 + by.0,
                y1: self.y1 + by.1,
            }
        }

        #[inline]
        pub fn intersection(&self, rect: &Self) -> Option<Self> {
            let (x0, y0, x1, y1) = (
                max(self.x0, rect.x0),
                max(self.y0, rect.y0),
                min(self.x1, rect.x1),
                min(self.y1, rect.y1),
            );

            if x1 > x0 && y1 > y0 {
                Some(Self { x0, y0, x1, y1 })
            } else {
                None
            }
        }

        #[inline]
        pub fn union(&self, rect: &Self) -> Self {
            Self {
                x0: min(self.x0, rect.x0),
                y0: min(self.y0, rect.y0),
                x1: max(self.x1, rect.x1),
                y1: max(self.y1, rect.y1),
            }
        }
    }

    impl Rect<i32> {
        #[inline]
        pub fn is_empty(&self) -> bool {
            // Give an explicit type to the right hand side of the ==, since sometimes
            // type inference fails to figure it out.  I have no idea why.
            self.width() == <i32 as Zero>::zero() || self.height() == <i32 as Zero>::zero()
        }

        #[inline]
        pub fn scale(self, x: f64, y: f64) -> Self {
            Self {
                x0: (f64::from(self.x0) * x).floor() as i32,
                y0: (f64::from(self.y0) * y).floor() as i32,
                x1: (f64::from(self.x1) * x).ceil() as i32,
                y1: (f64::from(self.y1) * y).ceil() as i32,
            }
        }
    }

    impl Rect<f64> {
        #[inline]
        pub fn is_empty(&self) -> bool {
            self.width().approx_eq_cairo(0.0) || self.height().approx_eq_cairo(0.0)
        }

        #[inline]
        pub fn scale(self, x: f64, y: f64) -> Self {
            Self {
                x0: self.x0 * x,
                y0: self.y0 * y,
                x1: self.x1 * x,
                y1: self.y1 * y,
            }
        }
    }
}

pub type Rect = rect::Rect<f64>;

impl From<Rect> for IRect {
    #[inline]
    fn from(r: Rect) -> Self {
        Self {
            x0: r.x0.floor() as i32,
            y0: r.y0.floor() as i32,
            x1: r.x1.ceil() as i32,
            y1: r.y1.ceil() as i32,
        }
    }
}

impl From<cairo::Rectangle> for Rect {
    #[inline]
    fn from(r: cairo::Rectangle) -> Self {
        Self {
            x0: r.x,
            y0: r.y,
            x1: r.x + r.width,
            y1: r.y + r.height,
        }
    }
}

impl From<Rect> for cairo::Rectangle {
    #[inline]
    fn from(r: Rect) -> Self {
        Self {
            x: r.x0,
            y: r.y0,
            width: r.x1 - r.x0,
            height: r.y1 - r.y0,
        }
    }
}

pub type IRect = rect::Rect<i32>;

impl From<IRect> for Rect {
    #[inline]
    fn from(r: IRect) -> Self {
        Self {
            x0: f64::from(r.x0),
            y0: f64::from(r.y0),
            x1: f64::from(r.x1),
            y1: f64::from(r.y1),
        }
    }
}

impl From<cairo::Rectangle> for IRect {
    #[inline]
    fn from(r: cairo::Rectangle) -> Self {
        Self {
            x0: r.x.floor() as i32,
            y0: r.y.floor() as i32,
            x1: (r.x + r.width).ceil() as i32,
            y1: (r.y + r.height).ceil() as i32,
        }
    }
}

impl From<IRect> for cairo::Rectangle {
    #[inline]
    fn from(r: IRect) -> Self {
        Self {
            x: f64::from(r.x0),
            y: f64::from(r.y0),
            width: f64::from(r.x1 - r.x0),
            height: f64::from(r.y1 - r.y0),
        }
    }
}
<|endoftext|>


<commit_before>use crate::utils;

use clap::{App, Arg, Error, ErrorKind};

fn compare_error(
    err: Error,
    expected_kind: ErrorKind,
    expected_output: &str,
    stderr: bool,
) -> bool {
    let actual_output = err.to_string();
    assert_eq!(
        stderr,
        err.use_stderr(),
        "Should Use STDERR failed. Should be {} but is {}",
        stderr,
        err.use_stderr()
    );
    assert_eq!(expected_kind, err.kind);
    utils::compare(expected_output, actual_output)
}

#[test]
fn app_error() {
    static MESSAGE: &str = "error: Failed for mysterious reasons

USAGE:
    test [OPTIONS] --all

For more information try --help
";
    let app = App::new("test")
        .arg(
            Arg::new("all")
                .short('a')
                .long("all")
                .required(true)
                .help("Also do versioning for private crates (will not be published)"),
        )
        .arg(
            Arg::new("exact")
                .long("exact")
                .help("Specify inter dependency version numbers exactly with `=`"),
        )
        .arg(
            Arg::new("no_git_commit")
                .long("no-git-commit")
                .help("Do not commit version changes"),
        )
        .arg(
            Arg::new("no_git_push")
                .long("no-git-push")
                .help("Do not push generated commit and tags to git remote"),
        );
    let mut app = app;
    let expected_kind = ErrorKind::InvalidValue;
    let err = app.error(expected_kind, "Failed for mysterious reasons");
    assert!(compare_error(err, expected_kind, MESSAGE, true));
}
<commit_msg>test(error): Add explicit value_of_t test case<commit_after>use crate::utils;

use clap::{arg, App, Arg, Error, ErrorKind};

fn compare_error(
    err: Error,
    expected_kind: ErrorKind,
    expected_output: &str,
    stderr: bool,
) -> bool {
    let actual_output = err.to_string();
    assert_eq!(
        stderr,
        err.use_stderr(),
        "Should Use STDERR failed. Should be {} but is {}",
        stderr,
        err.use_stderr()
    );
    assert_eq!(expected_kind, err.kind);
    utils::compare(expected_output, actual_output)
}

#[test]
fn app_error() {
    static MESSAGE: &str = "error: Failed for mysterious reasons

USAGE:
    test [OPTIONS] --all

For more information try --help
";
    let app = App::new("test")
        .arg(
            Arg::new("all")
                .short('a')
                .long("all")
                .required(true)
                .help("Also do versioning for private crates (will not be published)"),
        )
        .arg(
            Arg::new("exact")
                .long("exact")
                .help("Specify inter dependency version numbers exactly with `=`"),
        )
        .arg(
            Arg::new("no_git_commit")
                .long("no-git-commit")
                .help("Do not commit version changes"),
        )
        .arg(
            Arg::new("no_git_push")
                .long("no-git-push")
                .help("Do not push generated commit and tags to git remote"),
        );
    let mut app = app;
    let expected_kind = ErrorKind::InvalidValue;
    let err = app.error(expected_kind, "Failed for mysterious reasons");
    assert!(compare_error(err, expected_kind, MESSAGE, true));
}

#[test]
fn value_validation_has_newline() {
    let m = App::new("test")
        .arg(arg!(<PORT>).help("Network port to use"))
        .try_get_matches_from(["test", "foo"])
        .unwrap();

    let res = m.value_of_t::<usize>("PORT");

    assert!(res.is_err());
    let err = res.unwrap_err();
    assert!(
        err.to_string().ends_with('\n'),
        "Errors should have a trailing newline, got {:?}",
        err.to_string()
    );
}
<|endoftext|>


<commit_before>#![deny(warnings)]

extern crate cargo;
extern crate filetime;
extern crate flate2;
extern crate git2;
extern crate hamcrest;
extern crate hex;
#[macro_use]
extern crate serde_json;
extern crate tar;
extern crate url;

use std::ffi::OsStr;
use std::time::Duration;

use cargo::util::Rustc;
use std::path::PathBuf;

pub mod support;
pub mod install;

thread_local!(pub static RUSTC: Rustc = Rustc::new(PathBuf::from("rustc"), None).unwrap());

pub fn rustc_host() -> String {
    RUSTC.with(|r| r.host.clone())
}

pub fn is_nightly() -> bool {
    RUSTC.with(|r| {
        r.verbose_version.contains("-nightly") ||
            r.verbose_version.contains("-dev")
    })
}

pub fn process<T: AsRef<OsStr>>(t: T) -> cargo::util::ProcessBuilder {
    _process(t.as_ref())
}

fn _process(t: &OsStr) -> cargo::util::ProcessBuilder {
    let mut p = cargo::util::process(t);
    p.cwd(&support::paths::root())
     .env_remove("CARGO_HOME")
     .env("HOME", support::paths::home())
     .env("CARGO_HOME", support::paths::home().join(".cargo"))
     .env("__CARGO_TEST_ROOT", support::paths::root())

     // Force cargo to think it's on the stable channel for all tests, this
     // should hopefully not suprise us as we add cargo features over time and
     // cargo rides the trains
     .env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "stable")

     // For now disable incremental by default as support hasn't ridden to the
     // stable channel yet. Once incremental support hits the stable compiler we
     // can switch this to one and then fix the tests.
     .env("CARGO_INCREMENTAL", "0")

     .env_remove("__CARGO_DEFAULT_LIB_METADATA")
     .env_remove("RUSTC")
     .env_remove("RUSTDOC")
     .env_remove("RUSTC_WRAPPER")
     .env_remove("RUSTFLAGS")
     .env_remove("XDG_CONFIG_HOME")      // see #2345
     .env("GIT_CONFIG_NOSYSTEM", "1")    // keep trying to sandbox ourselves
     .env_remove("EMAIL")
     .env_remove("MFLAGS")
     .env_remove("MAKEFLAGS")
     .env_remove("CARGO_MAKEFLAGS")
     .env_remove("GIT_AUTHOR_NAME")
     .env_remove("GIT_AUTHOR_EMAIL")
     .env_remove("GIT_COMMITTER_NAME")
     .env_remove("GIT_COMMITTER_EMAIL")
     .env_remove("CARGO_TARGET_DIR")     // we assume 'target'
     .env_remove("MSYSTEM");             // assume cmd.exe everywhere on windows
    return p
}

pub trait ChannelChanger: Sized {
    fn masquerade_as_nightly_cargo(&mut self) -> &mut Self;
}

impl ChannelChanger for cargo::util::ProcessBuilder {
    fn masquerade_as_nightly_cargo(&mut self) -> &mut Self {
        self.env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "nightly")
    }
}

pub fn cargo_process() -> cargo::util::ProcessBuilder {
    process(&support::cargo_exe())
}

pub fn sleep_ms(ms: u64) {
    std::thread::sleep(Duration::from_millis(ms));
}
<commit_msg>Forcibly remove CARGO_HTTP_CHECK_REVOKE when testing<commit_after>#![deny(warnings)]

extern crate cargo;
extern crate filetime;
extern crate flate2;
extern crate git2;
extern crate hamcrest;
extern crate hex;
#[macro_use]
extern crate serde_json;
extern crate tar;
extern crate url;

use std::ffi::OsStr;
use std::time::Duration;

use cargo::util::Rustc;
use std::path::PathBuf;

pub mod support;
pub mod install;

thread_local!(pub static RUSTC: Rustc = Rustc::new(PathBuf::from("rustc"), None).unwrap());

pub fn rustc_host() -> String {
    RUSTC.with(|r| r.host.clone())
}

pub fn is_nightly() -> bool {
    RUSTC.with(|r| {
        r.verbose_version.contains("-nightly") ||
            r.verbose_version.contains("-dev")
    })
}

pub fn process<T: AsRef<OsStr>>(t: T) -> cargo::util::ProcessBuilder {
    _process(t.as_ref())
}

fn _process(t: &OsStr) -> cargo::util::ProcessBuilder {
    let mut p = cargo::util::process(t);
    p.cwd(&support::paths::root())
     .env_remove("CARGO_HOME")
     .env("HOME", support::paths::home())
     .env("CARGO_HOME", support::paths::home().join(".cargo"))
     .env("__CARGO_TEST_ROOT", support::paths::root())

     // Force cargo to think it's on the stable channel for all tests, this
     // should hopefully not suprise us as we add cargo features over time and
     // cargo rides the trains
     .env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "stable")

     // For now disable incremental by default as support hasn't ridden to the
     // stable channel yet. Once incremental support hits the stable compiler we
     // can switch this to one and then fix the tests.
     .env("CARGO_INCREMENTAL", "0")

     // This env var can switch the git backend from libgit2 to git2-curl, which
     // can tweak error messages and cause some tests to fail, so let's forcibly
     // remove it.
     .env_remove("CARGO_HTTP_CHECK_REVOKE")

     .env_remove("__CARGO_DEFAULT_LIB_METADATA")
     .env_remove("RUSTC")
     .env_remove("RUSTDOC")
     .env_remove("RUSTC_WRAPPER")
     .env_remove("RUSTFLAGS")
     .env_remove("XDG_CONFIG_HOME")      // see #2345
     .env("GIT_CONFIG_NOSYSTEM", "1")    // keep trying to sandbox ourselves
     .env_remove("EMAIL")
     .env_remove("MFLAGS")
     .env_remove("MAKEFLAGS")
     .env_remove("CARGO_MAKEFLAGS")
     .env_remove("GIT_AUTHOR_NAME")
     .env_remove("GIT_AUTHOR_EMAIL")
     .env_remove("GIT_COMMITTER_NAME")
     .env_remove("GIT_COMMITTER_EMAIL")
     .env_remove("CARGO_TARGET_DIR")     // we assume 'target'
     .env_remove("MSYSTEM");             // assume cmd.exe everywhere on windows
    return p
}

pub trait ChannelChanger: Sized {
    fn masquerade_as_nightly_cargo(&mut self) -> &mut Self;
}

impl ChannelChanger for cargo::util::ProcessBuilder {
    fn masquerade_as_nightly_cargo(&mut self) -> &mut Self {
        self.env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "nightly")
    }
}

pub fn cargo_process() -> cargo::util::ProcessBuilder {
    process(&support::cargo_exe())
}

pub fn sleep_ms(ms: u64) {
    std::thread::sleep(Duration::from_millis(ms));
}
<|endoftext|>


<commit_before>//! Contains the `Snes` struct, which wields the combined power of this project.

use apu::Apu;
use cpu::Cpu;
use dma::{do_dma, DmaChannel};
use frontend::Renderer;
use input::Input;
use log_util::LogOnPanic;
use ppu::Ppu;
use rom::Rom;

const WRAM_SIZE: usize = 128 * 1024;
byte_array!(Wram[WRAM_SIZE]);

/// Contains everything connected to the CPU via one of the two address buses. All memory accesses
/// will be directed through this (the CPU already takes access time into account).
pub struct Peripherals {
    apu: Apu,
    ppu: Ppu,
    rom: Rom,
    /// The 128 KB of working RAM of the SNES (separate from cartridge RAM)
    wram: Wram,
    input: Input,

    pub dma: [DmaChannel; 8],
    /// `$420c` - HDMAEN: HDMA enable flags
    /// (Note that general DMA doesn't have a register here, since all transactions are started
    /// immediately and the register can't be read)
    hdmaen: u8,
    /// `$4200` - NMITIMEN: Interrupt enable flags
    /// `n-xy---a`
    /// * `n`: Enable NMI on V-Blank
    /// * `x`: Enable IRQ on H-Counter match
    /// * `y`: Enable IRQ on V-Counter match
    /// * `a`: Enable auto-joypad read
    nmien: u8,
    /// `$4207`/`$4208` - HTIMEL/HTIMEH: H Timer (9-bit value)
    htime: u16,
    /// `$4209`/`$420a` - VTIMEL/VTIMEH: V Timer (9-bit value)
    vtime: u16,
    /// `$4210` NMI flag and 5A22 Version
    /// `n---vvvv`
    /// * `n`: `self.nmi`
    /// * `v`: Version
    nmi: bool,
    /// `$4211` TIMEUP - IRQ flag
    /// `i-------`
    /// * `i`: IRQ flag (cleared on read)
    irq: bool,

    /// Additional cycles spent doing IO (in master clock cycles). This is reset before each CPU
    /// instruction and added to the cycle count returned by the CPU.
    cy: u32,
}

impl Peripherals {
    pub fn new(rom: Rom) -> Peripherals {
        Peripherals {
            rom: rom,
            apu: Apu::new(),
            ppu: Ppu::new(),
            wram: Wram::default(),
            input: Input::default(),
            dma: [DmaChannel::new(); 8],
            hdmaen: 0x00,
            nmien: 0x00,
            htime: 0x1ff,
            vtime: 0x1ff,
            nmi: false,
            irq: false,
            cy: 0,
        }
    }

    pub fn load(&mut self, bank: u8, addr: u16) -> u8 {
        match bank {
            0x00 ... 0x3f | 0x80 ... 0xbf => match addr {
                // Mirror of first 8k of WRAM
                0x0000 ... 0x1fff => self.wram[addr as usize],
                // PPU
                0x2100 ... 0x2133 => panic!("read from write-only PPU register ${:04X}", addr),
                0x2138 ... 0x213f => self.ppu.load(addr),
                // APU IO registers
                0x2140 ... 0x217f => self.apu.read_port((addr & 0b11) as u8),
                0x4016 | 0x4017 => self.input.load(addr),
                0x4210 => {
                    const CPU_VERSION: u8 = 2;  // FIXME Is 2 okay in all cases? Does anyone care?
                    let nmi = if self.nmi { 0x80 } else { 0 };
                    self.nmi = false;   // Cleared on read
                    nmi | CPU_VERSION
                }
                0x4211 => {
                    let val = if self.irq { 0x80 } else { 0 };
                    self.irq = false;
                    val
                }
                0x4218 ... 0x421f => self.input.load(addr),
                // DMA channels (0x43xr, where x is the channel and r is the channel register)
                0x4300 ... 0x43ff => self.dma[(addr as usize & 0x00f0) >> 4].load(addr as u8 & 0xf),
                0x8000 ... 0xffff => self.rom.loadb(bank, addr),
                _ => panic!("invalid/unimplemented load from ${:02X}:{:04X}", bank, addr)
            },
            // WRAM banks. The first 8k are mapped into the start of all banks.
            0x7e | 0x7f => self.wram[(bank as usize - 0x7e) * 65536 + addr as usize],
            0x40 ... 0x7d | 0xc0 ... 0xff => self.rom.loadb(bank, addr),
            _ => unreachable!(),    // Rust should know this!
        }
    }

    pub fn store(&mut self, bank: u8, addr: u16, value: u8) {
        match bank {
            0x00 ... 0x3f | 0x80 ... 0xbf => match addr {
                0x0000 ... 0x1fff => self.wram[addr as usize] = value,
                // PPU registers. Let it deal with the access.
                0x2100 ... 0x2133 => self.ppu.store(addr, value),
                0x2138 ... 0x213f => panic!("store to read-only PPU register ${:04X}", addr),
                // APU IO registers.
                0x2140 ... 0x217f => self.apu.store_port((addr & 0b11) as u8, value),
                0x2180 ... 0x2183 => panic!("NYI: WRAM registers"),
                0x4016 => self.input.store(addr, value),
                0x4200 => {
                    // NMITIMEN - NMI/IRQ enable
                    // E-HV---J
                    // E: Enable NMI
                    // H: Enable IRQ on H-Counter
                    // V: Enable IRQ on V-Counter
                    // J: Enable Auto-Joypad-Read

                    // Check useless bits
                    if value & 0x4e != 0 { panic!("Invalid value for NMIEN: ${:02X}", value) }
                    self.nmien = value;
                }
                0x4207 => self.htime = (self.htime & 0xff00) | value as u16,
                0x4208 => {
                    assert!(value & 0x01 == value, "invalid value for $4207: ${:02X}", value);
                    self.htime = ((value as u16) << 8) | (self.htime & 0xff);
                }
                0x4209 => self.vtime = (self.vtime & 0xff00) | value as u16,
                0x420a => {
                    assert!(value & 0x01 == value, "invalid value for $4209: ${:02X}", value);
                    self.vtime = ((value as u16) << 8) | (self.vtime & 0xff);
                }
                // MDMAEN - Party enable
                0x420b => self.cy += do_dma(self, value),
                // HDMAEN - HDMA enable
                0x420c => self.hdmaen = value,
                // DMA channels (0x43xr, where x is the channel and r is the channel register)
                0x4300 ... 0x43ff => {
                    self.dma[(addr as usize & 0x00f0) >> 4].store(addr as u8 & 0xf, value);
                }
                0x8000 ... 0xffff => self.rom.storeb(bank, addr, value),
                _ => panic!("invalid store: ${:02X} to ${:02X}:{:04X}", value, bank, addr)
            },
            // WRAM main banks
            0x7e | 0x7f => self.wram[(bank as usize - 0x7e) * 65536 + addr as usize] = value,
            0x40 ... 0x7d | 0xc0 ... 0xff => self.rom.storeb(bank, addr, value),
            _ => unreachable!(),    // Rust should know this!
        }
    }

    fn nmi_enabled(&self) -> bool { self.nmien & 0x80 != 0 }
    fn v_irq_enabled(&self) -> bool { self.nmien & 0x10 != 0 }
    fn h_irq_enabled(&self) -> bool { self.nmien & 0x20 != 0 }
}

pub struct Snes {
    cpu: Cpu,
    renderer: Box<Renderer>,
}

impl Snes {
    pub fn new(rom: Rom, renderer: Box<Renderer>) -> Snes {
        Snes {
            cpu: Cpu::new(Peripherals::new(rom)),
            renderer: renderer,
        }
    }

    pub fn run(&mut self) {
        /// Exit after this number of master clock cycles
        const CY_LIMIT: u64 = 150_000_000;
        /// Start tracing at this master cycle (0 to trace everything)
        const TRACE_START: u64 = CY_LIMIT - 10_000;

        const MASTER_CLOCK_FREQ: i32 = 21_477_000;
        /// APU clock speed. On real hardware, this can vary quite a bit (I think it uses a ceramic
        /// resonator instead of a quartz).
        const APU_CLOCK_FREQ: i32 = 1_024_000;
        /// Approximated APU clock divider. It's actually somewhere around 20.9..., which is why we
        /// can't directly use `MASTER_CLOCK_FREQ / APU_CLOCK_FREQ` (it would round down, which
        /// might not be critical, but better safe than sorry).
        const APU_DIVIDER: i32 = 21;

        // Master cycle counter, used only for debugging atm
        let mut master_cy: u64 = 0;
        let mut total_apu_cy: u64 = 0;
        let mut total_ppu_cy: u64 = 0;
        // Master clock cycles for the APU not yet accounted for (can be negative)
        let mut apu_master_cy_debt = 0;
        let mut ppu_master_cy_debt = 0;
        let working_cy = LogOnPanic::new(0);

        while master_cy < CY_LIMIT {
            if master_cy >= TRACE_START {
                self.cpu.trace = true;
                self.cpu.mem.apu.trace = true;
            }

            // Run a CPU instruction and calculate the master cycles elapsed
            self.cpu.mem.cy = 0;
            let cpu_master_cy = self.cpu.dispatch() as i32 + self.cpu.mem.cy as i32;
            master_cy += cpu_master_cy as u64;

            // Now we "owe" the other components a few cycles:
            apu_master_cy_debt += cpu_master_cy;
            ppu_master_cy_debt += cpu_master_cy;

            // Run all components until we no longer owe them:
            while apu_master_cy_debt > APU_DIVIDER {
                // (Since the APU uses lots of cycles to do stuff - lower clock rate and such - we
                // only run it if we owe it `APU_DIVIDER` master cycles - or one SPC700 cycle)
                let apu_master_cy = self.cpu.mem.apu.dispatch() as i32 * APU_DIVIDER;
                apu_master_cy_debt -= apu_master_cy;
                total_apu_cy += apu_master_cy as u64;
            }
            while ppu_master_cy_debt > 0 {
                let (cy, result) = self.cpu.mem.ppu.update();
                ppu_master_cy_debt -= cy as i32;
                total_ppu_cy += cy as u64;

                if result.hblank {
                    // TODO Do HDMA
                }
                if result.last_pixel {
                    self.renderer.render(&*self.cpu.mem.ppu.framebuf);
                }
                if result.vblank {
                    self.cpu.mem.input.new_frame();
                    if self.cpu.mem.nmi_enabled() {
                        //trace!("V-Blank NMI triggered! Trace started!");
                        //self.cpu.trace = true;
                        self.cpu.mem.nmi = true;
                        self.cpu.trigger_nmi();
                        // XXX Break to handle the NMI immediately. Let's hope we don't owe the PPU
                        // too many cycles.
                        break;
                    }
                }
                if result.new_frame {
                    self.cpu.mem.nmi = false;   // Flag cleared on read or end of VBlank
                }

                let cpu = &mut self.cpu;
                if cpu.mem.ppu.v_counter() == cpu.mem.vtime && cpu.mem.v_irq_enabled() {
                    cpu.mem.irq = true;
                    cpu.trigger_irq();
                    break;
                }
                if cpu.mem.ppu.h_counter() == cpu.mem.htime && cpu.mem.h_irq_enabled() {
                    cpu.mem.irq = true;
                    cpu.trigger_irq();
                    break;
                }
            }

            working_cy.set(master_cy);
        }

        info!("EXITING. Master cycle count: {}, APU: {}, PPU: {}",
            master_cy, total_apu_cy, total_ppu_cy);
    }
}
<commit_msg>Call do_hdma every H-Blank<commit_after>//! Contains the `Snes` struct, which wields the combined power of this project.

use apu::Apu;
use cpu::Cpu;
use dma::{do_dma, do_hdma, DmaChannel};
use frontend::Renderer;
use input::Input;
use log_util::LogOnPanic;
use ppu::Ppu;
use rom::Rom;

const WRAM_SIZE: usize = 128 * 1024;
byte_array!(Wram[WRAM_SIZE]);

/// Contains everything connected to the CPU via one of the two address buses. All memory accesses
/// will be directed through this (the CPU already takes access time into account).
pub struct Peripherals {
    apu: Apu,
    ppu: Ppu,
    rom: Rom,
    /// The 128 KB of working RAM of the SNES (separate from cartridge RAM)
    wram: Wram,
    input: Input,

    pub dma: [DmaChannel; 8],
    /// `$420c` - HDMAEN: HDMA enable flags
    /// (Note that general DMA doesn't have a register here, since all transactions are started
    /// immediately and the register can't be read)
    hdmaen: u8,
    /// `$4200` - NMITIMEN: Interrupt enable flags
    /// `n-xy---a`
    /// * `n`: Enable NMI on V-Blank
    /// * `x`: Enable IRQ on H-Counter match
    /// * `y`: Enable IRQ on V-Counter match
    /// * `a`: Enable auto-joypad read
    nmien: u8,
    /// `$4207`/`$4208` - HTIMEL/HTIMEH: H Timer (9-bit value)
    htime: u16,
    /// `$4209`/`$420a` - VTIMEL/VTIMEH: V Timer (9-bit value)
    vtime: u16,
    /// `$4210` NMI flag and 5A22 Version
    /// `n---vvvv`
    /// * `n`: `self.nmi`
    /// * `v`: Version
    nmi: bool,
    /// `$4211` TIMEUP - IRQ flag
    /// `i-------`
    /// * `i`: IRQ flag (cleared on read)
    irq: bool,

    /// Additional cycles spent doing IO (in master clock cycles). This is reset before each CPU
    /// instruction and added to the cycle count returned by the CPU.
    cy: u32,
}

impl Peripherals {
    pub fn new(rom: Rom) -> Peripherals {
        Peripherals {
            rom: rom,
            apu: Apu::new(),
            ppu: Ppu::new(),
            wram: Wram::default(),
            input: Input::default(),
            dma: [DmaChannel::new(); 8],
            hdmaen: 0x00,
            nmien: 0x00,
            htime: 0x1ff,
            vtime: 0x1ff,
            nmi: false,
            irq: false,
            cy: 0,
        }
    }

    pub fn load(&mut self, bank: u8, addr: u16) -> u8 {
        match bank {
            0x00 ... 0x3f | 0x80 ... 0xbf => match addr {
                // Mirror of first 8k of WRAM
                0x0000 ... 0x1fff => self.wram[addr as usize],
                // PPU
                0x2100 ... 0x2133 => panic!("read from write-only PPU register ${:04X}", addr),
                0x2138 ... 0x213f => self.ppu.load(addr),
                // APU IO registers
                0x2140 ... 0x217f => self.apu.read_port((addr & 0b11) as u8),
                0x4016 | 0x4017 => self.input.load(addr),
                0x4210 => {
                    const CPU_VERSION: u8 = 2;  // FIXME Is 2 okay in all cases? Does anyone care?
                    let nmi = if self.nmi { 0x80 } else { 0 };
                    self.nmi = false;   // Cleared on read
                    nmi | CPU_VERSION
                }
                0x4211 => {
                    let val = if self.irq { 0x80 } else { 0 };
                    self.irq = false;
                    val
                }
                0x4218 ... 0x421f => self.input.load(addr),
                // DMA channels (0x43xr, where x is the channel and r is the channel register)
                0x4300 ... 0x43ff => self.dma[(addr as usize & 0x00f0) >> 4].load(addr as u8 & 0xf),
                0x8000 ... 0xffff => self.rom.loadb(bank, addr),
                _ => panic!("invalid/unimplemented load from ${:02X}:{:04X}", bank, addr)
            },
            // WRAM banks. The first 8k are mapped into the start of all banks.
            0x7e | 0x7f => self.wram[(bank as usize - 0x7e) * 65536 + addr as usize],
            0x40 ... 0x7d | 0xc0 ... 0xff => self.rom.loadb(bank, addr),
            _ => unreachable!(),    // Rust should know this!
        }
    }

    pub fn store(&mut self, bank: u8, addr: u16, value: u8) {
        match bank {
            0x00 ... 0x3f | 0x80 ... 0xbf => match addr {
                0x0000 ... 0x1fff => self.wram[addr as usize] = value,
                // PPU registers. Let it deal with the access.
                0x2100 ... 0x2133 => self.ppu.store(addr, value),
                0x2138 ... 0x213f => panic!("store to read-only PPU register ${:04X}", addr),
                // APU IO registers.
                0x2140 ... 0x217f => self.apu.store_port((addr & 0b11) as u8, value),
                0x2180 ... 0x2183 => panic!("NYI: WRAM registers"),
                0x4016 => self.input.store(addr, value),
                0x4200 => {
                    // NMITIMEN - NMI/IRQ enable
                    // E-HV---J
                    // E: Enable NMI
                    // H: Enable IRQ on H-Counter
                    // V: Enable IRQ on V-Counter
                    // J: Enable Auto-Joypad-Read

                    // Check useless bits
                    if value & 0x4e != 0 { panic!("Invalid value for NMIEN: ${:02X}", value) }
                    self.nmien = value;
                }
                0x4207 => self.htime = (self.htime & 0xff00) | value as u16,
                0x4208 => {
                    assert!(value & 0x01 == value, "invalid value for $4207: ${:02X}", value);
                    self.htime = ((value as u16) << 8) | (self.htime & 0xff);
                }
                0x4209 => self.vtime = (self.vtime & 0xff00) | value as u16,
                0x420a => {
                    assert!(value & 0x01 == value, "invalid value for $4209: ${:02X}", value);
                    self.vtime = ((value as u16) << 8) | (self.vtime & 0xff);
                }
                // MDMAEN - Party enable
                0x420b => self.cy += do_dma(self, value),
                // HDMAEN - HDMA enable
                0x420c => self.hdmaen = value,
                // DMA channels (0x43xr, where x is the channel and r is the channel register)
                0x4300 ... 0x43ff => {
                    self.dma[(addr as usize & 0x00f0) >> 4].store(addr as u8 & 0xf, value);
                }
                0x8000 ... 0xffff => self.rom.storeb(bank, addr, value),
                _ => panic!("invalid store: ${:02X} to ${:02X}:{:04X}", value, bank, addr)
            },
            // WRAM main banks
            0x7e | 0x7f => self.wram[(bank as usize - 0x7e) * 65536 + addr as usize] = value,
            0x40 ... 0x7d | 0xc0 ... 0xff => self.rom.storeb(bank, addr, value),
            _ => unreachable!(),    // Rust should know this!
        }
    }

    fn nmi_enabled(&self) -> bool { self.nmien & 0x80 != 0 }
    fn v_irq_enabled(&self) -> bool { self.nmien & 0x10 != 0 }
    fn h_irq_enabled(&self) -> bool { self.nmien & 0x20 != 0 }
}

pub struct Snes {
    cpu: Cpu,
    renderer: Box<Renderer>,
}

impl Snes {
    pub fn new(rom: Rom, renderer: Box<Renderer>) -> Snes {
        Snes {
            cpu: Cpu::new(Peripherals::new(rom)),
            renderer: renderer,
        }
    }

    pub fn run(&mut self) {
        /// Exit after this number of master clock cycles
        const CY_LIMIT: u64 = 150_000_000;
        /// Start tracing at this master cycle (0 to trace everything)
        const TRACE_START: u64 = CY_LIMIT - 10_000;

        /// Approximated APU clock divider. It's actually somewhere around 20.9..., which is why we
        /// can't directly use `MASTER_CLOCK_FREQ / APU_CLOCK_FREQ` (it would round down, which
        /// might not be critical, but better safe than sorry).
        const APU_DIVIDER: i32 = 21;

        // Master cycle counter, used only for debugging atm
        let mut master_cy: u64 = 0;
        let mut total_apu_cy: u64 = 0;
        let mut total_ppu_cy: u64 = 0;
        // Master clock cycles for the APU not yet accounted for (can be negative)
        let mut apu_master_cy_debt = 0;
        let mut ppu_master_cy_debt = 0;
        let working_cy = LogOnPanic::new(0);

        while master_cy < CY_LIMIT {
            if master_cy >= TRACE_START {
                self.cpu.trace = true;
                self.cpu.mem.apu.trace = true;
            }

            // Run a CPU instruction and calculate the master cycles elapsed
            self.cpu.mem.cy = 0;
            let cpu_master_cy = self.cpu.dispatch() as i32 + self.cpu.mem.cy as i32;
            master_cy += cpu_master_cy as u64;

            // Now we "owe" the other components a few cycles:
            apu_master_cy_debt += cpu_master_cy;
            ppu_master_cy_debt += cpu_master_cy;

            // Run all components until we no longer owe them:
            while apu_master_cy_debt > APU_DIVIDER {
                // (Since the APU uses lots of cycles to do stuff - lower clock rate and such - we
                // only run it if we owe it `APU_DIVIDER` master cycles - or one SPC700 cycle)
                let apu_master_cy = self.cpu.mem.apu.dispatch() as i32 * APU_DIVIDER;
                apu_master_cy_debt -= apu_master_cy;
                total_apu_cy += apu_master_cy as u64;
            }
            while ppu_master_cy_debt > 0 {
                let (cy, result) = self.cpu.mem.ppu.update();
                ppu_master_cy_debt -= cy as i32;
                total_ppu_cy += cy as u64;

                if result.hblank {
                    // FIXME Cycles
                    do_hdma(self.cpu.mem.hdmaen);
                }
                if result.last_pixel {
                    self.renderer.render(&*self.cpu.mem.ppu.framebuf);
                }
                if result.vblank {
                    self.cpu.mem.input.new_frame();
                    if self.cpu.mem.nmi_enabled() {
                        //trace!("V-Blank NMI triggered! Trace started!");
                        //self.cpu.trace = true;
                        self.cpu.mem.nmi = true;
                        self.cpu.trigger_nmi();
                        // XXX Break to handle the NMI immediately. Let's hope we don't owe the PPU
                        // too many cycles.
                        break;
                    }
                }
                if result.new_frame {
                    self.cpu.mem.nmi = false;   // Flag cleared on read or end of VBlank
                }

                let cpu = &mut self.cpu;
                if cpu.mem.ppu.v_counter() == cpu.mem.vtime && cpu.mem.v_irq_enabled() {
                    cpu.mem.irq = true;
                    cpu.trigger_irq();
                    break;
                }
                if cpu.mem.ppu.h_counter() == cpu.mem.htime && cpu.mem.h_irq_enabled() {
                    cpu.mem.irq = true;
                    cpu.trigger_irq();
                    break;
                }
            }

            working_cy.set(master_cy);
        }

        info!("EXITING. Master cycle count: {}, APU: {}, PPU: {}",
            master_cy, total_apu_cy, total_ppu_cy);
    }
}
<|endoftext|>


<commit_before>#![warn(clippy::drop_ref, clippy::forget_ref)]
#![allow(clippy::toplevel_ref_arg, clippy::similar_names, clippy::needless_pass_by_value)]

use std::mem::{drop, forget};

struct SomeStruct;

fn main() {
    drop(&SomeStruct);
    forget(&SomeStruct);

    let mut owned1 = SomeStruct;
    drop(&owned1);
    drop(&&owned1);
    drop(&mut owned1);
    drop(owned1); //OK
    let mut owned2 = SomeStruct;
    forget(&owned2);
    forget(&&owned2);
    forget(&mut owned2);
    forget(owned2); //OK

    let reference1 = &SomeStruct;
    drop(reference1);
    forget(&*reference1);

    let reference2 = &mut SomeStruct;
    drop(reference2);
    let reference3 = &mut SomeStruct;
    forget(reference3);

    let ref reference4 = SomeStruct;
    drop(reference4);
    forget(reference4);
}

#[allow(dead_code)]
fn test_generic_fn_drop<T>(val: T) {
    drop(&val);
    drop(val); //OK
}

#[allow(dead_code)]
fn test_generic_fn_forget<T>(val: T) {
    forget(&val);
    forget(val); //OK
}

#[allow(dead_code)]
fn test_similarly_named_function() {
    fn drop<T>(_val: T) {}
    drop(&SomeStruct); //OK; call to unrelated function which happens to have the same name
    std::mem::drop(&SomeStruct);
    fn forget<T>(_val: T) {}
    forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name
    std::mem::forget(&SomeStruct);
}
<commit_msg>Don't nudge people towards toilet closures when producing owl results<commit_after>#![warn(clippy::drop_ref, clippy::forget_ref)]
#![allow(clippy::toplevel_ref_arg, clippy::similar_names, clippy::needless_pass_by_value)]

use std::mem::{drop, forget};

struct SomeStruct;

fn main() {
    drop(&SomeStruct);
    forget(&SomeStruct);

    let mut owned1 = SomeStruct;
    drop(&owned1);
    drop(&&owned1);
    drop(&mut owned1);
    drop(owned1); //OK
    let mut owned2 = SomeStruct;
    forget(&owned2);
    forget(&&owned2);
    forget(&mut owned2);
    forget(owned2); //OK

    let reference1 = &SomeStruct;
    drop(reference1);
    forget(&*reference1);

    let reference2 = &mut SomeStruct;
    drop(reference2);
    let reference3 = &mut SomeStruct;
    forget(reference3);

    let ref reference4 = SomeStruct;
    drop(reference4);
    forget(reference4);
}

#[allow(dead_code)]
fn test_generic_fn_drop<T>(val: T) {
    drop(&val);
    drop(val); //OK
}

#[allow(dead_code)]
fn test_generic_fn_forget<T>(val: T) {
    forget(&val);
    forget(val); //OK
}

#[allow(dead_code)]
fn test_similarly_named_function() {
    fn drop<T>(_val: T) {}
    drop(&SomeStruct); //OK; call to unrelated function which happens to have the same name
    std::mem::drop(&SomeStruct);
    fn forget<T>(_val: T) {}
    forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name
    std::mem::forget(&SomeStruct);
}

#[derive(Copy, Clone)]
pub struct Error;
fn produce_half_owl_error() -> Result<(), Error> {
    Ok(())
}

fn produce_half_owl_ok() -> Result<bool, ()> {
    Ok(true)
}

#[allow(dead_code)]
fn test_owl_result() -> Result<(), ()> {
    produce_half_owl_error().map_err(|_| ())?;
    produce_half_owl_ok().map(|_| ())?;
    // the following should not be linted,
    // we should not force users to use toilet closures
    // to produce owl results when drop is more convenient
    produce_half_owl_error().map_err(drop)?;
    produce_half_owl_ok().map_err(drop)?;
    Ok(())
}

#[allow(dead_code)]
fn test_owl_result_2() -> Result<u8, ()> {
    produce_half_owl_error().map_err(|_| ())?;
    produce_half_owl_ok().map(|_| ())?;
    // the following should not be linted,
    // we should not force users to use toilet closures
    // to produce owl results when drop is more convenient
    produce_half_owl_error().map_err(drop)?;
    produce_half_owl_ok().map(drop)?;
    Ok(1)
}
<|endoftext|>


<commit_before>extern crate std;
use std::vec::{Vec};

pub fn merge_sort<T: Ord + Clone>(q: &Vec<T>) -> Vec<T> {
    type Slice = (uint, uint);

    return merge_sort_(q, (0u, q.len()));

    fn merge_sort_<T: Ord + Clone>(v: &Vec<T>, slice: Slice) -> Vec<T> {
        let begin = slice.val0();
        let end   = slice.val1();

        let v_len = end - begin;
        if v_len == 0 {
            return vec!(v.get(begin).clone());
        }
        if v_len == 1 {
            return vec!(v.get(begin).clone());
        }

        let mid = begin + v_len / 2;
        let a = (begin, mid);
        let b = (mid, end);

        return merge(merge_sort_(v, a),
        merge_sort_(v, b));
    }

    fn merge<T: Ord + Clone>(a: Vec<T>, b: Vec<T>) -> Vec<T> {
        let (a_len, b_len) = (a.len(), b.len());
        let (mut a_ix, mut b_ix) = (0u, 0u);
        let mut rs = Vec::with_capacity(a_len + b_len);

        while a_ix < a_len && b_ix < b_len {
            if a.get(a_ix) < b.get(b_ix) {
                rs.push(a.get(a_ix).clone());
                a_ix += 1;
            } else {
                rs.push(b.get(b_ix).clone());
                b_ix += 1;
            }
        }

        rs.push_all(a.slice(a_ix, a_len));
        rs.push_all(b.slice(b_ix, b_len));
        rs
    }
}

pub fn insertion_sort<T: Ord + Clone>(q: &Vec<T>) -> Vec<T>{
    let mut xs = q.clone();
    for i in range(1, xs.len()) {
        let mut j = i;
        while j >= 1  && xs.get(j) < xs.get(j - 1){
            if xs.get(j) < xs.get(j - 1) {
                let temp = xs.get(j - 1).clone();
                *xs.get_mut(j - 1) = xs.get(j).clone();
                *xs.get_mut(j) = temp.clone();
                j -= 1;
            }
        }
    }
    return xs;
}
<commit_msg>redundant extern<commit_after>use std::vec::{Vec};

pub fn merge_sort<T: Ord + Clone>(q: &Vec<T>) -> Vec<T> {
    type Slice = (uint, uint);

    return merge_sort_(q, (0u, q.len()));

    fn merge_sort_<T: Ord + Clone>(v: &Vec<T>, slice: Slice) -> Vec<T> {
        let begin = slice.val0();
        let end   = slice.val1();

        let v_len = end - begin;
        if v_len == 0 {
            return vec!(v.get(begin).clone());
        }
        if v_len == 1 {
            return vec!(v.get(begin).clone());
        }

        let mid = begin + v_len / 2;
        let a = (begin, mid);
        let b = (mid, end);

        return merge(merge_sort_(v, a),
        merge_sort_(v, b));
    }

    fn merge<T: Ord + Clone>(a: Vec<T>, b: Vec<T>) -> Vec<T> {
        let (a_len, b_len) = (a.len(), b.len());
        let (mut a_ix, mut b_ix) = (0u, 0u);
        let mut rs = Vec::with_capacity(a_len + b_len);

        while a_ix < a_len && b_ix < b_len {
            if a.get(a_ix) < b.get(b_ix) {
                rs.push(a.get(a_ix).clone());
                a_ix += 1;
            } else {
                rs.push(b.get(b_ix).clone());
                b_ix += 1;
            }
        }

        rs.push_all(a.slice(a_ix, a_len));
        rs.push_all(b.slice(b_ix, b_len));
        rs
    }
}

pub fn insertion_sort<T: Ord + Clone>(q: &Vec<T>) -> Vec<T>{
    let mut xs = q.clone();
    for i in range(1, xs.len()) {
        let mut j = i;
        while j >= 1  && xs.get(j) < xs.get(j - 1){
            if xs.get(j) < xs.get(j - 1) {
                let temp = xs.get(j - 1).clone();
                *xs.get_mut(j - 1) = xs.get(j).clone();
                *xs.get_mut(j) = temp.clone();
                j -= 1;
            }
        }
    }
    return xs;
}
<|endoftext|>


<commit_before>#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
extern crate num;
extern crate rand;
extern crate time;

use std::ops::{Add, Sub, Mul};
use num::Float;

pub use rng::{EncodeRng, RngExt};
pub use text::{split_line, wrap_lines, Map2DIterator, Map2DUtil};

mod rng;
mod text;
pub mod timing;

pub mod ease;

/// Clamp a value to range.
pub fn clamp<C: PartialOrd + Copy>(mn: C, mx: C, x: C) -> C {
    if x < mn {
        mn
    } else if x > mx {
        mx
    } else {
        x
    }
}

/// Deterministic noise.
pub fn noise(n: i32) -> f32 {
    use std::num::Wrapping;

    let n = Wrapping(n);
    let n = (n << 13) ^ n;
    let m = (n * (n * n * Wrapping(15731) + Wrapping(789221)) +
             Wrapping(1376312589)) & Wrapping(0x7fffffff);
    let Wrapping(m) = m;
    1.0 - m as f32 / 1073741824.0
}

/// Convert probability to a log odds deciban value.
///
/// Log odds correspond to the Bayesian probability for a hypothesis that
/// has decibans * 1/10 log_2(10) bits of evidence in favor of it. They're
/// a bit like rolling a d20 but better.
pub fn to_log_odds(p: f32) -> f32 {
    10.0 * (p / (1.0 - p)).log(10.0)
}

/// Convert a log odds deciban value to the corresponding probability.
pub fn from_log_odds(db: f32) -> f32 {
    (1.0 - 1.0 / (1.0 + 10.0.powf(db / 10.0)))
}

/// Interpolate linearly between two values.
pub fn lerp<T, U>(a: U, b: U, t: T) -> U
    where U: Add<U, Output = U> + Sub<U, Output = U> + Mul<T, Output = U> + Copy
{
    a + (b - a) * t
}

/// Return the two arguments sorted to order.
pub fn sorted_pair<T: PartialOrd>(a: T, b: T) -> (T, T) {
    if a < b {
        (a, b)
    } else {
        (b, a)
    }
}
<commit_msg>Add count_exprs to calx-alg<commit_after>#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
extern crate num;
extern crate rand;
extern crate time;

use std::ops::{Add, Sub, Mul};
use num::Float;

pub use rng::{EncodeRng, RngExt};
pub use text::{split_line, wrap_lines, Map2DIterator, Map2DUtil};

mod rng;
mod text;
pub mod timing;

pub mod ease;

/// Clamp a value to range.
pub fn clamp<C: PartialOrd + Copy>(mn: C, mx: C, x: C) -> C {
    if x < mn {
        mn
    } else if x > mx {
        mx
    } else {
        x
    }
}

/// Deterministic noise.
pub fn noise(n: i32) -> f32 {
    use std::num::Wrapping;

    let n = Wrapping(n);
    let n = (n << 13) ^ n;
    let m = (n * (n * n * Wrapping(15731) + Wrapping(789221)) +
             Wrapping(1376312589)) & Wrapping(0x7fffffff);
    let Wrapping(m) = m;
    1.0 - m as f32 / 1073741824.0
}

/// Convert probability to a log odds deciban value.
///
/// Log odds correspond to the Bayesian probability for a hypothesis that
/// has decibans * 1/10 log_2(10) bits of evidence in favor of it. They're
/// a bit like rolling a d20 but better.
pub fn to_log_odds(p: f32) -> f32 {
    10.0 * (p / (1.0 - p)).log(10.0)
}

/// Convert a log odds deciban value to the corresponding probability.
pub fn from_log_odds(db: f32) -> f32 {
    (1.0 - 1.0 / (1.0 + 10.0.powf(db / 10.0)))
}

/// Interpolate linearly between two values.
pub fn lerp<T, U>(a: U, b: U, t: T) -> U
    where U: Add<U, Output = U> + Sub<U, Output = U> + Mul<T, Output = U> + Copy
{
    a + (b - a) * t
}

/// Return the two arguments sorted to order.
pub fn sorted_pair<T: PartialOrd>(a: T, b: T) -> (T, T) {
    if a < b {
        (a, b)
    } else {
        (b, a)
    }
}

// TODO: Remove this thing once Rust has a proper way of counting macro
// arguments.

/// Macro hack for counting the number of arguments.
///
/// Use for determining the size of a fixed array type created by a macro that
/// takes variadic arguments. Due to its hackiness, will fail around 100
/// elements.
#[macro_export]
macro_rules! count_exprs {
    () => { 0 };
    ($e:expr) => { 1 };
    ($e:expr, $($es:expr),+) => { 1 + count_exprs!($($es),*) };
}
<|endoftext|>