<commit_before>extern crate rs6502;

use std::io::{self, BufRead, Write};
use std::sync::mpsc::{channel, Receiver};
use std::thread;

use rs6502::{Cpu, Disassembler};

#[derive(Debug)]
pub struct MemoryMonitor {
    pub enabled: bool,
    start_addr: usize,
    end_addr: usize,
}

pub struct VirtualMachine {
    pub cpu: Cpu,
    pub monitor: MemoryMonitor,
    code_offset: u16,
    clock_rate: Option<u32>,
    receiver: Receiver<String>,
    last_command: String,
}

impl VirtualMachine {
    pub fn new<CR>(cpu: Cpu, code_offset: u16, clock_rate: CR) -> VirtualMachine
        where CR: Into<Option<u32>>
    {
        let (tx, rx) = channel();

        thread::spawn(move || {
            std::io::stdout().write(b"hakka> ").unwrap();
            std::io::stdout().flush().unwrap();

            loop {
                let mut line = String::new();
                let stdin = io::stdin();
                stdin.lock().read_line(&mut line).expect("Could not read line");
                tx.send(line).unwrap();
            }
        });

        VirtualMachine {
            cpu: cpu,
            code_offset: code_offset,
            clock_rate: clock_rate.into(),
            receiver: rx,
            monitor: MemoryMonitor {
                enabled: false,
                start_addr: 0,
                end_addr: 0,
            },
            last_command: "".into(),
        }
    }

    pub fn cycle(&mut self) {
        if let Some(clock_rate) = self.clock_rate {
            let mut n = 0;
            while n < clock_rate {
                n += self.cpu.step().expect("SEGFAULT") as u32;
            }
        } else {
            self.cpu.step().expect("SEGFAULT");
        }
    }

    pub fn try_execute_command(&mut self) {
        if let Ok(input) = self.receiver.try_recv() {
            let mut input: String = input.trim().into();

            if input.len() == 0 {
                if self.monitor.enabled {
                    self.monitor.enabled = false;
                } else {
                    input = self.last_command.clone();
                }
            }

            if input == "source" {
                self.dump_disassembly();
            }

            if input == "list" {
                self.dump_local_disassembly();
            }

            if input.starts_with("monitor") {
                if self.monitor.enabled {
                    self.monitor.enabled = false;
                } else {
                    self.enable_memory_monitor(&input);
                }
            }

            if input.starts_with("memset") {
                let parts: Vec<&str> = input.split(" ").collect();
                if parts.len() < 3 {
                    println!("ERR: Requires 2 arguments. Example: memset 0x00 0x01 to store 0x01 \
                              in 0x00.");
                } else if parts.len() == 3 {
                    if let Ok(dst) = u16::from_str_radix(&parts[1].replace("0x", "")[..], 16) {
                        if let Ok(src) = u8::from_str_radix(&parts[2].replace("0x", "")[..], 16) {
                            self.cpu.memory[dst as usize] = src;
                        } else {
                            println!("ERR: Unable to parse source byte value");
                        }
                    } else {
                        println!("ERR: Unable to parse destination byte value");
                    }
                } else {
                    if let Ok(mut dst) = usize::from_str_radix(&parts[1].replace("0x", "")[..],
                                                               16) {
                        for p in &parts[2..] {
                            if let Ok(byte) = u8::from_str_radix(&p.replace("0x", "")[..], 16) {
                                self.cpu.memory[dst] = byte;
                                dst += 0x01;
                            } else {
                                println!("ERR: Unable to parse source byte value");
                            }
                        }
                    } else {
                        println!("ERR: Unable to parse destination byte value");
                    }
                }
            }

            if input.starts_with("memdmp") {
                // 1 argument assumes 1 memory "page"
                let parts: Vec<&str> = input.split(" ").collect();
                if parts.len() == 2 {
                    let page_number: usize =
                        parts[1].parse().expect("Unable to parse memory page number");

                    self.dump_memory_page(page_number);
                }

            }

            std::io::stdout().write(b"hakka> ").unwrap();
            std::io::stdout().flush().unwrap();

            // Don't assign a blank command as a last command
            if input.len() > 0 {
                self.last_command = input.clone();
            }
        }

    }

    fn enable_memory_monitor(&mut self, input: &str) {
        let parts: Vec<&str> = input.split(" ").collect();
        if parts.len() < 3 {
            println!("ERR: Requires 2 arguments. Example: monitor 0x00 0xFF");
        } else {
            let start = usize::from_str_radix(&parts[1].replace("0x", "")[..], 16).unwrap();
            let end = usize::from_str_radix(&parts[2].replace("0x", "")[..], 16).unwrap();

            self.monitor.start_addr = start;
            self.monitor.end_addr = end;
            self.monitor.enabled = true;

            println!("{:?}", self.monitor);
        }
    }

    fn dump_disassembly(&self) {
        println!("");
        println!("-- Disassembly --");

        let disassembler = Disassembler::with_offset(self.code_offset);
        let asm = disassembler.disassemble(self.cpu.get_code());
        print!("{}", asm);
    }

    fn dump_local_disassembly(&self) {
        println!("");
        println!("-- Disassembly --");

        let disassembler = Disassembler::with_offset(self.code_offset);
        let pc = self.cpu.registers.PC as usize;
        let (bytes, current_line) = if pc <= self.code_offset as usize + 0x0B {
            if pc + 0x0B >= self.cpu.memory.len() {
                (&self.cpu.memory[pc..], 0)
            } else {
                (&self.cpu.memory[pc..pc + 0x0A], 0)
            }
        } else {
            if pc + 0x0B >= self.cpu.memory.len() {
                (&self.cpu.memory[pc - 0x0A..], 10)
            } else {
                (&self.cpu.memory[pc - 0x0A..pc + 0x0A], 10)
            }
        };
        let asm = disassembler.disassemble(bytes);
        let highlighted = self.highlight_line(&asm, current_line);
        print!("{}", highlighted);
    }

    pub fn dump_memory_page(&self, page: usize) {
        let mut addr = page * 0x100;
        println!("-- Memory dump --");
        for chunk in self.cpu.memory[page * 0x100..(page * 0x100) + 0x100].chunks(8) {
            print!("{:04X}: ", addr);
            for b in chunk {
                print!("{:02X} ", *b);
            }
            addr += 0x08;
            println!("");
        }
    }

    pub fn dump_memory(&self) {
        println!("-- Memory dump --");
        for chunk in self.cpu.memory[self.monitor.start_addr..self.monitor.end_addr + 0x01]
            .chunks(8) {
            for b in chunk {
                print!("{:02X} ", *b);
            }
            println!("");
        }
    }

    fn highlight_line(&self, code: &str, line_number: usize) -> String {
        let mut result = Vec::new();
        let mut line_counter = 0;
        for line in code.lines() {
            if line_counter == line_number {
                result.push(format!("{} {}", "> ", line.clone()));
            } else {
                result.push(format!("{} {}", "  ", line.clone()));
            }
            line_counter += 0x01;
        }

        result.join("\n")
    }
}<commit_msg>Add break and continue support<commit_after>extern crate rs6502;

use std::io::{self, BufRead, Write};
use std::sync::mpsc::{channel, Receiver};
use std::thread;

use rs6502::{Cpu, Disassembler};

#[derive(Debug)]
pub struct MemoryMonitor {
    pub enabled: bool,
    start_addr: usize,
    end_addr: usize,
}

pub struct VirtualMachine {
    pub cpu: Cpu,
    pub monitor: MemoryMonitor,
    code_offset: u16,
    clock_rate: Option<u32>,
    receiver: Receiver<String>,
    last_command: String,
    breakpoints: [u8; 64 * 1024],
    broken: bool,
}

impl VirtualMachine {
    pub fn new<CR>(cpu: Cpu, code_offset: u16, clock_rate: CR) -> VirtualMachine
        where CR: Into<Option<u32>>
    {
        let (tx, rx) = channel();

        thread::spawn(move || {
            std::io::stdout().write(b"hakka> ").unwrap();
            std::io::stdout().flush().unwrap();

            loop {
                let mut line = String::new();
                let stdin = io::stdin();
                stdin.lock().read_line(&mut line).expect("Could not read line");
                tx.send(line).unwrap();
            }
        });

        VirtualMachine {
            cpu: cpu,
            code_offset: code_offset,
            clock_rate: clock_rate.into(),
            receiver: rx,
            monitor: MemoryMonitor {
                enabled: false,
                start_addr: 0,
                end_addr: 0,
            },
            last_command: "".into(),
            breakpoints: [0; 64 * 1024],
            broken: false,
        }
    }

    pub fn cycle(&mut self) {
        if let Some(clock_rate) = self.clock_rate {
            let mut n = 0;
            while n < clock_rate && !self.broken {
                n += self.cpu.step().expect("SEGFAULT") as u32;
                if self.breakpoints[self.cpu.registers.PC as usize] > 0 {
                    self.broken = true;
                    println!("");
                    println!("BREAKPOINT hit at {:04X}", self.cpu.registers.PC);
                }
            }
        } else {
            self.cpu.step().expect("SEGFAULT");
            if self.breakpoints[self.cpu.registers.PC as usize] > 0 {
                self.broken = true;
                println!("");
                println!("BREAKPOINT hit at {:04X}", self.cpu.registers.PC);
            }
        }
    }

    pub fn try_execute_command(&mut self) {
        if let Ok(input) = self.receiver.try_recv() {
            let mut input: String = input.trim().into();

            if input.len() == 0 {
                if self.monitor.enabled {
                    self.monitor.enabled = false;
                } else {
                    input = self.last_command.clone();
                }
            }

            if input == "source" {
                self.dump_disassembly();
            }

            if input == "list" {
                self.dump_local_disassembly();
            }

            if input.starts_with("monitor") {
                if self.monitor.enabled {
                    self.monitor.enabled = false;
                } else {
                    self.enable_memory_monitor(&input);
                }
            }

            if input.starts_with("memset") {
                let parts: Vec<&str> = input.split(" ").collect();
                if parts.len() < 3 {
                    println!("ERR: Requires 2 arguments. Example: memset 0x00 0x01 to store 0x01 \
                              in 0x00.");
                } else if parts.len() == 3 {
                    if let Ok(dst) = u16::from_str_radix(&parts[1].replace("0x", "")[..], 16) {
                        if let Ok(src) = u8::from_str_radix(&parts[2].replace("0x", "")[..], 16) {
                            self.cpu.memory[dst as usize] = src;
                        } else {
                            println!("ERR: Unable to parse source byte value");
                        }
                    } else {
                        println!("ERR: Unable to parse destination byte value");
                    }
                } else {
                    if let Ok(mut dst) = usize::from_str_radix(&parts[1].replace("0x", "")[..],
                                                               16) {
                        for p in &parts[2..] {
                            if let Ok(byte) = u8::from_str_radix(&p.replace("0x", "")[..], 16) {
                                self.cpu.memory[dst] = byte;
                                dst += 0x01;
                            } else {
                                println!("ERR: Unable to parse source byte value");
                            }
                        }
                    } else {
                        println!("ERR: Unable to parse destination byte value");
                    }
                }
            }

            if input.starts_with("memdmp") {
                // 1 argument assumes 1 memory "page"
                let parts: Vec<&str> = input.split(" ").collect();
                if parts.len() == 2 {
                    let page_number: usize =
                        parts[1].parse().expect("Unable to parse memory page number");

                    self.dump_memory_page(page_number);
                }
            }

            if input.starts_with("break") {
                // 1 argument assumes 1 memory "page"
                let parts: Vec<&str> = input.split(" ").collect();
                if parts.len() == 2 {
                    if let Ok(addr) = usize::from_str_radix(&parts[1][..], 16) {
                        self.breakpoints[addr] = 1;
                    } else {
                        println!("Err: Unable to parse breakpoint address");
                    }
                } else {
                    println!("ERR: Requires 1 argument");
                }
            }

            if input == "continue" {
                self.broken = false;
                println!("Execution resumed");
            }

            std::io::stdout().write(b"hakka> ").unwrap();
            std::io::stdout().flush().unwrap();

            // Don't assign a blank command as a last command
            if input.len() > 0 {
                self.last_command = input.clone();
            }
        }

    }

    fn enable_memory_monitor(&mut self, input: &str) {
        let parts: Vec<&str> = input.split(" ").collect();
        if parts.len() < 3 {
            println!("ERR: Requires 2 arguments. Example: monitor 0x00 0xFF");
        } else {
            let start = usize::from_str_radix(&parts[1].replace("0x", "")[..], 16).unwrap();
            let end = usize::from_str_radix(&parts[2].replace("0x", "")[..], 16).unwrap();

            self.monitor.start_addr = start;
            self.monitor.end_addr = end;
            self.monitor.enabled = true;

            println!("{:?}", self.monitor);
        }
    }

    fn dump_disassembly(&self) {
        println!("");
        println!("-- Disassembly --");

        let disassembler = Disassembler::with_offset(self.code_offset);
        let pairs = disassembler.disassemble_with_addresses(self.cpu.get_code());
        let result = self.highlight_lines(self.cpu.registers.PC as usize, pairs, false).join("");
        print!("{}", result);
    }

    fn dump_local_disassembly(&self) {
        println!("");
        println!("-- Disassembly --");

        let disassembler = Disassembler::with_offset(self.code_offset);
        let pc = self.cpu.registers.PC as usize;
        let code = self.cpu.get_code();
        let pairs = disassembler.disassemble_with_addresses(code);
        let result = self.highlight_lines(pc, pairs, true).join("");
        print!("{}", result);
    }

    pub fn dump_memory_page(&self, page: usize) {
        let mut addr = page * 0x100;
        println!("-- Memory dump --");
        for chunk in self.cpu.memory[page * 0x100..(page * 0x100) + 0x100].chunks(8) {
            print!("{:04X}: ", addr);
            for b in chunk {
                print!("{:02X} ", *b);
            }
            addr += 0x08;
            println!("");
        }
    }

    pub fn dump_memory(&self) {
        println!("-- Memory dump --");
        for chunk in self.cpu.memory[self.monitor.start_addr..self.monitor.end_addr + 0x01]
            .chunks(8) {
            for b in chunk {
                print!("{:02X} ", *b);
            }
            println!("");
        }
    }

    fn highlight_lines(&self,
                       pc: usize,
                       pairs: Vec<(String, u16)>,
                       limit_results: bool)
                       -> Vec<String> {
        let mut result = Vec::new();

        let base = pc - self.code_offset as usize;

        for pair in pairs {
            if limit_results {
                let start = if base > 0x0A { base - 0x0A } else { 0 };
                if (pair.1 as usize) < start || (pair.1 as usize) > base + 0x0A {
                    continue;
                }
            }
            let breakpoint = self.breakpoints[self.code_offset as usize + pair.1 as usize] > 0x00;
            let current_line = pc as u16 == self.code_offset + pair.1;

            if breakpoint && current_line {
                result.push(format!("> * {}", pair.0));
            } else if breakpoint && !current_line {
                result.push(format!("  * {}", pair.0));
            } else {
                result.push(format!("    {}", pair.0));
            }
        }

        result
    }
}<|endoftext|>


<commit_before>use envelope_lib;
pub use envelope_lib::Envelope as Trait;
use std::iter::FromIterator;

/// An alias to the type of point to be used for amp and freq interpolation.
pub type Point = envelope_lib::BezierPoint<f64, f64>;

/// An alias for the envelope to be used used for amp and freq interpolation.
#[derive(Clone, Debug, PartialEq)]
pub struct Envelope {
    pub points: Vec<Point>,
}

impl FromIterator<Point> for Envelope {
    fn from_iter<T>(iter: T) -> Self where T: IntoIterator<Item=Point> {
        Envelope { points: iter.into_iter().collect(), }
    }
}

impl ::std::convert::From<Vec<Point>> for Envelope {
    fn from(points: Vec<Point>) -> Self {
        Envelope { points: points }
    }
}

impl<'a> Trait<'a> for Envelope {
    type X = f64;
    type Y = f64;
    type Point = Point;
    type Points = ::std::slice::Iter<'a, Point>;
    #[inline]
    fn points(&'a self) -> Self::Points { self.points.iter() }
}
<commit_msg>Clean up std namespacing.<commit_after>use envelope_lib;
pub use envelope_lib::Envelope as Trait;
use std;

/// An alias to the type of point to be used for amp and freq interpolation.
pub type Point = envelope_lib::BezierPoint<f64, f64>;

/// An alias for the envelope to be used used for amp and freq interpolation.
#[derive(Clone, Debug, PartialEq)]
pub struct Envelope {
    pub points: Vec<Point>,
}

impl std::iter::FromIterator<Point> for Envelope {
    fn from_iter<T>(iter: T) -> Self
        where T: IntoIterator<Item=Point>
    {
        Envelope { points: iter.into_iter().collect() }
    }
}

impl std::convert::From<Vec<Point>> for Envelope {
    fn from(points: Vec<Point>) -> Self {
        Envelope { points: points }
    }
}

impl<'a> Trait<'a> for Envelope {
    type X = f64;
    type Y = f64;
    type Point = Point;
    type Points = std::slice::Iter<'a, Point>;
    #[inline]
    fn points(&'a self) -> Self::Points { self.points.iter() }
}
<|endoftext|>


<commit_before>use answer::Answer;
use expr::Expr;
use query::Query;
use row::Row;

pub fn execute(query: Query, source: Box<Iterator<Item=Row>>) -> Answer {
    let mut aggregates = Vec::new();
    let mut non_aggregates = Vec::new();

    for expr in query.select.iter() {
        if let Some(call) = expr.get_aggregate_call() {
            let aggregate = call.function.aggregate();
            aggregates.push((aggregate, call));
        } else {
            non_aggregates.push(expr.clone());
        }
    }

    let output_rows = if aggregates.len() > 0 {
        for row in source {
            for tuple in aggregates.iter_mut() {
                let &mut(ref mut aggregate, ref call) = tuple;
                aggregate.apply(call.argument.eval(&row));
            }
        }

        let mut aggregate_row = Row::new();
        for tuple in aggregates.iter() {
            let &(ref aggregate, ref call) = tuple;
            aggregate_row.fields.insert(Expr::AggregateCall(call.clone()), aggregate.final_value());
        }

        vec![aggregate_row]
    } else {
        let mut rows = Vec::new();
        for input_row in source {
            let mut row = Row::new();
            for field in non_aggregates.iter() {
                let name = format!("{}", field);
                row.fields.insert(Expr::Column(name), field.eval(&input_row));
            }
            rows.push(row);
        }

        rows
    };

    let mut columns = Vec::new();
    for field in query.select.iter() {
        columns.push(format!("{}", field));
    }

    let mut rows = Vec::new();
    for output_row in output_rows {
        let mut row = Vec::new();
        for field in query.select.iter() {
            row.push(field.eval(&output_row));
        }
        rows.push(row);
    }

    Answer{columns: columns, rows: rows}
}

#[cfg(test)]
mod tests {
    use super::*;
    use aggregate::{AggregateCall, AggregateFunction};
    use data::Data;
    use expr::Expr;
    use row::make_rows;

    #[test]
    fn aggregate_query() {
        let source = make_rows(vec!["a"], vec![
            vec![Data::Int(1)],
            vec![Data::Int(2)],
            vec![Data::Int(3)],
            vec![Data::Int(4)],
            vec![Data::Int(5)],
        ]);

        let call = AggregateCall{
            function: AggregateFunction::Sum,
            argument: Box::new(Expr::Column(String::from("a"))),
        };

        let query = Query {
            select: vec![Expr::AggregateCall(call)],
            from: String::new(),
        };

        let actual = execute(query, Box::new(source.into_iter()));
        let expected = Answer {
            columns: vec![String::from("sum(a)")],
            rows: vec![vec![Data::Int(15)]],
        };

        assert_eq!(expected, actual);
    }

    #[test]
    fn non_aggregate_query() {
        let source = make_rows(vec!["a"], vec![
            vec![Data::Int(1)],
            vec![Data::Int(2)],
            vec![Data::Int(3)],
            vec![Data::Int(4)],
            vec![Data::Int(5)],
        ]);

        let query = Query {
            select: vec![Expr::Column(String::from("a"))],
            from: String::new(),
        };

        let actual = execute(query, Box::new(source.clone().into_iter()));
        let expected = Answer {
            columns: vec![String::from("a")],
            rows: vec![
                vec![Data::Int(1)],
                vec![Data::Int(2)],
                vec![Data::Int(3)],
                vec![Data::Int(4)],
                vec![Data::Int(5)],
            ],
        };

        assert_eq!(expected, actual);
    }
}
<commit_msg>Refactor to use Executor<commit_after>use std::collections::HashMap;
use aggregate::AggregateCall;
use answer::Answer;
use expr::Expr;
use query::Query;
use row::Row;

struct Executor {
    query: Query,
    aggregate_calls: Vec<AggregateCall>,
    non_aggregates: Vec<Expr>,
}

impl Executor {
    fn new(query: Query) -> Self {
        let mut aggregates = Vec::new();
        let mut non_aggregates = Vec::new();

        for expr in query.select.iter() {
            if let Some(call) = expr.get_aggregate_call() {
                aggregates.push(call);
            } else {
                non_aggregates.push(expr.clone());
            }
        }

        Executor {
            query: query,
            aggregate_calls: aggregates,
            non_aggregates: non_aggregates,
        }
    }

    fn execute(&self, source: Box<Iterator<Item=Row>>) -> Answer {
        if self.aggregate_calls.is_empty() {
            self.execute_non_aggregate(source)
        } else {
            self.execute_aggregate(source)
        }
    }

    fn execute_non_aggregate(&self, source: Box<Iterator<Item=Row>>) -> Answer {
        let mut rows = Vec::new();
        for input_row in source {
            let mut row = Vec::new();
            for field in self.non_aggregates.iter() {
                row.push(field.eval(&input_row));
            }
            rows.push(row);
        }

        Answer {
            columns: self.get_columns(),
            rows: rows,
        }
    }

    fn execute_aggregate(&self, source: Box<Iterator<Item=Row>>) -> Answer {
        let mut aggregates = HashMap::new();
        for call in self.aggregate_calls.iter() {
            aggregates.insert(call.clone(), call.function.aggregate());
        }

        for row in source {
            for (call, aggregate) in aggregates.iter_mut() {
                aggregate.apply(call.argument.eval(&row));
            }
        }

        let mut aggregate_row = Row::new();
        for (call, aggregate) in aggregates {
            aggregate_row.fields.insert(Expr::AggregateCall(call), aggregate.final_value());
        }

        let mut output_row = Vec::new();
        for field in self.query.select.iter() {
            output_row.push(field.eval(&aggregate_row));
        }

        Answer {
            columns: self.get_columns(),
            rows: vec![output_row],
        }
    }

    fn get_columns(&self) -> Vec<String> {
        let mut columns = Vec::new();
        for field in self.query.select.iter() {
            columns.push(format!("{}", field));
        }
        columns
    }
}

pub fn execute(query: Query, source: Box<Iterator<Item=Row>>) -> Answer {
    Executor::new(query).execute(source)
}

#[cfg(test)]
mod tests {
    use super::*;
    use aggregate::{AggregateCall, AggregateFunction};
    use data::Data;
    use expr::Expr;
    use row::make_rows;

    #[test]
    fn aggregate_query() {
        let source = make_rows(vec!["a"], vec![
            vec![Data::Int(1)],
            vec![Data::Int(2)],
            vec![Data::Int(3)],
            vec![Data::Int(4)],
            vec![Data::Int(5)],
        ]);

        let call = AggregateCall{
            function: AggregateFunction::Sum,
            argument: Box::new(Expr::Column(String::from("a"))),
        };

        let query = Query {
            select: vec![Expr::AggregateCall(call)],
            from: String::new(),
        };

        let actual = execute(query, Box::new(source.into_iter()));
        let expected = Answer {
            columns: vec![String::from("sum(a)")],
            rows: vec![vec![Data::Int(15)]],
        };

        assert_eq!(expected, actual);
    }

    #[test]
    fn non_aggregate_query() {
        let source = make_rows(vec!["a"], vec![
            vec![Data::Int(1)],
            vec![Data::Int(2)],
            vec![Data::Int(3)],
            vec![Data::Int(4)],
            vec![Data::Int(5)],
        ]);

        let query = Query {
            select: vec![Expr::Column(String::from("a"))],
            from: String::new(),
        };

        let actual = execute(query, Box::new(source.clone().into_iter()));
        let expected = Answer {
            columns: vec![String::from("a")],
            rows: vec![
                vec![Data::Int(1)],
                vec![Data::Int(2)],
                vec![Data::Int(3)],
                vec![Data::Int(4)],
                vec![Data::Int(5)],
            ],
        };

        assert_eq!(expected, actual);
    }
}
<|endoftext|>


<commit_before>extern crate reqwest;

pub mod statistics;
mod scrape;

use config::Config;
use failure::{Error, ResultExt};
use std::io::Read;

#[derive(Debug, Clone)]
pub struct State {
    pub id: u32,
    pub abbrev: String,
}

impl State {
    pub fn new(id: u32, abbrev: String) -> State {
        State { id, abbrev }
    }
}

#[derive(Debug)]
pub struct Feed {
    pub id: u32,
    pub name: String,
    pub listeners: u32,
    pub state: State,
    pub county: String,
    pub alert: Option<String>,
}

impl Feed {
    pub fn download_and_scrape(config: &Config) -> Result<Vec<Feed>, Error> {
        let client = reqwest::Client::new();

        let mut feeds = FeedSource::Top.download_and_scrape(&client)?;

        if let Some(state_id) = config.misc.state_feeds_id {
            let state = State::new(state_id, "CS".into()); // CS = Config Specified
            let state_feeds = FeedSource::State(state).download_and_scrape(&client)?;

            feeds.extend(state_feeds);
        }

        filter_whitelist_blacklist(config, &mut feeds);

        feeds.sort_by_key(|feed| feed.id);
        feeds.dedup();

        Ok(feeds)
    }
}

impl PartialEq for Feed {
    fn eq(&self, other: &Feed) -> bool {
        self.id == other.id
    }
}

fn filter_whitelist_blacklist(config: &Config, feeds: &mut Vec<Feed>) {
    if !config.whitelist.is_empty() {
        feeds.retain(|feed| {
            config
                .whitelist
                .iter()
                .any(|entry| entry.matches_feed(feed))
        });
    }

    if !config.blacklist.is_empty() {
        feeds.retain(|feed| {
            config
                .blacklist
                .iter()
                .any(|entry| !entry.matches_feed(feed))
        });
    }
}

// TODO: move to scrape module (?)
#[derive(Fail, Debug)]
pub enum FeedSourceError {
    #[fail(display = "failed to parse top feeds")] FailedToParseTopFeeds,
    #[fail(display = "failed to parse state feeds")] FailedToParseStateFeeds,
}

enum FeedSource {
    Top,
    State(State),
}

impl FeedSource {
    fn get_url(&self) -> String {
        match *self {
            FeedSource::Top => "http://www.broadcastify.com/listen/top".into(),
            FeedSource::State(ref state) => {
                format!("http://www.broadcastify.com/listen/stid/{}", state.id)
            }
        }
    }

    fn download_page(&self, client: &reqwest::Client) -> Result<String, Error> {
        let mut resp = client.get(&self.get_url()).send()?;
        let mut body = String::new();

        resp.read_to_string(&mut body)?;

        Ok(body)
    }

    fn scrape(&self, body: &str) -> Result<Vec<Feed>, Error> {
        match *self {
            FeedSource::Top => {
                let scraped =
                    scrape::scrape_top(body).context(FeedSourceError::FailedToParseTopFeeds)?;

                Ok(scraped)
            }
            FeedSource::State(ref state) => {
                let scraped = scrape::scrape_state(state, body)
                    .context(FeedSourceError::FailedToParseStateFeeds)?;

                Ok(scraped)
            }
        }
    }

    fn download_and_scrape(&self, client: &reqwest::Client) -> Result<Vec<Feed>, Error> {
        let body = self.download_page(client)?;
        self.scrape(&body)
    }
}
<commit_msg>Call text() method to get the response body instead of manually reading it<commit_after>extern crate reqwest;

pub mod statistics;
mod scrape;

use config::Config;
use failure::{Error, ResultExt};

#[derive(Debug, Clone)]
pub struct State {
    pub id: u32,
    pub abbrev: String,
}

impl State {
    pub fn new(id: u32, abbrev: String) -> State {
        State { id, abbrev }
    }
}

#[derive(Debug)]
pub struct Feed {
    pub id: u32,
    pub name: String,
    pub listeners: u32,
    pub state: State,
    pub county: String,
    pub alert: Option<String>,
}

impl Feed {
    pub fn download_and_scrape(config: &Config) -> Result<Vec<Feed>, Error> {
        let client = reqwest::Client::new();

        let mut feeds = FeedSource::Top.download_and_scrape(&client)?;

        if let Some(state_id) = config.misc.state_feeds_id {
            let state = State::new(state_id, "CS".into()); // CS = Config Specified
            let state_feeds = FeedSource::State(state).download_and_scrape(&client)?;

            feeds.extend(state_feeds);
        }

        filter_whitelist_blacklist(config, &mut feeds);

        feeds.sort_by_key(|feed| feed.id);
        feeds.dedup();

        Ok(feeds)
    }
}

impl PartialEq for Feed {
    fn eq(&self, other: &Feed) -> bool {
        self.id == other.id
    }
}

fn filter_whitelist_blacklist(config: &Config, feeds: &mut Vec<Feed>) {
    if !config.whitelist.is_empty() {
        feeds.retain(|feed| {
            config
                .whitelist
                .iter()
                .any(|entry| entry.matches_feed(feed))
        });
    }

    if !config.blacklist.is_empty() {
        feeds.retain(|feed| {
            config
                .blacklist
                .iter()
                .any(|entry| !entry.matches_feed(feed))
        });
    }
}

// TODO: move to scrape module (?)
#[derive(Fail, Debug)]
pub enum FeedSourceError {
    #[fail(display = "failed to parse top feeds")] FailedToParseTopFeeds,
    #[fail(display = "failed to parse state feeds")] FailedToParseStateFeeds,
}

enum FeedSource {
    Top,
    State(State),
}

impl FeedSource {
    fn get_url(&self) -> String {
        match *self {
            FeedSource::Top => "http://www.broadcastify.com/listen/top".into(),
            FeedSource::State(ref state) => {
                format!("http://www.broadcastify.com/listen/stid/{}", state.id)
            }
        }
    }

    fn download_page(&self, client: &reqwest::Client) -> Result<String, Error> {
        let body = client.get(&self.get_url()).send()?.text()?;
        Ok(body)
    }

    fn scrape(&self, body: &str) -> Result<Vec<Feed>, Error> {
        match *self {
            FeedSource::Top => {
                let scraped =
                    scrape::scrape_top(body).context(FeedSourceError::FailedToParseTopFeeds)?;

                Ok(scraped)
            }
            FeedSource::State(ref state) => {
                let scraped = scrape::scrape_state(state, body)
                    .context(FeedSourceError::FailedToParseStateFeeds)?;

                Ok(scraped)
            }
        }
    }

    fn download_and_scrape(&self, client: &reqwest::Client) -> Result<Vec<Feed>, Error> {
        let body = self.download_page(client)?;
        self.scrape(&body)
    }
}
<|endoftext|>


<commit_before>/**
 * Exponential Functions
 */

use num::Num;

use ncast::*;

pub trait Exp {
    pure fn pow(n: self) -> self;
    pure fn exp()        -> self;
    pure fn log_()       -> self;
    pure fn exp2()       -> self;
    pure fn log2()       -> self;
    pure fn sqrt()       -> self;
    pure fn inv_sqrt()   -> self;
}

#[inline(always)] pub pure fn pow<T:Exp>(x: T, n: T) -> T { x.pow(move n) }
#[inline(always)] pub pure fn exp<T:Exp>(x: T)       -> T { x.exp() }
#[inline(always)] pub pure fn log_<T:Exp>(x: T)      -> T { x.log_() }
#[inline(always)] pub pure fn exp2<T:Exp>(x: T)      -> T { x.exp2() }
#[inline(always)] pub pure fn log2<T:Exp>(x: T)      -> T { x.log2() }
#[inline(always)] pub pure fn sqrt<T:Exp>(x: T)      -> T { x.sqrt() }
#[inline(always)] pub pure fn inv_sqrt<T:Exp>(x: T)  -> T { x.inv_sqrt() }

pub impl f32: Exp {
    #[inline(always)] pure fn pow(n: f32)   -> f32 { f32::pow(self, n) }
    #[inline(always)] pure fn exp()         -> f32 { f32::exp(self) }
    #[inline(always)] pure fn log_()        -> f32 { f32::ln(self) }
    #[inline(always)] pure fn exp2()        -> f32 { f32::exp2(self) }
    #[inline(always)] pure fn log2()        -> f32 { f32::log2(self) }
    #[inline(always)] pure fn sqrt()        -> f32 { f32::sqrt(self) }
    #[inline(always)] pure fn inv_sqrt()    -> f32 { 1f32 / self.sqrt() }  // TODO: optimise? need a wizard
}

pub impl f64: Exp {
    #[inline(always)] pure fn pow(n: f64)   -> f64 { f64::pow(self, n) }
    #[inline(always)] pure fn exp()         -> f64 { f64::exp(self) }
    #[inline(always)] pure fn log_()        -> f64 { f64::ln(self) }
    #[inline(always)] pure fn exp2()        -> f64 { f64::exp2(self) }
    #[inline(always)] pure fn log2()        -> f64 { f64::log2(self) }
    #[inline(always)] pure fn sqrt()        -> f64 { f64::sqrt(self) }
    #[inline(always)] pure fn inv_sqrt()    -> f64 { 1f64 / self.sqrt() }  // TODO: optimise? need a wizard
}

pub impl float: Exp {
    #[inline(always)] pure fn pow(n: float) -> float { cast(float::pow(cast(self), cast(n))) }
    #[inline(always)] pure fn exp()         -> float { cast(float::exp(cast(self))) }
    #[inline(always)] pure fn log_()        -> float { cast(float::ln(cast(self))) }
    #[inline(always)] pure fn exp2()        -> float { cast(float::exp2(cast(self))) }
    #[inline(always)] pure fn log2()        -> float { cast(float::log2(cast(self))) }
    #[inline(always)] pure fn sqrt()        -> float { cast(float::sqrt(cast(self))) }
    #[inline(always)] pure fn inv_sqrt()    -> float { 1f / self.sqrt() }  // TODO: optimise? need a wizard
}
<commit_msg>Implemented exponential functions for each vector type<commit_after>/**
 * Exponential Functions
 */

use num::Num;

use ncast::*;
use vector::{Vec2, Vec3, Vec4};

pub trait Exp {
    pure fn pow<N:NumCast>(n: &N) -> self;
    pure fn exp()      -> self;
    pure fn log_()     -> self;
    pure fn exp2()     -> self;
    pure fn log2()     -> self;
    pure fn sqrt()     -> self;
    pure fn inv_sqrt() -> self;
}

#[inline(always)] pub pure fn pow<T:Exp, N:NumCast>(x: &T, n: &N) -> T { x.pow(n) }
#[inline(always)] pub pure fn exp<T:Exp>(x: &T)      -> T { x.exp() }
#[inline(always)] pub pure fn log_<T:Exp>(x: &T)     -> T { x.log_() }
#[inline(always)] pub pure fn exp2<T:Exp>(x: &T)     -> T { x.exp2() }
#[inline(always)] pub pure fn log2<T:Exp>(x: &T)     -> T { x.log2() }
#[inline(always)] pub pure fn sqrt<T:Exp>(x: &T)     -> T { x.sqrt() }
#[inline(always)] pub pure fn inv_sqrt<T:Exp>(x: &T) -> T { x.inv_sqrt() }

pub impl f32: Exp {
    #[inline(always)] pure fn pow<N:NumCast>(n: &N) -> f32 { f32::pow(self, n.cast()) }
    #[inline(always)] pure fn exp()      -> f32 { f32::exp(self) }
    #[inline(always)] pure fn log_()     -> f32 { f32::ln(self) }
    #[inline(always)] pure fn exp2()     -> f32 { f32::exp2(self) }
    #[inline(always)] pure fn log2()     -> f32 { f32::log2(self) }
    #[inline(always)] pure fn sqrt()     -> f32 { f32::sqrt(self) }
    #[inline(always)] pure fn inv_sqrt() -> f32 { 1f32 / self.sqrt() }  // TODO: optimise? need a wizard
}

pub impl f64: Exp {
    #[inline(always)] pure fn pow<N:NumCast>(n: &N) -> f64 { f64::pow(self, n.cast()) }
    #[inline(always)] pure fn exp()      -> f64 { f64::exp(self) }
    #[inline(always)] pure fn log_()     -> f64 { f64::ln(self) }
    #[inline(always)] pure fn exp2()     -> f64 { f64::exp2(self) }
    #[inline(always)] pure fn log2()     -> f64 { f64::log2(self) }
    #[inline(always)] pure fn sqrt()     -> f64 { f64::sqrt(self) }
    #[inline(always)] pure fn inv_sqrt() -> f64 { 1f64 / self.sqrt() }  // TODO: optimise? need a wizard
}

pub impl float: Exp {
    #[inline(always)] pure fn pow<N:NumCast>(n: &N) -> float { cast(float::pow(cast(self), n.cast())) }
    #[inline(always)] pure fn exp()      -> float { cast(float::exp(cast(self))) }
    #[inline(always)] pure fn log_()     -> float { cast(float::ln(cast(self))) }
    #[inline(always)] pure fn exp2()     -> float { cast(float::exp2(cast(self))) }
    #[inline(always)] pure fn log2()     -> float { cast(float::log2(cast(self))) }
    #[inline(always)] pure fn sqrt()     -> float { cast(float::sqrt(cast(self))) }
    #[inline(always)] pure fn inv_sqrt() -> float { 1f / self.sqrt() }  // TODO: optimise? need a wizard
}

pub impl<T:Copy Exp> Vec2<T>: Exp {
    #[inline(always)]
    pure fn pow<N:NumCast>(n: &N) -> Vec2<T> {
        Vec2::new(pow(&self[0], n),
                  pow(&self[1], n))
    }

    #[inline(always)]
    pure fn exp() -> Vec2<T> {
        Vec2::new(exp(&self[0]),
                  exp(&self[1]))
    }

    #[inline(always)]
    pure fn log_() -> Vec2<T> {
        Vec2::new(log_(&self[0]),
                  log_(&self[1]))
    }

    #[inline(always)]
    pure fn exp2() -> Vec2<T> {
        Vec2::new(exp2(&self[0]),
                  exp2(&self[1]))
    }

    #[inline(always)]
    pure fn log2() -> Vec2<T> {
        Vec2::new(log2(&self[0]),
                  log2(&self[1]))
    }

    #[inline(always)]
    pure fn sqrt() -> Vec2<T> {
        Vec2::new(sqrt(&self[0]),
                  sqrt(&self[1]))
    }

    #[inline(always)]
    pure fn inv_sqrt() -> Vec2<T> {
        Vec2::new(inv_sqrt(&self[0]),
                  inv_sqrt(&self[1]))
    }
}

pub impl<T:Copy Exp> Vec3<T>: Exp {
    #[inline(always)]
    pure fn pow<N:NumCast>(n: &N) -> Vec3<T> {
        Vec3::new(pow(&self[0], n),
                  pow(&self[1], n),
                  pow(&self[2], n))
    }

    #[inline(always)]
    pure fn exp() -> Vec3<T> {
        Vec3::new(exp(&self[0]),
                  exp(&self[1]),
                  exp(&self[2]))
    }

    #[inline(always)]
    pure fn log_() -> Vec3<T> {
        Vec3::new(log_(&self[0]),
                  log_(&self[1]),
                  log_(&self[2]))
    }

    #[inline(always)]
    pure fn exp2() -> Vec3<T> {
        Vec3::new(exp2(&self[0]),
                  exp2(&self[1]),
                  exp2(&self[2]))
    }

    #[inline(always)]
    pure fn log2() -> Vec3<T> {
        Vec3::new(log2(&self[0]),
                  log2(&self[1]),
                  log2(&self[2]))
    }

    #[inline(always)]
    pure fn sqrt() -> Vec3<T> {
        Vec3::new(sqrt(&self[0]),
                  sqrt(&self[1]),
                  sqrt(&self[2]))
    }

    #[inline(always)]
    pure fn inv_sqrt() -> Vec3<T> {
        Vec3::new(inv_sqrt(&self[0]),
                  inv_sqrt(&self[1]),
                  inv_sqrt(&self[2]))
    }
}

pub impl<T:Copy Exp> Vec4<T>: Exp {
    #[inline(always)]
    pure fn pow<N:NumCast>(n: &N) -> Vec4<T> {
        Vec4::new(pow(&self[0], n),
                  pow(&self[1], n),
                  pow(&self[2], n),
                  pow(&self[3], n))
    }

    #[inline(always)]
    pure fn exp() -> Vec4<T> {
        Vec4::new(exp(&self[0]),
                  exp(&self[1]),
                  exp(&self[2]),
                  exp(&self[3]))
    }

    #[inline(always)]
    pure fn log_() -> Vec4<T> {
        Vec4::new(log_(&self[0]),
                  log_(&self[1]),
                  log_(&self[2]),
                  log_(&self[3]))
    }

    #[inline(always)]
    pure fn exp2() -> Vec4<T> {
        Vec4::new(exp2(&self[0]),
                  exp2(&self[1]),
                  exp2(&self[2]),
                  exp2(&self[3]))
    }

    #[inline(always)]
    pure fn log2() -> Vec4<T> {
        Vec4::new(log2(&self[0]),
                  log2(&self[1]),
                  log2(&self[2]),
                  log2(&self[3]))
    }

    #[inline(always)]
    pure fn sqrt() -> Vec4<T> {
        Vec4::new(sqrt(&self[0]),
                  sqrt(&self[1]),
                  sqrt(&self[2]),
                  sqrt(&self[3]))
    }

    #[inline(always)]
    pure fn inv_sqrt() -> Vec4<T> {
        Vec4::new(inv_sqrt(&self[0]),
                  inv_sqrt(&self[1]),
                  inv_sqrt(&self[2]),
                  inv_sqrt(&self[3]))
    }
}<|endoftext|>


<commit_before>use ::screen;
use ::screen::Screen;

use piston_window;

pub struct Game {
    window: piston_window::PistonWindow,
    screens: Vec<Box<screen::Screen>>,
}

impl Game {
    pub fn new() -> Game {
        let window: piston_window::PistonWindow = piston_window::WindowSettings::new("rrthozopsi", [600, 600]).exit_on_esc(true).build().unwrap();
        let screens: Vec<Box<screen::Screen>> = vec![Box::new(screen::MainMenuScreen::new())];
        Game {
            window: window,
            screens: screens,
        }
    }

    pub fn run(&mut self) {
        use piston_window::Event;

        // TODO: Remove clone?
        for window in &mut self.window {
            match window.event {
                Some(Event::Update(ref args)) => { self.screens.last_mut().unwrap().on_update(&args); }
                Some(Event::Render(ref args)) => { self.screens.last_mut().unwrap().on_draw(&args, &window); }
                Some(Event::Input(ref input)) => {
                    for action in self.screens.last_mut().unwrap().on_input(&input, &window) {
                        match action {
                            screen::InputResult::PushScreen(new_screen) => {
                                self.screens.push(new_screen);
                            }
            		        screen::InputResult::PopScreen => {
            			        self.screens.pop();
            		        }
                        }
                    }
            	}
                _ => {}
            }
        }
    }
}

fn last<'a>(vec: &'a mut Vec<Box<screen::Screen>>) -> &'a mut Box<screen::Screen> {
    vec.last_mut().unwrap()
}<commit_msg>Use last function<commit_after>use ::screen;
use ::screen::Screen;

use piston_window;

pub struct Game {
    window: piston_window::PistonWindow,
    screens: Vec<Box<screen::Screen>>,
}

impl Game {
    pub fn new() -> Game {
        let window: piston_window::PistonWindow = piston_window::WindowSettings::new("rrthozopsi", [600, 600]).exit_on_esc(true).build().unwrap();
        let screens: Vec<Box<screen::Screen>> = vec![Box::new(screen::MainMenuScreen::new())];
        Game {
            window: window,
            screens: screens,
        }
    }

    pub fn run(&mut self) {
        use piston_window::Event;

        let screens = &mut self.screens;

        // TODO: Remove clone?
        for window in &mut self.window {
            match window.event {
                Some(Event::Update(ref args)) => { last(screens).on_update(&args); }
                Some(Event::Render(ref args)) => { last(screens).on_draw(&args, &window); }
                Some(Event::Input(ref input)) => {
                    for action in last(screens).on_input(&input, &window) {
                        match action {
                            screen::InputResult::PushScreen(new_screen) => {
                                screens.push(new_screen);
                            }
            		        screen::InputResult::PopScreen => {
            			        screens.pop();
            		        }
                        }
                    }
            	}
                _ => {}
            }
        }
    }
}

fn last<'a>(vec: &'a mut Vec<Box<screen::Screen>>) -> &'a mut Box<screen::Screen> {
    vec.last_mut().unwrap()
}<|endoftext|>


<commit_before>//! The graphite module is the default backend for capella.

use std::io::{self, Write};
use std::fmt::Write as FmtWrite;
use std::net::{SocketAddr, ToSocketAddrs};

use chrono::offset::local::Local;

use futures::Future;

use tokio_core::net::TcpStream;
use tokio_core::reactor::Core;

use backend::Backend;

use cache::CapellaCache;

/// The backend to a graphite server.
#[derive(Debug)]
pub struct Graphite {
    addr: SocketAddr,
}

impl Graphite {
    /// Construct a new graphite instance with a given address.
    pub fn new<A: ToSocketAddrs>(addr: A) -> io::Result<Graphite> {
        Ok(Graphite {
            addr: addr.to_socket_addrs()?.next().unwrap(),
        })
    }
}

impl Backend for Graphite {
    // TODO: Clear the cache?
    fn purge_metrics(&self, cache: &mut CapellaCache) {
        let mut core = Core::new().unwrap();
        let handle = core.handle();

        let unix_time = Local::now().timestamp();
        let mut buffer = String::new();

        for (k, v) in cache.counters_iter() {
            write!(buffer, "{} {} {}\n", k, v, unix_time);
        }

        for (k, v) in cache.gauges_iter() {
            write!(buffer, "{} {} {}\n", k, v, unix_time);
        }
        println!("{}", buffer);

        let send = TcpStream::connect(&self.addr, &handle).and_then(|mut out| {
            out.write_all(buffer.as_bytes());
            Ok(())
        });
        drop(core.run(send));
    }
}
<commit_msg>add some more to do comments<commit_after>//! The graphite module is the default backend for capella.

use std::io::{self, Write};
// TODO: Is this needed?
use std::fmt::Write as FmtWrite;
use std::net::{SocketAddr, ToSocketAddrs};

use chrono::offset::local::Local;

use futures::Future;

use tokio_core::net::TcpStream;
use tokio_core::reactor::Core;

use backend::Backend;

use cache::CapellaCache;

/// The backend to a graphite server.
#[derive(Debug)]
pub struct Graphite {
    addr: SocketAddr,
}

impl Graphite {
    /// Construct a new graphite instance with a given address.
    pub fn new<A: ToSocketAddrs>(addr: A) -> io::Result<Graphite> {
        Ok(Graphite {
            addr: addr.to_socket_addrs()?.next().unwrap(),
        })
    }
}

impl Backend for Graphite {
    // TODO: Clear the cache?
    fn purge_metrics(&self, cache: &mut CapellaCache) {
        let mut core = Core::new().unwrap();
        let handle = core.handle();

        let unix_time = Local::now().timestamp();
        let mut buffer = String::new();

        // TODO: Need to do this more efficiently.
        for (k, v) in cache.counters_iter() {
            write!(buffer, "{} {} {}\n", k, v, unix_time);
        }

        for (k, v) in cache.gauges_iter() {
            write!(buffer, "{} {} {}\n", k, v, unix_time);
        }
        println!("{}", buffer);

        let send = TcpStream::connect(&self.addr, &handle).and_then(|mut out| {
            // TODO: Is this safe to call? Is it async?
            out.write_all(buffer.as_bytes());
            Ok(())
        });
        drop(core.run(send));
    }
}
<|endoftext|>


<commit_before>use ::libc::{self, c_int, O_EXCL, O_RDWR, O_CREAT};
use ::libc::stat as stat_t;
use std::os::unix::ffi::OsStrExt;
use std::ffi::CString;
use std::io;
use std::os::unix::io::{RawFd, FromRawFd, AsRawFd};
use std::fs::{self, File, OpenOptions};
use std::path::Path;
use ::util::tmpname;

pub const O_CLOEXEC: libc::c_int = 0o2000000;

// Stolen from std.
pub fn cstr(path: &Path) -> io::Result<CString> {
    // TODO: Use OsStr::to_cstring (convert)
    CString::new(path.as_os_str().as_bytes()).map_err(|_|
        io::Error::new(io::ErrorKind::InvalidInput, "path contained a null"))
}

pub fn create_named(path: &Path) -> io::Result<File> {
    match unsafe {
        let path = try!(cstr(&path));
        libc::open(
            path.as_ptr() as *const libc::c_char,
            O_CLOEXEC | O_EXCL | O_RDWR | O_CREAT,
            0o600)
    } {
        -1 => Err(io::Error::last_os_error()),
        fd => Ok(unsafe { FromRawFd::from_raw_fd(fd) }),
    }
}

#[cfg(target_os = "linux")]
pub fn create(dir: &Path) -> io::Result<File> {
    const O_TMPFILE: libc::c_int = 0o20200000;
    match unsafe {
        let path = try!(cstr(dir));
        libc::open(
            path.as_ptr() as *const libc::c_char,
            O_CLOEXEC | O_EXCL | O_TMPFILE | O_RDWR,
            0o600)
    } {
        -1 => create_unix(dir),
        fd => Ok(unsafe { FromRawFd::from_raw_fd(fd) }),
    }
}

#[cfg(not(target_os = "linux"))]
pub fn create(dir: &Path) -> io::Result<File> {
    create_unix(dir)
}

fn create_unix(dir: &Path) -> io::Result<File> {
    for _ in 0..::NUM_RETRIES {
        let tmp_path = dir.join(&tmpname());
        return match create_named(&tmp_path) {
            Ok(file) => {
                // I should probably tell the user this failed but the temporary file creation
                // didn't really fail...
                let _ = fs::remove_file(tmp_path);
                Ok(file)
            },
            Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => continue,
            Err(e) => Err(e),
        }
    }
    Err(io::Error::new(io::ErrorKind::AlreadyExists,
                       "too many temporary directories already exist"))
}

unsafe fn stat(fd: RawFd) -> io::Result<stat_t> {
    let mut meta: stat_t = ::std::mem::zeroed();
    if libc::fstat(fd, &mut meta as *mut stat_t) != 0 {
        Err(io::Error::last_os_error())
    } else {
        Ok(meta)
    }
}

// Helper for ensuring that the temporary file gets deleted.
struct DeleteGuard<'a>(&'a Path);

impl<'a> Drop for DeleteGuard<'a> {
    fn drop(&mut self) {
        let _ = fs::remove_file(self.0);
    }
}

// One can do this on linux using proc but that doesn't play well with sandboxing...
pub fn create_shared(dir: &Path, count: usize) -> io::Result<Vec<File>> {
    let mut opts = OpenOptions::new();
    opts.read(true).write(true).create(false);

    if count == 0 {
        return Ok(vec![]);
    }
    'outer: for _ in 0..::NUM_RETRIES {
        let tmp_path = dir.join(&tmpname());
        return match unsafe {
            let tmp_path = try!(cstr(&tmp_path));
            libc::open(
                tmp_path.as_ptr() as *const libc::c_char,
                O_CLOEXEC | O_EXCL | O_RDWR | O_CREAT,
                0o600)
        } {
            -1 => {
                let err = io::Error::last_os_error();
                if err.kind() == io::ErrorKind::AlreadyExists {
                    continue;
                } else {
                    Err(err)
                }
            },
            fd => unsafe {
                let first = FromRawFd::from_raw_fd(fd);
                let _dg = DeleteGuard(&tmp_path);

                let target_meta = try!(stat(fd));
                let mut files: Vec<File> = try!((1..count).map(|_| opts.open(&tmp_path)).collect());
                for file in &files {
                    let meta = try!(stat(file.as_raw_fd()));
                    if meta.st_dev != target_meta.st_dev ||
                       meta.st_ino != target_meta.st_ino ||
                       // Even if the device information get's reused, the owner should actually be
                       // sufficient.
                       meta.st_uid != target_meta.st_uid ||
                       meta.st_gid != target_meta.st_gid {

                        // Error? Panic? If we hit this, we're likely under attack (or a hardware
                        // glitch/reconfiguration?.
                        continue 'outer;
                    }

                }
                files.push(first);
                Ok(files)
            },
        }
    }
    Err(io::Error::new(io::ErrorKind::AlreadyExists,
                       "too many temporary directories already exist"))
}

pub fn persist(old_path: &Path, new_path: &Path) -> io::Result<()> {
    fs::rename(old_path, new_path)
}
<commit_msg>Use libc O_CLOEXEC<commit_after>use ::libc::{self, c_int, O_EXCL, O_RDWR, O_CREAT, O_CLOEXEC};
use ::libc::stat as stat_t;
use std::os::unix::ffi::OsStrExt;
use std::ffi::CString;
use std::io;
use std::os::unix::io::{RawFd, FromRawFd, AsRawFd};
use std::fs::{self, File, OpenOptions};
use std::path::Path;
use ::util::tmpname;

// Stolen from std.
pub fn cstr(path: &Path) -> io::Result<CString> {
    // TODO: Use OsStr::to_cstring (convert)
    CString::new(path.as_os_str().as_bytes()).map_err(|_|
        io::Error::new(io::ErrorKind::InvalidInput, "path contained a null"))
}

pub fn create_named(path: &Path) -> io::Result<File> {
    match unsafe {
        let path = try!(cstr(&path));
        libc::open(
            path.as_ptr() as *const libc::c_char,
            O_CLOEXEC | O_EXCL | O_RDWR | O_CREAT,
            0o600)
    } {
        -1 => Err(io::Error::last_os_error()),
        fd => Ok(unsafe { FromRawFd::from_raw_fd(fd) }),
    }
}

#[cfg(target_os = "linux")]
pub fn create(dir: &Path) -> io::Result<File> {
    const O_TMPFILE: libc::c_int = 0o20200000;
    match unsafe {
        let path = try!(cstr(dir));
        libc::open(
            path.as_ptr() as *const libc::c_char,
            O_CLOEXEC | O_EXCL | O_TMPFILE | O_RDWR,
            0o600)
    } {
        -1 => create_unix(dir),
        fd => Ok(unsafe { FromRawFd::from_raw_fd(fd) }),
    }
}

#[cfg(not(target_os = "linux"))]
pub fn create(dir: &Path) -> io::Result<File> {
    create_unix(dir)
}

fn create_unix(dir: &Path) -> io::Result<File> {
    for _ in 0..::NUM_RETRIES {
        let tmp_path = dir.join(&tmpname());
        return match create_named(&tmp_path) {
            Ok(file) => {
                // I should probably tell the user this failed but the temporary file creation
                // didn't really fail...
                let _ = fs::remove_file(tmp_path);
                Ok(file)
            },
            Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => continue,
            Err(e) => Err(e),
        }
    }
    Err(io::Error::new(io::ErrorKind::AlreadyExists,
                       "too many temporary directories already exist"))
}

unsafe fn stat(fd: RawFd) -> io::Result<stat_t> {
    let mut meta: stat_t = ::std::mem::zeroed();
    if libc::fstat(fd, &mut meta as *mut stat_t) != 0 {
        Err(io::Error::last_os_error())
    } else {
        Ok(meta)
    }
}

// Helper for ensuring that the temporary file gets deleted.
struct DeleteGuard<'a>(&'a Path);

impl<'a> Drop for DeleteGuard<'a> {
    fn drop(&mut self) {
        let _ = fs::remove_file(self.0);
    }
}

// One can do this on linux using proc but that doesn't play well with sandboxing...
pub fn create_shared(dir: &Path, count: usize) -> io::Result<Vec<File>> {
    let mut opts = OpenOptions::new();
    opts.read(true).write(true).create(false);

    if count == 0 {
        return Ok(vec![]);
    }
    'outer: for _ in 0..::NUM_RETRIES {
        let tmp_path = dir.join(&tmpname());
        return match unsafe {
            let tmp_path = try!(cstr(&tmp_path));
            libc::open(
                tmp_path.as_ptr() as *const libc::c_char,
                O_CLOEXEC | O_EXCL | O_RDWR | O_CREAT,
                0o600)
        } {
            -1 => {
                let err = io::Error::last_os_error();
                if err.kind() == io::ErrorKind::AlreadyExists {
                    continue;
                } else {
                    Err(err)
                }
            },
            fd => unsafe {
                let first = FromRawFd::from_raw_fd(fd);
                let _dg = DeleteGuard(&tmp_path);

                let target_meta = try!(stat(fd));
                let mut files: Vec<File> = try!((1..count).map(|_| opts.open(&tmp_path)).collect());
                for file in &files {
                    let meta = try!(stat(file.as_raw_fd()));
                    if meta.st_dev != target_meta.st_dev ||
                       meta.st_ino != target_meta.st_ino ||
                       // Even if the device information get's reused, the owner should actually be
                       // sufficient.
                       meta.st_uid != target_meta.st_uid ||
                       meta.st_gid != target_meta.st_gid {

                        // Error? Panic? If we hit this, we're likely under attack (or a hardware
                        // glitch/reconfiguration?.
                        continue 'outer;
                    }

                }
                files.push(first);
                Ok(files)
            },
        }
    }
    Err(io::Error::new(io::ErrorKind::AlreadyExists,
                       "too many temporary directories already exist"))
}

pub fn persist(old_path: &Path, new_path: &Path) -> io::Result<()> {
    fs::rename(old_path, new_path)
}
<|endoftext|>


<commit_before>extern crate mio;
use getopts::{Options,Matches};
use std::old_io;

use self::mio::*;
use self::mio::net::tcp::*;
use self::mio::buf::{ByteBuf};

use std::net::{SocketAddr,ToSocketAddrs};
use std::str::FromStr;

use std::thread;

const SERVER: Token = Token(1);
const CLIENT: Token = Token(2);

struct ServerHandler {
    conn: Option<NonBlock<TcpStream>>,
    sock: NonBlock<TcpListener>
}

impl ServerHandler {
    fn accept(&mut self, event_loop: &mut EventLoop<ServerHandler>) {
        match self.conn {
            Some(_) => {
                // already have connection, do nothing
            },
            None => {
                let conn = self.sock.accept();
                let stream = conn.unwrap().unwrap();
                self.conn = Some(stream);
                match self.conn {
                    Some(ref c) => {
                        event_loop.register(c, CLIENT);
                    },
                    None => {
                        panic!("no ref??".to_string());
                    }
                }
            }
        }
    }
}

impl Handler for ServerHandler {
    type Timeout = usize;
    type Message = String;

    fn readable(&mut self, event_loop: &mut EventLoop<ServerHandler>, token: Token, hint: ReadHint) {
        match token {
            SERVER => {
                // Call `accept` on our `tcp_handler`.
                self.accept(event_loop);
            },
            CLIENT => {
                if hint.is_hup() {
                    event_loop.shutdown();
                }
                let mut read_buf = ByteBuf::mut_with_capacity(2048);
                match self.conn {
                    Some(ref mut c) => {
                        match c.read(&mut read_buf) {
                            Ok(None) => {
                                panic!("Got read event, but nothing to read??");
                            },
                            Ok(Some(n)) => {
                                // `_` would be the number of bytes read.
                                // `flip` will return a `ByteBuf` on which we can call
                                // `read_slice` to get the data available to be read.
                                // See http://carllerche.github.io/bytes/bytes/struct.ByteBuf.html
                                let mut buf = read_buf.flip();
                                let mut sl = [0; 2048];
                                buf.read_slice(&mut sl);
                                // Assuming what was written was encoded as UTF8, print what
                                // was read to STDOUT.
                                print!("{}", String::from_utf8(sl.to_vec()).unwrap());
                            }
                            Err(e) => {
                                // Probably because connection could not be established.
                                event_loop.shutdown();
                                panic!(e.to_string());
                            }
                        }
                    },
                    None => {
                        panic!("can't read".to_string());
                    }
                }
            },
            _ => {
                panic!("unexpected token".to_string());
            }
        }
    }

    fn notify(&mut self, event_loop: &mut EventLoop<ServerHandler>, msg: String) {
        match self.conn {
            Some(ref mut c) => {
                c.write_slice(msg.as_bytes()).unwrap();
            },
            None => {
                panic!("??".to_string());
            }
        }
    }

    fn timeout(&mut self, event_loop: &mut EventLoop<ServerHandler>, timeout: usize) {
        println!("timeout");
    }

    fn interrupted(&mut self, event_loop: &mut EventLoop<ServerHandler>) {
        println!("interupt");
    }

}

pub fn nc_listen(matches: &Matches) {
    // append port to localhost IP address
    let mut s = String::from_str("127.0.0.1:");
    s.push_str(matches.free[0].as_slice());
    let addr: SocketAddr = FromStr::from_str(s.as_slice()).unwrap();

    let listener = v4().unwrap();
    listener.bind(&addr).ok().expect("Failed to bind to port");
    let listener = listener.listen(1).ok().expect("Failed to listen on port");

    let mut event_loop = EventLoop::new().unwrap();
    event_loop.register_opt(&listener, SERVER, Interest::readable() | Interest::hup() | Interest::error(), PollOpt::level()).unwrap();

    let mut server_handler = ServerHandler {
        conn: None,
        sock: listener
    };

    let sender = event_loop.channel();
    thread::spawn(move || {
        readwrite_chan(&sender);
    });

    let _ = event_loop.run(&mut server_handler);
}

fn readwrite_chan(channel: &EventLoopSender<String>) {
    let mut stdin_reader = old_io::stdin();
    let mut read_buf = [0; 4096];
    loop {
        match stdin_reader.read(&mut read_buf) {
            Ok(n) => {
                let read = read_buf.slice_to(n);
                let byte_vec: Vec<u8> = read.to_vec();
                let message = String::from_utf8(byte_vec).unwrap();
                channel.send(message).unwrap();
            },
            Err(f) => {
                panic!(f.to_string());
            }
        }
    }
}
<commit_msg>removing unused server timeout/interrupt handlers<commit_after>extern crate mio;
use getopts::{Options,Matches};
use std::old_io;

use self::mio::*;
use self::mio::net::tcp::*;
use self::mio::buf::{ByteBuf};

use std::net::{SocketAddr,ToSocketAddrs};
use std::str::FromStr;

use std::thread;

const SERVER: Token = Token(1);
const CLIENT: Token = Token(2);

struct ServerHandler {
    conn: Option<NonBlock<TcpStream>>,
    sock: NonBlock<TcpListener>
}

impl ServerHandler {
    fn accept(&mut self, event_loop: &mut EventLoop<ServerHandler>) {
        match self.conn {
            Some(_) => {
                // already have connection, do nothing
            },
            None => {
                let conn = self.sock.accept();
                let stream = conn.unwrap().unwrap();
                self.conn = Some(stream);
                match self.conn {
                    Some(ref c) => {
                        event_loop.register(c, CLIENT);
                    },
                    None => {
                        panic!("no ref??".to_string());
                    }
                }
            }
        }
    }
}

impl Handler for ServerHandler {
    type Timeout = usize;
    type Message = String;

    fn readable(&mut self, event_loop: &mut EventLoop<ServerHandler>, token: Token, hint: ReadHint) {
        match token {
            SERVER => {
                // Call `accept` on our `tcp_handler`.
                self.accept(event_loop);
            },
            CLIENT => {
                if hint.is_hup() {
                    event_loop.shutdown();
                }
                let mut read_buf = ByteBuf::mut_with_capacity(2048);
                match self.conn {
                    Some(ref mut c) => {
                        match c.read(&mut read_buf) {
                            Ok(None) => {
                                panic!("Got read event, but nothing to read??");
                            },
                            Ok(Some(n)) => {
                                // `_` would be the number of bytes read.
                                // `flip` will return a `ByteBuf` on which we can call
                                // `read_slice` to get the data available to be read.
                                // See http://carllerche.github.io/bytes/bytes/struct.ByteBuf.html
                                let mut buf = read_buf.flip();
                                let mut sl = [0; 2048];
                                buf.read_slice(&mut sl);
                                // Assuming what was written was encoded as UTF8, print what
                                // was read to STDOUT.
                                print!("{}", String::from_utf8(sl.to_vec()).unwrap());
                            }
                            Err(e) => {
                                // Probably because connection could not be established.
                                event_loop.shutdown();
                                panic!(e.to_string());
                            }
                        }
                    },
                    None => {
                        panic!("can't read".to_string());
                    }
                }
            },
            _ => {
                panic!("unexpected token".to_string());
            }
        }
    }

    fn notify(&mut self, event_loop: &mut EventLoop<ServerHandler>, msg: String) {
        match self.conn {
            Some(ref mut c) => {
                c.write_slice(msg.as_bytes()).unwrap();
            },
            None => {
                panic!("??".to_string());
            }
        }
    }
}

pub fn nc_listen(matches: &Matches) {
    // append port to localhost IP address
    let mut s = String::from_str("127.0.0.1:");
    s.push_str(matches.free[0].as_slice());
    let addr: SocketAddr = FromStr::from_str(s.as_slice()).unwrap();

    let listener = v4().unwrap();
    listener.bind(&addr).ok().expect("Failed to bind to port");
    let listener = listener.listen(1).ok().expect("Failed to listen on port");

    let mut event_loop = EventLoop::new().unwrap();
    event_loop.register_opt(&listener, SERVER, Interest::readable() | Interest::hup() | Interest::error(), PollOpt::level()).unwrap();

    let mut server_handler = ServerHandler {
        conn: None,
        sock: listener
    };

    let sender = event_loop.channel();
    thread::spawn(move || {
        readwrite_chan(&sender);
    });

    let _ = event_loop.run(&mut server_handler);
}

fn readwrite_chan(channel: &EventLoopSender<String>) {
    let mut stdin_reader = old_io::stdin();
    let mut read_buf = [0; 4096];
    loop {
        match stdin_reader.read(&mut read_buf) {
            Ok(n) => {
                let read = read_buf.slice_to(n);
                let byte_vec: Vec<u8> = read.to_vec();
                let message = String::from_utf8(byte_vec).unwrap();
                channel.send(message).unwrap();
            },
            Err(f) => {
                panic!(f.to_string());
            }
        }
    }
}
<|endoftext|>


<commit_before>//! This module provides tools for generating meshes for simple shapes like
//! cubes and spheres. It uses an iterator-based interface that begins with a
//! unit shape and manipulates its constituent primitives like points, lines,
//! and polygons. All shapes provide position information and some can
//! additionally generate index, texture, and conjoint point information as
//! well.
//!
//! # Examples
//!
//! Generating position and index data for a scaled sphere mesh:
//!
//! ```
//! use bismuth::mesh::{ConjointPoints, IndexPolygons, Points, Triangulate};
//! use bismuth::mesh::sphere::UVSphere;
//!
//! let sphere = UVSphere::with_unit_radius(16, 16);
//! let positions: Vec<_> = sphere.conjoint_points().map(|point| point * 10.0).collect();
//! let indeces: Vec<_> = sphere.index_polygons().triangulate().points().collect();
//! ```

pub mod cube;
mod decompose;
mod generate;
mod primitive;
pub mod sphere;

pub use self::decompose::{Lines, Points, Subdivide, Tetrahedrons, Triangulate};
pub use self::generate::{ConjointPoints, IndexPolygons, Polygons, TexturePolygons};
pub use self::primitive::{Line, MapPoints, Polygon, Rotate, Triangle, Quad};

#[cfg(test)]
mod tests {
    use super::*;
}
<commit_msg>Provide comments in `mesh` module documentation code.<commit_after>//! This module provides tools for generating meshes for simple shapes like
//! cubes and spheres.
//!
//! It uses an iterator-based interface that begins with a unit shape and
//! manipulates its constituent primitives like points, lines, and polygons.
//! All shapes provide position information and some can additionally generate
//! index, texture, and conjoint point information as well.
//!
//! # Examples
//!
//! Generating position and index data for a scaled sphere mesh:
//!
//! ```
//! use bismuth::mesh::{ConjointPoints, IndexPolygons, Points, Triangulate};
//! use bismuth::mesh::sphere::UVSphere;
//!
//! let sphere = UVSphere::with_unit_radius(16, 16);
//! let positions: Vec<_> = sphere
//!     .conjoint_points() // Get the unique set of points.
//!     .map(|point| point * 10.0) // Scale the points by 10.
//!     .collect();
//! let indeces: Vec<_> = sphere
//!     .index_polygons() // Get indeces into the unique set of points as polygons.
//!     .triangulate() // Decompose the polygons into triangles.
//!     .points() // Decompose the triangles into points (indeces).
//!     .collect();
//! ```

pub mod cube;
mod decompose;
mod generate;
mod primitive;
pub mod sphere;

pub use self::decompose::{Lines, Points, Subdivide, Tetrahedrons, Triangulate};
pub use self::generate::{ConjointPoints, IndexPolygons, Polygons, TexturePolygons};
pub use self::primitive::{Line, MapPoints, Polygon, Rotate, Triangle, Quad};

#[cfg(test)]
mod tests {
    use super::*;
}
<|endoftext|>