<commit_before>use encoding_rs::Encoding;
use html5ever::rcdom::RcDom;
use reqwest::blocking::Client;
use reqwest::header::{HeaderMap, HeaderValue, USER_AGENT};
use std::collections::HashMap;
use std::fs;
use std::io::{self, prelude::*, Error, Write};
use std::path::Path;
use std::process;
use std::time::Duration;
use url::Url;

use monolith::html::{
    add_favicon, create_metadata_tag, get_base_url, get_charset, has_favicon, html_to_dom,
    serialize_document, set_base_url, set_charset, walk_and_embed_assets,
};
use monolith::opts::Options;
use monolith::url::{create_data_url, resolve_url};
use monolith::utils::retrieve_asset;

enum Output {
    Stdout(io::Stdout),
    File(fs::File),
}

impl Output {
    fn new(file_path: &str) -> Result<Output, Error> {
        if file_path.is_empty() || file_path.eq("-") {
            Ok(Output::Stdout(io::stdout()))
        } else {
            Ok(Output::File(fs::File::create(file_path)?))
        }
    }

    fn write(&mut self, bytes: &Vec<u8>) -> Result<(), Error> {
        match self {
            Output::Stdout(stdout) => {
                stdout.write_all(bytes)?;
                // Ensure newline at end of output
                if bytes.last() != Some(&b"\n"[0]) {
                    stdout.write(b"\n")?;
                }
                stdout.flush()
            }
            Output::File(file) => {
                file.write_all(bytes)?;
                // Ensure newline at end of output
                if bytes.last() != Some(&b"\n"[0]) {
                    file.write(b"\n")?;
                }
                file.flush()
            }
        }
    }
}

pub fn read_stdin() -> Vec<u8> {
    let mut buffer: Vec<u8> = vec![];

    match io::stdin().lock().read_to_end(&mut buffer) {
        Ok(_) => buffer,
        Err(_) => buffer,
    }
}

fn main() {
    let options = Options::from_args();
    let mut target: String = options.target.clone();

    // Check if target was provided
    if target.len() == 0 {
        if !options.silent {
            eprintln!("No target specified");
        }
        process::exit(1);
    }

    // Check if custom charset is valid
    if let Some(custom_charset) = options.charset.clone() {
        if !Encoding::for_label_no_replacement(custom_charset.as_bytes()).is_some() {
            eprintln!("Unknown encoding: {}", &custom_charset);
            process::exit(1);
        }
    }

    let target_url: Url;
    let mut use_stdin: bool = false;

    // Determine exact target URL
    if target.clone() == "-" {
        // Read from pipe (stdin)
        use_stdin = true;
        // Set default target URL to an empty data URL; the user can set it via --base-url
        target_url = Url::parse("data:text/html,").unwrap();
    } else {
        match Url::parse(&target.clone()) {
            Ok(parsed_url) => {
                if parsed_url.scheme() == "data"
                    || parsed_url.scheme() == "file"
                    || (parsed_url.scheme() == "http" || parsed_url.scheme() == "https")
                {
                    target_url = parsed_url;
                } else {
                    if !options.silent {
                        eprintln!("Unsupported target URL type: {}", &parsed_url.scheme());
                    }
                    process::exit(1);
                }
            }
            Err(_err) => {
                // Failed to parse given base URL (perhaps it's a filesystem path?)
                let path: &Path = Path::new(&target);

                if path.exists() {
                    if path.is_file() {
                        match Url::from_file_path(fs::canonicalize(&path).unwrap()) {
                            Ok(file_url) => {
                                target_url = file_url;
                            }
                            Err(_err) => {
                                if !options.silent {
                                    eprintln!(
                                        "Could not generate file URL out of given path: {}",
                                        "err"
                                    );
                                }
                                process::exit(1);
                            }
                        }
                    } else {
                        if !options.silent {
                            eprintln!("Local target is not a file: {}", &options.target);
                        }
                        process::exit(1);
                    }
                } else {
                    // Last chance, now we do what browsers do:
                    // prepend "http://" and hope it points to a website
                    target.insert_str(0, "http://");
                    target_url = Url::parse(&target).unwrap();
                }
            }
        }
    }

    // Initialize client
    let mut cache = HashMap::new();
    let mut header_map = HeaderMap::new();
    if let Some(user_agent) = &options.user_agent {
        header_map.insert(
            USER_AGENT,
            HeaderValue::from_str(&user_agent).expect("Invalid User-Agent header specified"),
        );
    }
    let client = if options.timeout > 0 {
        Client::builder().timeout(Duration::from_secs(options.timeout))
    } else {
        // No timeout is default
        Client::builder()
    }
    .danger_accept_invalid_certs(options.insecure)
    .default_headers(header_map)
    .build()
    .expect("Failed to initialize HTTP client");

    // At first we assume that base URL is the same as target URL
    let mut base_url: Url = target_url.clone();

    let data: Vec<u8>;
    let mut document_encoding: String = "".to_string();
    let mut dom: RcDom;

    // Retrieve target document
    if use_stdin {
        data = read_stdin();
    } else if target_url.scheme() == "file"
        || (target_url.scheme() == "http" || target_url.scheme() == "https")
        || target_url.scheme() == "data"
    {
        match retrieve_asset(&mut cache, &client, &target_url, &target_url, &options, 0) {
            Ok((retrieved_data, final_url, media_type, charset)) => {
                // Make sure the media type is text/html
                if !media_type.eq_ignore_ascii_case("text/html") {
                    if !options.silent {
                        eprintln!("Unsupported document media type");
                    }
                    process::exit(1);
                }

                if options
                    .base_url
                    .clone()
                    .unwrap_or("".to_string())
                    .is_empty()
                {
                    base_url = final_url;
                }

                data = retrieved_data;
                document_encoding = charset;
            }
            Err(_) => {
                if !options.silent {
                    eprintln!("Could not retrieve target document");
                }
                process::exit(1);
            }
        }
    } else {
        process::exit(1);
    }

    // Initial parse
    dom = html_to_dom(&data, document_encoding.clone());

    // TODO: investigate if charset from filesystem/data URL/HTTP headers
    //       has say over what's specified in HTML

    // Attempt to determine document's charset
    if let Some(html_charset) = get_charset(&dom.document) {
        if !html_charset.is_empty() {
            // Check if the charset specified inside HTML is valid
            if let Some(encoding) = Encoding::for_label_no_replacement(html_charset.as_bytes()) {
                document_encoding = html_charset;
                dom = html_to_dom(&data, encoding.name().to_string());
            }
        }
    }

    // Use custom base URL if specified, read and use what's in the DOM otherwise
    let custom_base_url: String = options.base_url.clone().unwrap_or("".to_string());
    if custom_base_url.is_empty() {
        // No custom base URL is specified
        // Try to see if document has BASE element
        if let Some(existing_base_url) = get_base_url(&dom.document) {
            base_url = resolve_url(&target_url, &existing_base_url);
        }
    } else {
        // Custom base URL provided
        match Url::parse(&custom_base_url) {
            Ok(parsed_url) => {
                if parsed_url.scheme() == "file" {
                    // File base URLs can only work with
                    // documents saved from filesystem
                    if target_url.scheme() == "file" {
                        base_url = parsed_url;
                    }
                } else {
                    base_url = parsed_url;
                }
            }
            Err(_) => {
                // Failed to parse given base URL, perhaps it's a filesystem path?
                if target_url.scheme() == "file" {
                    // Relative paths could work for documents saved from filesystem
                    let path: &Path = Path::new(&custom_base_url);
                    if path.exists() {
                        match Url::from_file_path(fs::canonicalize(&path).unwrap()) {
                            Ok(file_url) => {
                                base_url = file_url;
                            }
                            Err(_) => {
                                if !options.silent {
                                    eprintln!(
                                        "Could not map given path to base URL: {}",
                                        custom_base_url
                                    );
                                }
                                process::exit(1);
                            }
                        }
                    }
                }
            }
        }
    }

    // Traverse through the document and embed remote assets
    walk_and_embed_assets(&mut cache, &client, &base_url, &dom.document, &options, 0);

    // Update or add new BASE element to reroute network requests and hash-links
    if let Some(new_base_url) = options.base_url.clone() {
        dom = set_base_url(&dom.document, new_base_url);
    }

    // Request and embed /favicon.ico (unless it's already linked in the document)
    if !options.no_images
        && (target_url.scheme() == "http" || target_url.scheme() == "https")
        && !has_favicon(&dom.document)
    {
        let favicon_ico_url: Url = resolve_url(&base_url, "/favicon.ico");

        match retrieve_asset(
            &mut cache,
            &client,
            &target_url,
            &favicon_ico_url,
            &options,
            0,
        ) {
            Ok((data, final_url, media_type, charset)) => {
                let favicon_data_url: Url =
                    create_data_url(&media_type, &charset, &data, &final_url);
                dom = add_favicon(&dom.document, favicon_data_url.to_string());
            }
            Err(_) => {
                // Failed to retrieve /favicon.ico
            }
        }
    }

    // Save using specified charset, if given
    if let Some(custom_charset) = options.charset.clone() {
        document_encoding = custom_charset;
        dom = set_charset(dom, document_encoding.clone());
    }

    // Serialize DOM tree
    let mut result: Vec<u8> = serialize_document(dom, document_encoding, &options);

    // Prepend metadata comment tag
    if !options.no_metadata {
        let mut metadata_comment: String = create_metadata_tag(&target_url);
        metadata_comment += "\n";
        result.splice(0..0, metadata_comment.as_bytes().to_vec());
    }

    // Define output
    let mut output = Output::new(&options.output).expect("Could not prepare output");

    // Write result into stdout or file
    output.write(&result).expect("Could not write HTML output");
}
<commit_msg>rewrite small part of the input argument handling<commit_after>use encoding_rs::Encoding;
use html5ever::rcdom::RcDom;
use reqwest::blocking::Client;
use reqwest::header::{HeaderMap, HeaderValue, USER_AGENT};
use std::collections::HashMap;
use std::fs;
use std::io::{self, prelude::*, Error, Write};
use std::path::Path;
use std::process;
use std::time::Duration;
use url::Url;

use monolith::html::{
    add_favicon, create_metadata_tag, get_base_url, get_charset, has_favicon, html_to_dom,
    serialize_document, set_base_url, set_charset, walk_and_embed_assets,
};
use monolith::opts::Options;
use monolith::url::{create_data_url, resolve_url};
use monolith::utils::retrieve_asset;

enum Output {
    Stdout(io::Stdout),
    File(fs::File),
}

impl Output {
    fn new(file_path: &str) -> Result<Output, Error> {
        if file_path.is_empty() || file_path.eq("-") {
            Ok(Output::Stdout(io::stdout()))
        } else {
            Ok(Output::File(fs::File::create(file_path)?))
        }
    }

    fn write(&mut self, bytes: &Vec<u8>) -> Result<(), Error> {
        match self {
            Output::Stdout(stdout) => {
                stdout.write_all(bytes)?;
                // Ensure newline at end of output
                if bytes.last() != Some(&b"\n"[0]) {
                    stdout.write(b"\n")?;
                }
                stdout.flush()
            }
            Output::File(file) => {
                file.write_all(bytes)?;
                // Ensure newline at end of output
                if bytes.last() != Some(&b"\n"[0]) {
                    file.write(b"\n")?;
                }
                file.flush()
            }
        }
    }
}

pub fn read_stdin() -> Vec<u8> {
    let mut buffer: Vec<u8> = vec![];

    match io::stdin().lock().read_to_end(&mut buffer) {
        Ok(_) => buffer,
        Err(_) => buffer,
    }
}

fn main() {
    let options = Options::from_args();

    // Check if target was provided
    if options.target.len() == 0 {
        if !options.silent {
            eprintln!("No target specified");
        }
        process::exit(1);
    }

    // Check if custom charset is valid
    if let Some(custom_charset) = options.charset.clone() {
        if !Encoding::for_label_no_replacement(custom_charset.as_bytes()).is_some() {
            eprintln!("Unknown encoding: {}", &custom_charset);
            process::exit(1);
        }
    }

    let mut use_stdin: bool = false;

    let target_url = match options.target.as_str() {
        "-" => {
            // Read from pipe (stdin)
            use_stdin = true;
            // Set default target URL to an empty data URL; the user can set it via --base-url
            Url::parse("data:text/html,").unwrap()
        }
        target => match Url::parse(&target) {
            Ok(url) => match url.scheme() {
                "data" | "file" | "http" | "https" => url,
                unsupported_scheme => {
                    if !options.silent {
                        eprintln!("Unsupported target URL type: {}", unsupported_scheme);
                    }
                    process::exit(1)
                }
            },
            Err(_) => {
                // Failed to parse given base URL (perhaps it's a filesystem path?)
                let path: &Path = Path::new(&target);
                match path.exists() {
                    true => match path.is_file() {
                        true => {
                            let canonical_path = fs::canonicalize(&path).unwrap();
                            match Url::from_file_path(canonical_path) {
                                Ok(url) => url,
                                Err(_) => {
                                    if !options.silent {
                                        eprintln!(
                                            "Could not generate file URL out of given path: {}",
                                            &target
                                        );
                                    }
                                    process::exit(1);
                                }
                            }
                        }
                        false => {
                            if !options.silent {
                                eprintln!("Local target is not a file: {}", &target);
                            }
                            process::exit(1);
                        }
                    },
                    false => {
                        // It is not a FS path, now we do what browsers do:
                        // prepend "http://" and hope it points to a website
                        Url::parse(&format!("https://{hopefully_url}", hopefully_url = &target))
                            .unwrap()
                    }
                }
            }
        },
    };

    // Initialize client
    let mut cache = HashMap::new();
    let mut header_map = HeaderMap::new();
    if let Some(user_agent) = &options.user_agent {
        header_map.insert(
            USER_AGENT,
            HeaderValue::from_str(&user_agent).expect("Invalid User-Agent header specified"),
        );
    }
    let client = if options.timeout > 0 {
        Client::builder().timeout(Duration::from_secs(options.timeout))
    } else {
        // No timeout is default
        Client::builder()
    }
    .danger_accept_invalid_certs(options.insecure)
    .default_headers(header_map)
    .build()
    .expect("Failed to initialize HTTP client");

    // At first we assume that base URL is the same as target URL
    let mut base_url: Url = target_url.clone();

    let data: Vec<u8>;
    let mut document_encoding: String = "".to_string();
    let mut dom: RcDom;

    // Retrieve target document
    if use_stdin {
        data = read_stdin();
    } else if target_url.scheme() == "file"
        || (target_url.scheme() == "http" || target_url.scheme() == "https")
        || target_url.scheme() == "data"
    {
        match retrieve_asset(&mut cache, &client, &target_url, &target_url, &options, 0) {
            Ok((retrieved_data, final_url, media_type, charset)) => {
                // Make sure the media type is text/html
                if !media_type.eq_ignore_ascii_case("text/html") {
                    if !options.silent {
                        eprintln!("Unsupported document media type");
                    }
                    process::exit(1);
                }

                if options
                    .base_url
                    .clone()
                    .unwrap_or("".to_string())
                    .is_empty()
                {
                    base_url = final_url;
                }

                data = retrieved_data;
                document_encoding = charset;
            }
            Err(_) => {
                if !options.silent {
                    eprintln!("Could not retrieve target document");
                }
                process::exit(1);
            }
        }
    } else {
        process::exit(1);
    }

    // Initial parse
    dom = html_to_dom(&data, document_encoding.clone());

    // TODO: investigate if charset from filesystem/data URL/HTTP headers
    //       has say over what's specified in HTML

    // Attempt to determine document's charset
    if let Some(html_charset) = get_charset(&dom.document) {
        if !html_charset.is_empty() {
            // Check if the charset specified inside HTML is valid
            if let Some(encoding) = Encoding::for_label_no_replacement(html_charset.as_bytes()) {
                document_encoding = html_charset;
                dom = html_to_dom(&data, encoding.name().to_string());
            }
        }
    }

    // Use custom base URL if specified, read and use what's in the DOM otherwise
    let custom_base_url: String = options.base_url.clone().unwrap_or("".to_string());
    if custom_base_url.is_empty() {
        // No custom base URL is specified
        // Try to see if document has BASE element
        if let Some(existing_base_url) = get_base_url(&dom.document) {
            base_url = resolve_url(&target_url, &existing_base_url);
        }
    } else {
        // Custom base URL provided
        match Url::parse(&custom_base_url) {
            Ok(parsed_url) => {
                if parsed_url.scheme() == "file" {
                    // File base URLs can only work with
                    // documents saved from filesystem
                    if target_url.scheme() == "file" {
                        base_url = parsed_url;
                    }
                } else {
                    base_url = parsed_url;
                }
            }
            Err(_) => {
                // Failed to parse given base URL, perhaps it's a filesystem path?
                if target_url.scheme() == "file" {
                    // Relative paths could work for documents saved from filesystem
                    let path: &Path = Path::new(&custom_base_url);
                    if path.exists() {
                        match Url::from_file_path(fs::canonicalize(&path).unwrap()) {
                            Ok(file_url) => {
                                base_url = file_url;
                            }
                            Err(_) => {
                                if !options.silent {
                                    eprintln!(
                                        "Could not map given path to base URL: {}",
                                        custom_base_url
                                    );
                                }
                                process::exit(1);
                            }
                        }
                    }
                }
            }
        }
    }

    // Traverse through the document and embed remote assets
    walk_and_embed_assets(&mut cache, &client, &base_url, &dom.document, &options, 0);

    // Update or add new BASE element to reroute network requests and hash-links
    if let Some(new_base_url) = options.base_url.clone() {
        dom = set_base_url(&dom.document, new_base_url);
    }

    // Request and embed /favicon.ico (unless it's already linked in the document)
    if !options.no_images
        && (target_url.scheme() == "http" || target_url.scheme() == "https")
        && !has_favicon(&dom.document)
    {
        let favicon_ico_url: Url = resolve_url(&base_url, "/favicon.ico");

        match retrieve_asset(
            &mut cache,
            &client,
            &target_url,
            &favicon_ico_url,
            &options,
            0,
        ) {
            Ok((data, final_url, media_type, charset)) => {
                let favicon_data_url: Url =
                    create_data_url(&media_type, &charset, &data, &final_url);
                dom = add_favicon(&dom.document, favicon_data_url.to_string());
            }
            Err(_) => {
                // Failed to retrieve /favicon.ico
            }
        }
    }

    // Save using specified charset, if given
    if let Some(custom_charset) = options.charset.clone() {
        document_encoding = custom_charset;
        dom = set_charset(dom, document_encoding.clone());
    }

    // Serialize DOM tree
    let mut result: Vec<u8> = serialize_document(dom, document_encoding, &options);

    // Prepend metadata comment tag
    if !options.no_metadata {
        let mut metadata_comment: String = create_metadata_tag(&target_url);
        metadata_comment += "\n";
        result.splice(0..0, metadata_comment.as_bytes().to_vec());
    }

    // Define output
    let mut output = Output::new(&options.output).expect("Could not prepare output");

    // Write result into stdout or file
    output.write(&result).expect("Could not write HTML output");
}
<|endoftext|>


<commit_before>//TODO(remove)
#![allow(dead_code)]

use std::io::{File, BufWriter, Reader};
use error::Ch8Error;

const RAM_SIZE: usize = 4096;
const PROGRAM_START: usize = 0x200;

mod error;

struct Vm {
    reg: [u8; 16],
    index: u16,
    pc: u16,
    sp: u8,
    stack: [u16; 256],
    ram: [u8; RAM_SIZE],

    timer: u8,
    tone: u8,

    screen: [u8; 64 * 32],
    keys: [u8; 16],
}

impl Vm {
    fn new() -> Vm {
        Vm {
            reg: [0; 16],
            index: 0,
            pc: PROGRAM_START as u16,
            sp: 0,
            stack: [0; 256],
            ram: [0; RAM_SIZE],

            timer: 0,
            tone: 0,

            screen: [0; 64 * 32],
            keys: [0; 16],
        }
    }

    fn load_rom(&mut self, reader: &mut Reader) -> Result<usize, Ch8Error> {
        let rom = try!(reader.read_to_end());
        if rom.len() > (RAM_SIZE - PROGRAM_START) {
           return Err(Ch8Error::Io("Rom was larger than available RAM", None))
        }
        let mut ram = BufWriter::new(&mut self.ram[PROGRAM_START..RAM_SIZE]);
        try!(ram.write(rom.as_slice()));
        return Ok(rom.len());
    }

    fn dump_ram(&self, writer: &mut Writer) {
        writer.write(&self.ram);
    }
}

struct Op {
    raw: u16
}

impl Op {
    fn addr(&self) -> u16 {
        self.raw & 0x0FFF
    }

    fn x(&self) -> u8 {
        ((self.raw & 0x0F00) >> 8) as u8
    }

    fn y(&self) -> u8 {
        ((self.raw & 0x00F0) >> 4) as u8
    }

    fn n(&self) -> u8 {
        ((self.raw & 0xF000) >> 12) as u8
    }

    fn kk(&self) -> u8 {
        (self.raw & 0x00FF) as u8
    }
}

fn main() {
    let mut vm = Vm::new();

    let mut rom_file = File::open(&Path::new("/Users/jakerr/Downloads/IBM Logo.ch8")).unwrap();
    match vm.load_rom(&mut rom_file) {
        Ok(size) => println!("Loaded rom size: {}", size),
        Err(e) => println!("Error loading rom: {}", e)
    }

    let mut dump_file = File::create(&Path::new("/Users/jakerr/tmp/dump.ch8ram")).unwrap();
    vm.dump_ram(&mut dump_file);

    for i in vm.ram.chunks(2) {
        match i {
            [0, 0] => continue,
            [h, l] => {
                let op = Op{raw:((h as u16) << 8) | l as u16};
                println!("raw: 0x{:X}", op.raw);
                println!("addr: 0x{:X}", op.addr());
                println!("x: 0x{:X}", op.x());
                println!("y: 0x{:X}", op.y());
                println!("n: 0x{:X}", op.n());
                println!("kk: 0x{:X}\n", op.kk());
            },
            _ => continue
        }
    }
}
<commit_msg>Start instruction parsing<commit_after>//TODO(remove)
#![allow(dead_code)]

use std::io::{File, BufWriter, Reader};
use error::Ch8Error;

const RAM_SIZE: usize = 4096;
const PROGRAM_START: usize = 0x200;

mod error;

struct Vm {
    reg: [u8; 16],
    index: u16,
    pc: u16,
    sp: u8,
    stack: [u16; 256],
    ram: [u8; RAM_SIZE],

    timer: u8,
    tone: u8,

    screen: [u8; 64 * 32],
    keys: [u8; 16],
}

impl Vm {
    fn new() -> Vm {
        Vm {
            reg: [0; 16],
            index: 0,
            pc: PROGRAM_START as u16,
            sp: 0,
            stack: [0; 256],
            ram: [0; RAM_SIZE],

            timer: 0,
            tone: 0,

            screen: [0; 64 * 32],
            keys: [0; 16],
        }
    }

    fn load_rom(&mut self, reader: &mut Reader) -> Result<usize, Ch8Error> {
        let rom = try!(reader.read_to_end());
        if rom.len() > (RAM_SIZE - PROGRAM_START) {
           return Err(Ch8Error::Io("Rom was larger than available RAM", None))
        }
        let mut ram = BufWriter::new(&mut self.ram[PROGRAM_START..RAM_SIZE]);
        try!(ram.write(rom.as_slice()));
        return Ok(rom.len());
    }

    fn dump_ram(&self, writer: &mut Writer) {
        writer.write(&self.ram).unwrap();
    }
}

struct Op {
    raw: u16
}

impl Op {
    fn addr(&self) -> Addr {
        self.raw & 0x0FFF
    }

    fn x(&self) -> Vx {
        ((self.raw & 0x0F00) >> 8) as u8
    }

    fn y(&self) -> Vy {
        ((self.raw & 0x00F0) >> 4) as u8
    }

    fn n_high(&self) -> Nibble {
        ((self.raw & 0xF000) >> 12) as u8
    }

    fn n_low(&self) -> Nibble {
        ((self.raw & 0xF000) >> 12) as u8
    }

    fn kk(&self) -> Byte {
        (self.raw & 0x00FF) as u8
    }
}

type Vx = u8;
type Vy = u8;
type Addr = u16;
type Byte = u8;
type Nibble = u8;

#[derive(Show)]
enum Instruction {
    Sys(Addr),              // 0nnn - SYS addr
    Clear,                  // 00E0 - CLS
    Return,                 // 00EE - RET
    Jump(Addr),             // 1nnn - JP addr
    Call(Addr),             // 2nnn - CALL addr
    SkipEqualK(Vx, Byte),   // 3xkk - SE Vx, byte
    SkipNotEqualK(Vx, Byte),// 4xkk - SNE Vx, byte
    SkipEqual(Vx, Vy),      // 5xy0 - SE Vx, Vy
    SetK(Vx, Byte),         // 6xkk - LD Vx, byte
    AddK(Vx, Byte),         // 7xkk - ADD Vx, byte
    Set(Vx, Vy),            // 8xy0 - LD Vx, Vy
    Or(Vx, Vy),             // 8xy1 - OR Vx, Vy
    And(Vx, Vy),            // 8xy2 - AND Vx, Vy
    XOr(Vx, Vy),            // 8xy3 - XOR Vx, Vy
    Add(Vx, Vy),            // 8xy4 - ADD Vx, Vy
    Sub(Vx, Vy),            // 8xy5 - SUB Vx, Vy
    ShiftRight(Vx, Vy),     // 8xy6 - SHR Vx {, Vy}
    SubInv(Vx, Vy),         // 8xy7 - SUBN Vx, Vy
    ShiftLeft(Vx, Vy),      // 8xyE - SHL Vx {, Vy}
    SkipNotEqual(Vx, Vy),   // 9xy0 - SNE Vx, Vy
    LoadI(Addr),            // Annn - LD I, addr
    LongJump(Addr),         // Bnnn - JP V0, addr
    Rand(Vx, Byte),         // Cxkk - RND Vx, byte
    Draw(Vx, Vy, Nibble),   // Dxyn - DRW Vx, Vy, nibble
    SkipPressed(Vx),        // Ex9E - SKP Vx
    SkipNotPressed(Vx),     // ExA1 - SKNP Vx
    GetTimer(Vx),           // Fx07 - LD Vx, DT
    WaitKey(Vx),            // Fx0A - LD Vx, K
    SetTimer(Vx),           // Fx15 - LD DT, Vx
    SetTone(Vx),            // Fx18 - LD ST, Vx
    AddToI(Vx),             // Fx1E - ADD I, Vx
    LoadHexGlyph(Vx),       // Fx29 - LD F, Vx
    StoreBCD(Vx),           // Fx33 - LD B, Vx
    StoreRegisters(Vx),     // Fx55 - LD [I], Vx
    LoadRegisters(Vx),      // Fx65 - LD Vx, [I]
    Unknown,
}

impl Instruction {
    fn from_op(op: &Op) -> Instruction {
        use Instruction::*;
        match op.n_high() {
            0x0 => {
                match op.kk() {
                    0xE0 => Clear,
                    0xEE => Return,
                    _ => Sys(op.addr())
                }
            },
            0x1 => Jump(op.addr()),
            0x2 => Call(op.addr()),
            0x3 => SkipEqualK(op.x(), op.kk()),
            0x4 => SkipNotEqualK(op.x(), op.kk()),
            _ => Unknown
        }
    }
}

fn main() {
    let mut vm = Vm::new();

    let mut rom_file = File::open(&Path::new("/Users/jakerr/Downloads/IBM Logo.ch8")).unwrap();
    match vm.load_rom(&mut rom_file) {
        Ok(size) => println!("Loaded rom size: {}", size),
        Err(e) => println!("Error loading rom: {}", e)
    }

    let mut dump_file = File::create(&Path::new("/Users/jakerr/tmp/dump.ch8ram")).unwrap();
    vm.dump_ram(&mut dump_file);

    for i in vm.ram.chunks(2) {
        match i {
            [0, 0] => continue,
            [h, l] => {
                let op = Op{raw:((h as u16) << 8) | l as u16};
                println!("raw: 0x{:X}", op.raw);
                println!("instruction: {:?}", Instruction::from_op(&op));
                println!("addr: 0x{:X}", op.addr());
                println!("x: 0x{:X}", op.x());
                println!("y: 0x{:X}", op.y());
                println!("n_high: 0x{:X}", op.n_high());
                println!("n_low: 0x{:X}", op.n_low());
                println!("kk: 0x{:X}\n", op.kk());
            },
            _ => continue
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2015-2016 William (B.J.) Snow Orvis
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate gfx_device_gl;
extern crate graphics;
extern crate opengl_graphics;
extern crate piston;
extern crate piston_window;

// must be before any local modules that use the macros
#[macro_use]
mod macros;

pub mod curves;
pub mod geometry;
pub mod lindenmayer;
pub mod turtle;
mod glwindow;

use std::env;

use curves::cesaro::CesaroFractal;
use curves::cesarotri::CesaroTriFractal;
use curves::dragon::DragonFractal;
use curves::kochcurve::KochCurve;
use curves::levyccurve::LevyCCurve;
use curves::terdragon::TerdragonFractal;
use lindenmayer::LindenmayerSystemTurtleProgram;
use turtle::TurtleProgram;

// TODO: Implement a proper "usage"
fn validate_args(args: &Vec<String>) {
    if (*args).len() <= 1 {
        panic!("You must provide a fractal type and an iteration number");
    }
    if (*args).len() <= 2 {
        panic!("You must provide an iteration number");
    }
}

fn main() {
    let args = env::args().collect::<Vec<String>>();
    validate_args(&args);

    let program_name: &str = args.get(1).unwrap();
    let iterations: u64 = args.get(2).unwrap().parse::<u64>().unwrap();

    let program: Box<TurtleProgram> = match program_name.as_ref() {
        "cesaro"     => Box::new(LindenmayerSystemTurtleProgram::new(CesaroFractal::new(iterations).unwrap())),
        "cesarotri"  => Box::new(LindenmayerSystemTurtleProgram::new(CesaroTriFractal::new(iterations).unwrap())),
        "dragon"     => Box::new(DragonFractal::new(iterations).unwrap()),
        "kochcurve"  => Box::new(LindenmayerSystemTurtleProgram::new(KochCurve::new(iterations).unwrap())),
        "levyccurve" => Box::new(LindenmayerSystemTurtleProgram::new(LevyCCurve::new(iterations).unwrap())),
        "terdragon"  => Box::new(LindenmayerSystemTurtleProgram::new(TerdragonFractal::new(iterations).unwrap())),
        _            => panic!("Unknown program type")
    };

    glwindow::run(&*program);
}
<commit_msg>Added a usage() to the program<commit_after>// Copyright (c) 2015-2016 William (B.J.) Snow Orvis
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate gfx_device_gl;
extern crate graphics;
extern crate opengl_graphics;
extern crate piston;
extern crate piston_window;

// must be before any local modules that use the macros
#[macro_use]
mod macros;

pub mod curves;
pub mod geometry;
pub mod lindenmayer;
pub mod turtle;
mod glwindow;

use std::env;

use curves::cesaro::CesaroFractal;
use curves::cesarotri::CesaroTriFractal;
use curves::dragon::DragonFractal;
use curves::kochcurve::KochCurve;
use curves::levyccurve::LevyCCurve;
use curves::terdragon::TerdragonFractal;
use lindenmayer::LindenmayerSystemTurtleProgram;
use turtle::TurtleProgram;

fn usage(program_name: &str) {
    println!("Usage: {} CURVE ARGS...", program_name);
    println!("");
    println!("CURVEs:");
    println!("    cesaro ITERATION     -- Césaro Square");
    println!("    cesarotri ITERATION  -- Césaro Triangle");
    println!("    dragon ITERATION     -- Dragon Curve");
    println!("    kochcurve ITERATION  -- Koch Snowflake");
    println!("    levyccurve ITERATION -- Lévy C Curve");
    println!("    terdragon ITERATION  -- Terdragon Curve");
    println!("");
    println!("ITERATION should be a a non-negative integer. Note that the complexity of the");
    println!("curves grows exponentially.");
    println!("");
}

fn validate_args(args: &Vec<String>) {
    if (*args).len() <= 1 {
        usage(&(*args)[0]);
        panic!("You must provide a fractal type and an iteration number");
    }
    if (*args).len() <= 2 {
        usage(&(*args)[0]);
        panic!("You must provide an iteration number");
    }
}

fn main() {
    let args = env::args().collect::<Vec<String>>();
    validate_args(&args);

    let curve_name: &str = args.get(1).unwrap();
    let iterations: u64 = args.get(2).unwrap().parse::<u64>().unwrap();

    let program: Box<TurtleProgram> = match curve_name.as_ref() {
        "cesaro"     => Box::new(LindenmayerSystemTurtleProgram::new(CesaroFractal::new(iterations).unwrap())),
        "cesarotri"  => Box::new(LindenmayerSystemTurtleProgram::new(CesaroTriFractal::new(iterations).unwrap())),
        "dragon"     => Box::new(DragonFractal::new(iterations).unwrap()),
        "kochcurve"  => Box::new(LindenmayerSystemTurtleProgram::new(KochCurve::new(iterations).unwrap())),
        "levyccurve" => Box::new(LindenmayerSystemTurtleProgram::new(LevyCCurve::new(iterations).unwrap())),
        "terdragon"  => Box::new(LindenmayerSystemTurtleProgram::new(TerdragonFractal::new(iterations).unwrap())),
        _            => panic!("Unknown program type")
    };

    glwindow::run(&*program);
}
<|endoftext|>


<commit_before>//
//	main.rs
//	SweetEngine
//
//	Copyright (c) 2015 Infinite
//	Licensed under the terms of the Apache License, v2
//

pub mod scripting;

use self::scripting::*;

fn main()
{
	execute_script("(lol -0.5)".to_string());
    println!("Hello, world!");
}
<commit_msg>TAB INDENTATION MASTER RACE<commit_after>//
//	main.rs
//	SweetEngine
//
//	Copyright (c) 2015 Infinite
//	Licensed under the terms of the Apache License, v2
//

pub mod scripting;

use self::scripting::*;

fn main()
{
	execute_script("(lol -0.5)".to_string());
	println!("Hello, world!");
}
<|endoftext|>


<commit_before>extern crate iron;
extern crate mote;
extern crate rgb;
extern crate router;
extern crate serde_json;
extern crate unicase;
extern crate url;

#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate maplit;

use std::io::Read;
use std::str::FromStr;
use std::sync::{Arc, Mutex};

use iron::headers::{AccessControlAllowHeaders, AccessControlAllowOrigin, ContentType};
use iron::middleware::Handler;
use iron::prelude::{IronResult, Request, Response};
use iron::prelude::*;
use iron::status;
use router::Router;
use unicase::UniCase;

mod google_actions;
use google_actions::{ActionRequest, ExecuteResponse, ExecuteResponseCommand,
                     ExecuteResponsePayload, Name, QueryResponse, QueryResponsePayload,
                     SyncResponse, SyncResponseDevice, SyncResponsePayload};

mod light;
use light::{Light, LightMode, LightStatus, LightType};

mod thermostat;
use thermostat::ThermostatMode;

mod scene;

mod device;
use device::Device;

mod oauth;

struct Hub {
    devices: Mutex<Vec<Device>>,
}

impl Handler for Hub {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        println!("hub handler");
        let mut body = String::new();
        req.body.read_to_string(&mut body).unwrap();
        let action_request: ActionRequest = serde_json::from_str(&body).unwrap();

        println!("action_request: {:?}", action_request);

        for input in action_request.inputs {
            if input.intent == "action.devices.SYNC" {
                let mut response = SyncResponse {
                    request_id: action_request.request_id.clone(),
                    payload: SyncResponsePayload {
                        agent_user_id: "1111".to_string(),
                        devices: vec![],
                    },
                };

                let ref devices = *self.devices.lock().unwrap();
                for device in devices {
                    match device {
                        &Device::Light(ref light) => {
                            response.payload.devices.push(SyncResponseDevice {
                                id: light.id.clone(),
                                type_: light.type_.to_string(),
                                traits: light
                                    .available_light_modes
                                    .iter()
                                    .map(LightMode::to_string)
                                    .collect(),
                                name: Name {
                                    default_name: vec![light.name.to_string()],
                                    name: Some(light.name.clone()),
                                    nicknames: vec![],
                                },
                                will_report_state: false,
                                device_info: None,
                                room_hint: None,
                                structure_hint: None,
                                attributes: None,
                            })
                        }
                        &Device::Thermostat(ref thermostat) => {
                            response.payload.devices.push(SyncResponseDevice {
                                id: thermostat.id.clone(),
                                type_: "".to_string(), // XXX
                                traits: vec![
                                    "action.devices.traits.TemperatureSetting".to_string(),
                                ],
                                name: Name {
                                    default_name: vec![thermostat.name.to_string()],
                                    name: Some(thermostat.name.clone()),
                                    nicknames: vec![],
                                },
                                // TODO: attributes.
                                will_report_state: false,
                                device_info: None,
                                room_hint: None,
                                structure_hint: None,
                                attributes: None,
                            })
                        }
                        &Device::Scene(ref scene) => {
                            response.payload.devices.push(SyncResponseDevice {
                                id: scene.id.clone(),
                                type_: "action.devices.types.SCENE".to_string(),
                                traits: vec!["action.devices.traits.Scene".to_string()],
                                name: Name {
                                    default_name: vec![scene.name.to_string()],
                                    name: Some(scene.name.clone()),
                                    nicknames: vec![],
                                },
                                will_report_state: false,
                                device_info: None,
                                room_hint: None,
                                structure_hint: None,
                                attributes: None,
                            })
                        }
                    }
                }

                let res = serde_json::to_string(&response).unwrap_or("".to_string());
                println!("action_response: {:?}", res);
                let mut rsp = Response::with((status::Ok, res));
                rsp.headers.set(ContentType::json());
                // For browser access.
                rsp.headers.set(AccessControlAllowOrigin::Any);
                return Ok(rsp);
            } else if input.intent == "action.devices.QUERY" {
                let mut response = QueryResponse {
                    request_id: action_request.request_id.clone(),
                    payload: QueryResponsePayload {
                        devices: btreemap!{},
                    },
                };

                let ref devices = *self.devices.lock().unwrap();
                if let Some(payload) = input.payload {
                    for request_device in payload.devices {
                        for device in devices {
                            match device {
                                &Device::Light(ref light) => if light.id == request_device.id {
                                    response
                                        .payload
                                        .devices
                                        .insert(light.id.clone(), light.status.clone().into());
                                },
                                &Device::Thermostat(ref thermostat) => {
                                    if thermostat.id == request_device.id {
                                        // TODO
                                    }
                                }
                                &Device::Scene(ref _scene) => {}
                            }
                        }
                    }
                }

                let res = serde_json::to_string(&response).unwrap_or("".to_string());
                println!("action_response: {:?}", res);
                let mut rsp = Response::with((status::Ok, res));
                rsp.headers.set(ContentType::json());
                // For browser access.
                rsp.headers.set(AccessControlAllowOrigin::Any);
                return Ok(rsp);
            } else if input.intent == "action.devices.EXECUTE" {
                let mut response = ExecuteResponse {
                    request_id: action_request.request_id.clone(),
                    payload: ExecuteResponsePayload {
                        error_code: None,
                        debug_string: None,
                        commands: vec![],
                    },
                };

                if let Some(ref p) = input.payload {
                    for command in &p.commands {
                        println!("command: {:?}", command);
                        for execution in &command.execution {
                            println!("execution: {:?}", execution);
                            for request_device in &command.devices {
                                println!("request_device: {:?}", request_device);
                                let ref mut devices = *self.devices.lock().unwrap();
                                for device in devices {
                                    match device {
                                        &mut Device::Light(ref mut light) => {
                                            if light.id == request_device.id {
                                                if let Some(s) = execution.params.on {
                                                    light.set_on(s);
                                                }
                                                if let Some(s) = execution.params.brightness {
                                                    light.set_brightness(s);
                                                }
                                                if let Some(ref s) = execution.params.color {
                                                    if let Some(s) = s.spectrum_rgb {
                                                        light.set_color(to_rgb(s));
                                                    }
                                                }
                                                response.payload.commands.push(
                                                    ExecuteResponseCommand {
                                                        ids: vec![light.id.clone()],
                                                        status: "SUCCESS".to_string(),
                                                        states: light.status.clone().into(),
                                                    },
                                                );
                                            }
                                        }
                                        &mut Device::Thermostat(ref mut thermostat) => {
                                            if thermostat.id == request_device.id {
                                                if let Some(s) =
                                                    execution.params.thermostat_temperature_setpoint
                                                {
                                                    thermostat.temperature_setpoint(s);
                                                }
                                                if let (Some(low), Some(high)) = (
                                                    execution
                                                        .params
                                                        .thermostat_temperature_setpoint_low,
                                                    execution
                                                        .params
                                                        .thermostat_temperature_setpoint_high,
                                                ) {
                                                    thermostat.temperature_set_range(low, high);
                                                }
                                                if let Some(ref mode) =
                                                    execution.params.thermostat_mode
                                                {
                                                    if let Ok(mode) = ThermostatMode::from_str(mode)
                                                    {
                                                        thermostat.thermostat_set_mode(mode);
                                                    }
                                                }
                                                response.payload.commands.push(
                                                    ExecuteResponseCommand {
                                                        ids: vec![thermostat.id.clone()],
                                                        status: "SUCCESS".to_string(),
                                                        states: thermostat.status.clone().into(),
                                                    },
                                                );
                                            }
                                        }
                                        &mut Device::Scene(ref mut _scene) => {}
                                    }
                                }
                            }
                        }
                    }
                }

                let res = serde_json::to_string(&response).unwrap_or("".to_string());
                println!("action_response: {:?}", res);
                let mut rsp = Response::with((status::Ok, res));
                rsp.headers.set(ContentType::json());
                // For browser access.
                rsp.headers.set(AccessControlAllowOrigin::Any);
                return Ok(rsp);
            }
        }

        let mut rsp = Response::with((status::Ok, "ACTION"));
        rsp.headers.set(ContentType::json());
        // For browser access.
        rsp.headers.set(AccessControlAllowOrigin::Any);
        Ok(rsp)
    }
}

fn to_rgb(c: u64) -> rgb::RGB8 {
    rgb::RGB8 {
        r: ((c & 0xFF0000) >> 16) as u8,
        g: ((c & 0x00FF00) >> 8) as u8,
        b: ((c & 0x0000FF) >> 0) as u8,
    }
}

fn main() {
    let mote = Arc::new(Mutex::new(mote::Mote::new("/dev/ttyACM0", true)));
    let hub = Hub {
        devices: Mutex::new(vec![
            Device::Light(Light {
                id: "11".to_string(),
                name: "TV lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 0,
                pixel_high: 16,
            }),
            Device::Light(Light {
                id: "22".to_string(),
                name: "TV lights 2".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 16,
                pixel_high: 32,
            }),
        ]),
    };
    let oauth = oauth::OAuth::new();
    let mut control = Router::new();
    control
        .get("/auth", oauth.auth, "auth")
        .post("/token", oauth.token, "token")
        .get("/login", oauth.login, "login")
        .post("/action", hub, "post action")
        .get("/action", get_action_handler, "get action")
        .options("/action", options_action_handler, "get action")
        .get("/", index_handler, "index");
    println!("Listening on port 1234");
    Iron::new(control).http("0.0.0.0:1234").unwrap();
}

fn index_handler(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, "index")))
}

fn get_action_handler(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, "get action")))
}

fn options_action_handler(_: &mut Request) -> IronResult<Response> {
    let mut rsp = Response::with((status::Ok, "options"));
    rsp.headers.set(AccessControlAllowOrigin::Any);
    rsp.headers.set(AccessControlAllowHeaders(
        vec![UniCase("Content-Type".to_string())],
    ));
    Ok(rsp)
}
<commit_msg>scenes<commit_after>extern crate iron;
extern crate mote;
extern crate rgb;
extern crate router;
extern crate serde_json;
extern crate unicase;
extern crate url;

#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate maplit;

use std::io::Read;
use std::str::FromStr;
use std::sync::{Arc, Mutex};

use iron::headers::{AccessControlAllowHeaders, AccessControlAllowOrigin, ContentType};
use iron::middleware::Handler;
use iron::prelude::{IronResult, Request, Response};
use iron::prelude::*;
use iron::status;
use router::Router;
use unicase::UniCase;

mod google_actions;
use google_actions::{ActionRequest, ExecuteResponse, ExecuteResponseCommand,
                     ExecuteResponsePayload, Name, QueryResponse, QueryResponsePayload,
                     SyncResponse, SyncResponseDevice, SyncResponsePayload};

mod light;
use light::{Light, LightMode, LightStatus, LightType};

mod thermostat;
use thermostat::ThermostatMode;

mod scene;
use scene::Scene;

mod device;
use device::Device;

mod oauth;

struct Hub {
    devices: Mutex<Vec<Device>>,
}

impl Handler for Hub {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        println!("hub handler");
        let mut body = String::new();
        req.body.read_to_string(&mut body).unwrap();
        let action_request: ActionRequest = serde_json::from_str(&body).unwrap();

        println!("action_request: {:?}", action_request);

        for input in action_request.inputs {
            if input.intent == "action.devices.SYNC" {
                let mut response = SyncResponse {
                    request_id: action_request.request_id.clone(),
                    payload: SyncResponsePayload {
                        agent_user_id: "1111".to_string(),
                        devices: vec![],
                    },
                };

                let ref devices = *self.devices.lock().unwrap();
                for device in devices {
                    match device {
                        &Device::Light(ref light) => {
                            response.payload.devices.push(SyncResponseDevice {
                                id: light.id.clone(),
                                type_: light.type_.to_string(),
                                traits: light
                                    .available_light_modes
                                    .iter()
                                    .map(LightMode::to_string)
                                    .collect(),
                                name: Name {
                                    default_name: vec![light.name.to_string()],
                                    name: Some(light.name.clone()),
                                    nicknames: vec![],
                                },
                                will_report_state: false,
                                device_info: None,
                                room_hint: None,
                                structure_hint: None,
                                attributes: None,
                            })
                        }
                        &Device::Thermostat(ref thermostat) => {
                            response.payload.devices.push(SyncResponseDevice {
                                id: thermostat.id.clone(),
                                type_: "".to_string(), // XXX
                                traits: vec![
                                    "action.devices.traits.TemperatureSetting".to_string(),
                                ],
                                name: Name {
                                    default_name: vec![thermostat.name.to_string()],
                                    name: Some(thermostat.name.clone()),
                                    nicknames: vec![],
                                },
                                // TODO: attributes.
                                will_report_state: false,
                                device_info: None,
                                room_hint: None,
                                structure_hint: None,
                                attributes: None,
                            })
                        }
                        &Device::Scene(ref scene) => {
                            response.payload.devices.push(SyncResponseDevice {
                                id: scene.id.clone(),
                                type_: "action.devices.types.SCENE".to_string(),
                                traits: vec!["action.devices.traits.Scene".to_string()],
                                name: Name {
                                    default_name: vec![scene.name.to_string()],
                                    name: Some(scene.name.clone()),
                                    nicknames: vec![],
                                },
                                will_report_state: false,
                                device_info: None,
                                room_hint: None,
                                structure_hint: None,
                                attributes: None,
                            })
                        }
                    }
                }

                let res = serde_json::to_string(&response).unwrap_or("".to_string());
                println!("action_response: {:?}", res);
                let mut rsp = Response::with((status::Ok, res));
                rsp.headers.set(ContentType::json());
                // For browser access.
                rsp.headers.set(AccessControlAllowOrigin::Any);
                return Ok(rsp);
            } else if input.intent == "action.devices.QUERY" {
                let mut response = QueryResponse {
                    request_id: action_request.request_id.clone(),
                    payload: QueryResponsePayload {
                        devices: btreemap!{},
                    },
                };

                let ref devices = *self.devices.lock().unwrap();
                if let Some(payload) = input.payload {
                    for request_device in payload.devices {
                        for device in devices {
                            match device {
                                &Device::Light(ref light) => if light.id == request_device.id {
                                    response
                                        .payload
                                        .devices
                                        .insert(light.id.clone(), light.status.clone().into());
                                },
                                &Device::Thermostat(ref thermostat) => {
                                    if thermostat.id == request_device.id {
                                        // TODO
                                    }
                                }
                                &Device::Scene(ref _scene) => {}
                            }
                        }
                    }
                }

                let res = serde_json::to_string(&response).unwrap_or("".to_string());
                println!("action_response: {:?}", res);
                let mut rsp = Response::with((status::Ok, res));
                rsp.headers.set(ContentType::json());
                // For browser access.
                rsp.headers.set(AccessControlAllowOrigin::Any);
                return Ok(rsp);
            } else if input.intent == "action.devices.EXECUTE" {
                let mut response = ExecuteResponse {
                    request_id: action_request.request_id.clone(),
                    payload: ExecuteResponsePayload {
                        error_code: None,
                        debug_string: None,
                        commands: vec![],
                    },
                };

                if let Some(ref p) = input.payload {
                    for command in &p.commands {
                        println!("command: {:?}", command);
                        for execution in &command.execution {
                            println!("execution: {:?}", execution);
                            for request_device in &command.devices {
                                println!("request_device: {:?}", request_device);
                                let ref mut devices = *self.devices.lock().unwrap();
                                for device in devices {
                                    match device {
                                        &mut Device::Light(ref mut light) => {
                                            if light.id == request_device.id {
                                                if let Some(s) = execution.params.on {
                                                    light.set_on(s);
                                                }
                                                if let Some(s) = execution.params.brightness {
                                                    light.set_brightness(s);
                                                }
                                                if let Some(ref s) = execution.params.color {
                                                    if let Some(s) = s.spectrum_rgb {
                                                        light.set_color(to_rgb(s));
                                                    }
                                                }
                                                response.payload.commands.push(
                                                    ExecuteResponseCommand {
                                                        ids: vec![light.id.clone()],
                                                        status: "SUCCESS".to_string(),
                                                        states: light.status.clone().into(),
                                                    },
                                                );
                                            }
                                        }
                                        &mut Device::Thermostat(ref mut thermostat) => {
                                            if thermostat.id == request_device.id {
                                                if let Some(s) =
                                                    execution.params.thermostat_temperature_setpoint
                                                {
                                                    thermostat.temperature_setpoint(s);
                                                }
                                                if let (Some(low), Some(high)) = (
                                                    execution
                                                        .params
                                                        .thermostat_temperature_setpoint_low,
                                                    execution
                                                        .params
                                                        .thermostat_temperature_setpoint_high,
                                                ) {
                                                    thermostat.temperature_set_range(low, high);
                                                }
                                                if let Some(ref mode) =
                                                    execution.params.thermostat_mode
                                                {
                                                    if let Ok(mode) = ThermostatMode::from_str(mode)
                                                    {
                                                        thermostat.thermostat_set_mode(mode);
                                                    }
                                                }
                                                response.payload.commands.push(
                                                    ExecuteResponseCommand {
                                                        ids: vec![thermostat.id.clone()],
                                                        status: "SUCCESS".to_string(),
                                                        states: thermostat.status.clone().into(),
                                                    },
                                                );
                                            }
                                        }
                                        &mut Device::Scene(ref mut _scene) => {}
                                    }
                                }
                            }
                        }
                    }
                }

                let res = serde_json::to_string(&response).unwrap_or("".to_string());
                println!("action_response: {:?}", res);
                let mut rsp = Response::with((status::Ok, res));
                rsp.headers.set(ContentType::json());
                // For browser access.
                rsp.headers.set(AccessControlAllowOrigin::Any);
                return Ok(rsp);
            }
        }

        let mut rsp = Response::with((status::Ok, "ACTION"));
        rsp.headers.set(ContentType::json());
        // For browser access.
        rsp.headers.set(AccessControlAllowOrigin::Any);
        Ok(rsp)
    }
}

fn to_rgb(c: u64) -> rgb::RGB8 {
    rgb::RGB8 {
        r: ((c & 0xFF0000) >> 16) as u8,
        g: ((c & 0x00FF00) >> 8) as u8,
        b: ((c & 0x0000FF) >> 0) as u8,
    }
}

fn main() {
    let mote = Arc::new(Mutex::new(mote::Mote::new("/dev/ttyACM0", true)));
    let hub = Hub {
        devices: Mutex::new(vec![
            Device::Light(Light {
                id: "11".to_string(),
                name: "Bedroom lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 0,
                pixel_high: 16,
            }),
            Device::Light(Light {
                id: "22".to_string(),
                name: "Kitchen lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 16,
                pixel_high: 32,
            }),
            Device::Light(Light {
                id: "33".to_string(),
                name: "Bathroom lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 32,
                pixel_high: 48,
            }),
            Device::Light(Light {
                id: "44".to_string(),
                name: "Living Room lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 48,
                pixel_high: 64,
            }),
            Device::Scene(Scene {
                id: "55".to_string(),
                name: "Party mode".to_string(),
                reversible: false,
            }),
        ]),
    };
    let oauth = oauth::OAuth::new();
    let mut control = Router::new();
    control
        .get("/auth", oauth.auth, "auth")
        .post("/token", oauth.token, "token")
        .get("/login", oauth.login, "login")
        .post("/action", hub, "post action")
        .get("/action", get_action_handler, "get action")
        .options("/action", options_action_handler, "get action")
        .get("/", index_handler, "index");
    println!("Listening on port 1234");
    Iron::new(control).http("0.0.0.0:1234").unwrap();
}

fn index_handler(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, "index")))
}

fn get_action_handler(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, "get action")))
}

fn options_action_handler(_: &mut Request) -> IronResult<Response> {
    let mut rsp = Response::with((status::Ok, "options"));
    rsp.headers.set(AccessControlAllowOrigin::Any);
    rsp.headers.set(AccessControlAllowHeaders(
        vec![UniCase("Content-Type".to_string())],
    ));
    Ok(rsp)
}
<|endoftext|>


<commit_before>extern crate docopt;

use docopt::Docopt;

fn main() {
	const VERSION: &'static str = env!("CARGO_PKG_VERSION");
	static USAGE: &'static str = "
	Usage:
	  sassers [options]

	Options:
	    -h, --help         Show this message.
	    -v, --version      Show the version of sassers.
	";

	let args = Docopt::new(USAGE)
	                  .and_then(|d| d.parse())
	                  .unwrap_or_else(|e| e.exit());

	if args.get_bool("-v") {
		println!("{}", VERSION);
	}
}
<commit_msg>Take style & input filename; output the input file contents.<commit_after>extern crate docopt;

use docopt::Docopt;
use std::fs::File;
use std::io::Read;
use std::path::Path;

fn main() {
    const VERSION: &'static str = env!("CARGO_PKG_VERSION");
    static USAGE: &'static str = "
Usage:
    sassers [-t <style>] <inputfile>
    sassers [-vh]

Options:
    -h, --help                   Show this message.
    -v, --version                Show the version of sassers.
    -t <style>, --style <style>  Output style.
    ";

    let args = Docopt::new(USAGE)
                      .and_then(|d| d.parse())
                      .unwrap_or_else(|e| e.exit());

    if args.get_bool("-v") {
        println!("{}", VERSION);
    } else {
        let style = args.get_str("-t");
        let inputfile = args.get_str("<inputfile>");

        let mut sass = String::new();
        File::open(&Path::new(&inputfile)).unwrap().read_to_string(&mut sass).unwrap();

        println!("{}", sass);
    }
}
<|endoftext|>


<commit_before>extern crate regex;
use regex::Regex;

fn main() {

    let test = "(abc)".to_string();
    let tokened: Vec<String> = tokenize(&test);

    println!("{:?}",tokened)
}

fn tokenize<'s>(input: &'s String) -> Vec<String>{
    let mut tokens = vec![];

    let re1 = Regex::new(r"\(").unwrap();
    let re2 = Regex::new(r"\)").unwrap();
    let mut after = re1.replace_all(input,"( ");
    after = re2.replace_all(after.as_slice(), " )");

    let after_sliced: &str = after.as_slice();
    let mut split = after_sliced.split_str(" ");

    //I bet there is a better way to do this, but I keep getting lifetime errors.
    for token in split {
        tokens.push(token.to_string());
    }

    tokens
}
<commit_msg>Small cleanuo.<commit_after>#![feature(core)] //this should be removed before out of beta
extern crate regex;
use regex::Regex;

fn main() {

    let test = "(abc)".to_string();
    let tokened: Vec<String> = tokenize(&test);

    println!("{:?}",tokened)
}

fn tokenize(input: & String) -> Vec<String>{
    let mut tokens = vec![];

    let re1 = Regex::new(r"\(").unwrap();
    let re2 = Regex::new(r"\)").unwrap();
    let mut after = re1.replace_all(input,"( ");
    after = re2.replace_all(after.as_slice(), " )");

    let after_sliced: &str = after.as_slice();
    let split = after_sliced.split(" ");

    //I bet there is a better way to do this, but I keep getting lifetime errors.
    for token in split {
        tokens.push(token.to_string());
    }

    tokens
}
<|endoftext|>


<commit_before>extern crate image;
extern crate time;

extern crate rusttracer;

use std::path::Path;
use std::env;

use rusttracer::math::Vector3;
use rusttracer::{Scene, Color, Camera, Material, Renderer, SuperSampling};
use rusttracer::geometry::{Shape, Sphere, Plane};

const MAX_DEPTH: u32 = 5;
const WIDTH: u32 = 1920;
const HEIGHT: u32 = 1080;
const BUFFER_SIZE: usize = (WIDTH * HEIGHT * 3) as usize;
const DEFAULT_NUMBER_OF_THREADS: u32 = 4;

fn main() {
    let num_threads = match env::var("NUM_THREADS") {
        Ok(threads) => threads.parse::<u32>().unwrap_or(DEFAULT_NUMBER_OF_THREADS),
        Err(_) => DEFAULT_NUMBER_OF_THREADS,
    };

    let benchmark = match env::var("BENCHMARK") {
        Ok(s) => s.parse::<bool>().unwrap_or(false),
        Err(_) => false,
    };

    let floor_material = Material::new(Color::white(), Color::black(), 0.0);
    let floor = Plane::new(Vector3::new(0.0, -15.0, 0.0),
                           Vector3::new(0.0, 1.0, 0.0),
                           floor_material);

    let m1 = Material::new(Color::new(29, 86, 140), Color::black(), 0.0);
    let s1 = Sphere::new(Vector3::new(0.0, 0.0, 15.0), 1.0, m1);

    let m2 = Material::new(Color::new(140, 10, 29), Color::black(), 0.0);
    let s2 = Sphere::new(Vector3::new(-3.0, 0.0, 15.0), 1.0, m2);

    let m3 = Material::new(Color::new(10, 145, 29), Color::black(), 0.0);
    let s3 = Sphere::new(Vector3::new(3.0, 0.0, 15.0), 1.0, m3);

    let m4 = Material::new(Color::new(10, 145, 120), Color::black(), 0.0);
    let s4 = Sphere::new(Vector3::new(1.5, 2.0, 15.0), 0.5, m4);

    let m5 = Material::new(Color::new(190, 145, 29), Color::black(), 0.0);
    let s5 = Sphere::new(Vector3::new(-1.5, 2.0, 15.0), 0.5, m5);

    let m6 = Material::new(Color::new(150, 10, 120), Color::black(), 0.0);
    let s6 = Sphere::new(Vector3::new(1.5, -2.0, 15.0), 0.5, m6);

    let m7 = Material::new(Color::new(190, 20, 29), Color::black(), 0.0);
    let s7 = Sphere::new(Vector3::new(-1.5, -2.0, 15.0), 0.5, m7);

    let objects: Vec<&Shape> = vec![&s1, &s2, &s3, &s4, &s5, &s6, &s7, &floor];
    let scene = Scene::new(&objects, Color::black());
    let camera = Camera::new(0.785398163, WIDTH, HEIGHT);

    let renderer = Renderer::new(&scene, &camera, SuperSampling::On(2), num_threads);

    if benchmark {
        for i in 0..10 {
            let x: Vec<Color> = renderer.render(MAX_DEPTH);
        }
    }

    let result: Vec<Color> = renderer.render(MAX_DEPTH);
    let mut buffer = vec![0x8C; BUFFER_SIZE];

    for (index, pixel) in result.iter().enumerate() {
        buffer[(index * 3) + 0] = pixel.r();
        buffer[(index * 3) + 1] = pixel.g();
        buffer[(index * 3) + 2] = pixel.b();
    }

    let timestamp = time::get_time().sec;
    let filename = format!("images/{}.png", timestamp);
    image::save_buffer(&Path::new(&filename),
                       &buffer[..],
                       WIDTH,
                       HEIGHT,
                       image::RGB(8))
            .unwrap();
}
<commit_msg>Don't produce output for benchmarks<commit_after>extern crate image;
extern crate time;

extern crate rusttracer;

use std::path::Path;
use std::env;

use rusttracer::math::Vector3;
use rusttracer::{Scene, Color, Camera, Material, Renderer, SuperSampling};
use rusttracer::geometry::{Shape, Sphere, Plane};

const MAX_DEPTH: u32 = 5;
const WIDTH: u32 = 1920;
const HEIGHT: u32 = 1080;
const BUFFER_SIZE: usize = (WIDTH * HEIGHT * 3) as usize;
const DEFAULT_NUMBER_OF_THREADS: u32 = 4;

fn main() {
    let num_threads = match env::var("NUM_THREADS") {
        Ok(threads) => threads.parse::<u32>().unwrap_or(DEFAULT_NUMBER_OF_THREADS),
        Err(_) => DEFAULT_NUMBER_OF_THREADS,
    };

    let benchmark = match env::var("BENCHMARK") {
        Ok(s) => s.parse::<bool>().unwrap_or(false),
        Err(_) => false,
    };

    let floor_material = Material::new(Color::white(), Color::black(), 0.0);
    let floor = Plane::new(Vector3::new(0.0, -15.0, 0.0),
                           Vector3::new(0.0, 1.0, 0.0),
                           floor_material);

    let m1 = Material::new(Color::new(29, 86, 140), Color::black(), 0.0);
    let s1 = Sphere::new(Vector3::new(0.0, 0.0, 15.0), 1.0, m1);

    let m2 = Material::new(Color::new(140, 10, 29), Color::black(), 0.0);
    let s2 = Sphere::new(Vector3::new(-3.0, 0.0, 15.0), 1.0, m2);

    let m3 = Material::new(Color::new(10, 145, 29), Color::black(), 0.0);
    let s3 = Sphere::new(Vector3::new(3.0, 0.0, 15.0), 1.0, m3);

    let m4 = Material::new(Color::new(10, 145, 120), Color::black(), 0.0);
    let s4 = Sphere::new(Vector3::new(1.5, 2.0, 15.0), 0.5, m4);

    let m5 = Material::new(Color::new(190, 145, 29), Color::black(), 0.0);
    let s5 = Sphere::new(Vector3::new(-1.5, 2.0, 15.0), 0.5, m5);

    let m6 = Material::new(Color::new(150, 10, 120), Color::black(), 0.0);
    let s6 = Sphere::new(Vector3::new(1.5, -2.0, 15.0), 0.5, m6);

    let m7 = Material::new(Color::new(190, 20, 29), Color::black(), 0.0);
    let s7 = Sphere::new(Vector3::new(-1.5, -2.0, 15.0), 0.5, m7);

    let objects: Vec<&Shape> = vec![&s1, &s2, &s3, &s4, &s5, &s6, &s7, &floor];
    let scene = Scene::new(&objects, Color::black());
    let camera = Camera::new(0.785398163, WIDTH, HEIGHT);

    let renderer = Renderer::new(&scene, &camera, SuperSampling::On(2), num_threads);

    if benchmark {
        for i in 0..10 {
            let x: Vec<Color> = renderer.render(MAX_DEPTH);
        }

        return;
    }

    let result: Vec<Color> = renderer.render(MAX_DEPTH);
    let mut buffer = vec![0x8C; BUFFER_SIZE];

    for (index, pixel) in result.iter().enumerate() {
        buffer[(index * 3) + 0] = pixel.r();
        buffer[(index * 3) + 1] = pixel.g();
        buffer[(index * 3) + 2] = pixel.b();
    }

    let timestamp = time::get_time().sec;
    let filename = format!("images/{}.png", timestamp);
    image::save_buffer(&Path::new(&filename),
                       &buffer[..],
                       WIDTH,
                       HEIGHT,
                       image::RGB(8))
            .unwrap();
}
<|endoftext|>


<commit_before>#![feature(libc, core, std_misc, io, alloc)]

extern crate libc;

use std::ptr;
use std::mem;
use std::ops::Drop;
use std::old_io::timer;
use std::time::Duration;
use std::sync::Arc;
use std::sync::Future;

use libc::{uint8_t,
	c_void,
	size_t};

// B8G8R8A8 pixel size in bytes
static PIXEL_SIZE: usize = 4;

// Like the failed windows one
macro_rules! FAILED { ($hr:expr) => ($hr < 0) }

enum CaptureResult {
	CrOk,
	// Could not duplicate output, access denied. Might be in protected fullscreen.
	CrAccessDenied,
	// Access to the duplicated output was lost. Likely, mode was changed e.g. window => full
	CrAccessLost,
	// AcquireNextFrame timed out.
	CrTimeout,
	// General/Unexpected failure
	CrFail,
}

trait AsCaptureResult {
	fn as_capture_result(&self) -> CaptureResult;
}

impl AsCaptureResult for uint8_t {
	fn as_capture_result(&self) -> CaptureResult {
		match *self {
			0 => CaptureResult::CrOk,
			1 => CaptureResult::CrAccessDenied,
			2 => CaptureResult::CrAccessLost,
			3 => CaptureResult::CrTimeout,
			_ => CaptureResult::CrFail,
		}
	}
}

#[link(name = "DXGCap")]
extern {
	fn init();

	fn create_dxgi_manager() -> *mut c_void;

	fn delete_dxgi_manager(dxgi_manager: *mut c_void);

	fn get_output_dimensions(dxgi_manager: *const c_void, width: *mut size_t,
		height: *mut size_t);

	// Returns whether succeded
	fn get_frame_bytes(dxgi_manager: *mut c_void, o_size: *mut size_t,
		o_bytes: *mut *mut uint8_t) -> uint8_t;
}

#[derive(Clone, Debug)]
struct RGB8 {
	red: u8,
	green: u8,
	blue: u8
}

#[derive(Clone)]
struct Frame {
	width: usize,
	height: usize,
	data: Vec<u8>,
}

impl Frame {
	fn new() -> Frame {
		Frame{ width: 0, height: 0, data: Vec::new() }
	}

	fn average_color(&self, led: &Led) -> RGB8 {
		let (mut r_sum, mut g_sum, mut b_sum) = (0u64, 0u64, 0u64);
		// Coordinate factors
		let &Led((x1f, y1f), (x2f, y2f)) = led;
		// Skip every second row and column for better performance, with not too much
		// signal loss for most monitors
		let (widthf32, heightf32) = ((self.width/2) as f32, (self.height/2) as f32);
		for row in (y1f * heightf32) as usize .. (y2f * heightf32) as usize {
			for col in (x1f * widthf32) as usize .. (x2f * widthf32) as usize {
				let i = 2 * PIXEL_SIZE * (row * self.width + col);
				b_sum += self.data[i] as u64;
				g_sum += self.data[i+1] as u64;
				r_sum += self.data[i+2] as u64;
			}
		}

		let n64 = (self.width * self.height) as u64;
		RGB8{ red: (r_sum/n64) as u8, green: (g_sum/n64) as u8, blue: (b_sum/n64) as u8 }
	}
}

struct Capturer {
	dxgi_manager: *mut c_void,
	frame: Frame,
}

impl Capturer {
	fn new() -> Result<Capturer, ()> {
		let manager = unsafe { create_dxgi_manager() };
		if manager.is_null() {
			Err(())
		} else {
			Ok(Capturer{
				dxgi_manager: manager,
				frame: Frame { width: 0, height: 0, data: Vec::new() }})
		}
	}

	fn output_dimensions(&self) -> (usize, usize) {
		let (mut width, mut height): (size_t, size_t) = (0, 0);
		unsafe { get_output_dimensions(self.dxgi_manager, &mut width, &mut height); }
		(width as usize, height as usize)
	}

	fn capture_frame(&mut self) -> CaptureResult {
		let mut buffer_size: size_t = 0;
		let mut buffer = ptr::null_mut::<u8>();
		let cr = unsafe{
			get_frame_bytes(self.dxgi_manager, &mut buffer_size, &mut buffer)
				.as_capture_result() };
		if let CaptureResult::CrOk = cr  {
			if buffer as *const _ == self.frame.data.as_ptr() {
				CaptureResult::CrOk
			} else {
				let buffer_size = buffer_size as usize;
				if buffer.is_null() {
					CaptureResult::CrFail
				} else {
					let (width, height) = self.output_dimensions();
					self.frame = Frame{ width: width, height: height,
						data: unsafe {
							Vec::from_raw_parts(buffer, buffer_size,
								buffer_size) }};
					CaptureResult::CrOk
				}
			}
		} else {
			cr
		}
	}

	// Replaces the selfs frame, returning it. This is not a problem in and by itself, only,
	// the pointer for the vector in the frame is also used at other locations, the vector may
	// therefore be unexpectedly modified
	unsafe fn replace_frame(&mut self, replacement: Frame) -> Frame {
		mem::replace(&mut self.frame, replacement)
	}
}

impl Drop for Capturer {
	fn drop(&mut self) {
		unsafe {
			let v = mem::replace(&mut self.frame.data, Vec::new());
			mem::forget(v);
			delete_dxgi_manager(self.dxgi_manager);
		}
	}
}

fn init_dxgi() {
	unsafe { init(); }
}

// (x1, y1), (x2, y2)
struct Led((f32, f32), (f32, f32));

static LEDS: [Led; 32] = [
	Led((0.0000, 0.9219), (0.0600, 1.0000)),
	Led((0.0000, 0.8450), (0.0600, 0.9242)),
	Led((0.0000, 0.7681), (0.0600, 0.8473)),
	Led((0.0000, 0.6912), (0.0600, 0.7704)),
	Led((0.0000, 0.6142), (0.0600, 0.6935)),
	Led((0.0000, 0.5373), (0.0600, 0.6165)),
	Led((0.0000, 0.4604), (0.0600, 0.5396)),
	Led((0.0000, 0.3835), (0.0600, 0.4627)),
	Led((0.0000, 0.3065), (0.0600, 0.3858)),
	Led((0.0000, 0.2296), (0.0600, 0.3088)),
	Led((0.0000, 0.1527), (0.0600, 0.2319)),
	Led((0.0000, 0.0758), (0.0600, 0.1550)),
	Led((0.0000, 0.0000), (0.0600, 0.0781)),
	Led((0.0000, 0.0000), (0.0600, 0.1000)),
	Led((0.0000, 0.0000), (0.0461, 0.1000)),
	Led((0.0448, 0.0000), (0.0916, 0.1000)),
	Led((0.0902, 0.0000), (0.1370, 0.1000)),
	Led((0.1357, 0.0000), (0.1825, 0.1000)),
	Led((0.1811, 0.0000), (0.2280, 0.1000)),
	Led((0.2266, 0.0000), (0.2734, 0.1000)),
	Led((0.2720, 0.0000), (0.3189, 0.1000)),
	Led((0.3175, 0.0000), (0.3643, 0.1000)),
	Led((0.3630, 0.0000), (0.4098, 0.1000)),
	Led((0.4084, 0.0000), (0.4552, 0.1000)),
	Led((0.4539, 0.0000), (0.5007, 0.1000)),
	Led((0.4993, 0.0000), (0.5461, 0.1000)),
	Led((0.5448, 0.0000), (0.5916, 0.1000)),
	Led((0.5902, 0.0000), (0.6370, 0.1000)),
	Led((0.6357, 0.0000), (0.6825, 0.1000)),
	Led((0.6811, 0.0000), (0.7280, 0.1000)),
	Led((0.7266, 0.0000), (0.7734, 0.1000)),
	Led((0.7720, 0.0000), (0.8189, 0.1000)),
];

fn main() {
	use CaptureResult::*;
	init_dxgi();
	let mut capturer = Capturer::new().unwrap();

	let (width, height) = capturer.output_dimensions();
	println!("{} x {}", width, height);

	for _ in 0..600u16 {
		match capturer.capture_frame() {
			CrOk => (),
			// We are probably in fullscreen app with restricted access,
			// sleep until we have access again
			CrAccessDenied => timer::sleep(Duration::seconds(2)),
			// Has already been handeled in DXGCap, just try again
			CrAccessLost => continue,
			CrTimeout => continue,
			// CrFail. Might be bad, might be no big deal. Just ignore for now
			CrFail => continue,
		}

		let frame = unsafe { capturer.replace_frame(Frame::new()) };
		let mut shared_frame = Arc::new(frame);

		let out_vals: Vec<_> = LEDS.iter()
			.map(|led| {
				let child_frame = shared_frame.clone();
				Future::spawn(move || child_frame.average_color(led)) })
			.collect::<Vec<_>>()
			.into_iter()
			.map(|mut guard| guard.get())
			.collect();

		unsafe { capturer.replace_frame(mem::replace(shared_frame.make_unique(),
			Frame::new())); }

		println!("{:?}", out_vals);
	}
}
<commit_msg>Led color grabbing worksC:\msys64\usr\bin\l_time.exe -m 'Next step: config parsing and outputting to arduino'<commit_after>#![feature(libc, core, std_misc, io, alloc)]

extern crate libc;

use std::ptr;
use std::mem;
use std::ops::Drop;
use std::old_io::timer;
use std::time::Duration;
use std::sync::Arc;
use std::sync::Future;

use libc::{uint8_t,
	c_void,
	size_t};

// B8G8R8A8 pixel size in bytes
static PIXEL_SIZE: usize = 4;

enum CaptureResult {
	CrOk,
	// Could not duplicate output, access denied. Might be in protected fullscreen.
	CrAccessDenied,
	// Access to the duplicated output was lost. Likely, mode was changed e.g. window => full
	CrAccessLost,
	// AcquireNextFrame timed out.
	CrTimeout,
	// General/Unexpected failure
	CrFail,
}

trait AsCaptureResult {
	fn as_capture_result(&self) -> CaptureResult;
}

impl AsCaptureResult for uint8_t {
	fn as_capture_result(&self) -> CaptureResult {
		match *self {
			0 => CaptureResult::CrOk,
			1 => CaptureResult::CrAccessDenied,
			2 => CaptureResult::CrAccessLost,
			3 => CaptureResult::CrTimeout,
			_ => CaptureResult::CrFail,
		}
	}
}

#[link(name = "DXGCap")]
extern {
	fn init();

	fn create_dxgi_manager() -> *mut c_void;

	fn delete_dxgi_manager(dxgi_manager: *mut c_void);

	fn get_output_dimensions(dxgi_manager: *const c_void, width: *mut size_t,
		height: *mut size_t);

	// Returns whether succeded
	fn get_frame_bytes(dxgi_manager: *mut c_void, o_size: *mut size_t,
		o_bytes: *mut *mut uint8_t) -> uint8_t;
}

#[derive(Clone, Debug)]
struct RGB8 {
	red: u8,
	green: u8,
	blue: u8
}

#[derive(Clone)]
struct Frame {
	width: usize,
	height: usize,
	data: Vec<u8>,
}

impl Frame {
	fn new() -> Frame {
		Frame{ width: 0, height: 0, data: Vec::new() }
	}

	fn average_color(&self, led: &Led) -> RGB8 {
		let (mut r_sum, mut g_sum, mut b_sum) = (0u64, 0u64, 0u64);
		// Coordinate factors
		let &Led((x1f, y1f), (x2f, y2f)) = led;
		// Skip every second row and column for better performance, with not too much
		// signal loss for most monitors
		let (widthf32, heightf32) = ((self.width/2) as f32, (self.height/2) as f32);
		let (start_y, end_y, start_x, end_x) = ((y1f * heightf32) as usize,
			(y2f * heightf32) as usize, (x1f * widthf32) as usize,
			(x2f * widthf32) as usize);
		for row in start_y..end_y {
			for col in start_x..end_x {
				let i = 2 * PIXEL_SIZE * (row * self.width + col);
				// println!("b val: {}", self.data[i]);
				b_sum += self.data[i] as u64;
				g_sum += self.data[i+1] as u64;
				r_sum += self.data[i+2] as u64;
			}
		}

		let n_of_pixels = ((end_x - start_x) * (end_y - start_y)) as u64;
		RGB8{ red: (r_sum/n_of_pixels) as u8, green: (g_sum/n_of_pixels) as u8,
			blue: (b_sum/n_of_pixels) as u8 }
	}
}

struct Capturer {
	dxgi_manager: *mut c_void,
	frame: Frame,
}

impl Capturer {
	fn new() -> Result<Capturer, ()> {
		let manager = unsafe { create_dxgi_manager() };
		if manager.is_null() {
			Err(())
		} else {
			Ok(Capturer{
				dxgi_manager: manager,
				frame: Frame { width: 0, height: 0, data: Vec::new() }})
		}
	}

	fn output_dimensions(&self) -> (usize, usize) {
		let (mut width, mut height): (size_t, size_t) = (0, 0);
		unsafe { get_output_dimensions(self.dxgi_manager, &mut width, &mut height); }
		(width as usize, height as usize)
	}

	fn capture_frame(&mut self) -> CaptureResult {
		let mut buffer_size: size_t = 0;
		let mut buffer = ptr::null_mut::<u8>();
		let cr = unsafe{
			get_frame_bytes(self.dxgi_manager, &mut buffer_size, &mut buffer)
				.as_capture_result() };
		if let CaptureResult::CrOk = cr  {
			if buffer as *const _ == self.frame.data.as_ptr() {
				CaptureResult::CrOk
			} else {
				let buffer_size = buffer_size as usize;
				if buffer.is_null() {
					CaptureResult::CrFail
				} else {
					let (width, height) = self.output_dimensions();
					self.frame = Frame{ width: width, height: height,
						data: unsafe {
							Vec::from_raw_parts(buffer, buffer_size,
								buffer_size) }};
					CaptureResult::CrOk
				}
			}
		} else {
			cr
		}
	}

	// Replaces the selfs frame, returning it. This is not a problem in and by itself, only,
	// the pointer for the vector in the frame is also used at other locations, the vector may
	// therefore be unexpectedly modified
	unsafe fn replace_frame(&mut self, replacement: Frame) -> Frame {
		mem::replace(&mut self.frame, replacement)
	}
}

impl Drop for Capturer {
	fn drop(&mut self) {
		unsafe {
			let v = mem::replace(&mut self.frame.data, Vec::new());
			mem::forget(v);
			delete_dxgi_manager(self.dxgi_manager);
		}
	}
}

fn init_dxgi() {
	unsafe { init(); }
}

// (x1, y1), (x2, y2)
struct Led((f32, f32), (f32, f32));

static LEDS: [Led; 32] = [
	Led((0.0000, 0.9219), (0.0600, 1.0000)),
	Led((0.0000, 0.8450), (0.0600, 0.9242)),
	Led((0.0000, 0.7681), (0.0600, 0.8473)),
	Led((0.0000, 0.6912), (0.0600, 0.7704)),
	Led((0.0000, 0.6142), (0.0600, 0.6935)),
	Led((0.0000, 0.5373), (0.0600, 0.6165)),
	Led((0.0000, 0.4604), (0.0600, 0.5396)),
	Led((0.0000, 0.3835), (0.0600, 0.4627)),
	Led((0.0000, 0.3065), (0.0600, 0.3858)),
	Led((0.0000, 0.2296), (0.0600, 0.3088)),
	Led((0.0000, 0.1527), (0.0600, 0.2319)),
	Led((0.0000, 0.0758), (0.0600, 0.1550)),
	Led((0.0000, 0.0000), (0.0600, 0.0781)),
	Led((0.0000, 0.0000), (0.0600, 0.1000)),
	Led((0.0000, 0.0000), (0.0461, 0.1000)),
	Led((0.0448, 0.0000), (0.0916, 0.1000)),
	Led((0.0902, 0.0000), (0.1370, 0.1000)),
	Led((0.1357, 0.0000), (0.1825, 0.1000)),
	Led((0.1811, 0.0000), (0.2280, 0.1000)),
	Led((0.2266, 0.0000), (0.2734, 0.1000)),
	Led((0.2720, 0.0000), (0.3189, 0.1000)),
	Led((0.3175, 0.0000), (0.3643, 0.1000)),
	Led((0.3630, 0.0000), (0.4098, 0.1000)),
	Led((0.4084, 0.0000), (0.4552, 0.1000)),
	Led((0.4539, 0.0000), (0.5007, 0.1000)),
	Led((0.4993, 0.0000), (0.5461, 0.1000)),
	Led((0.5448, 0.0000), (0.5916, 0.1000)),
	Led((0.5902, 0.0000), (0.6370, 0.1000)),
	Led((0.6357, 0.0000), (0.6825, 0.1000)),
	Led((0.6811, 0.0000), (0.7280, 0.1000)),
	Led((0.7266, 0.0000), (0.7734, 0.1000)),
	Led((0.7720, 0.0000), (0.8189, 0.1000)),
];

fn main() {
	use CaptureResult::*;
	init_dxgi();
	let mut capturer = Capturer::new().unwrap();

	let (width, height) = capturer.output_dimensions();
	println!("{} x {}", width, height);

	for _ in 0..600u16 {
		match capturer.capture_frame() {
			CrOk => (),
			// We are probably in fullscreen app with restricted access,
			// sleep until we have access again
			CrAccessDenied => timer::sleep(Duration::seconds(2)),
			// Has already been handeled in DXGCap, just try again
			CrAccessLost => continue,
			CrTimeout => continue,
			// CrFail. Might be bad, might be no big deal. Just ignore for now
			CrFail => continue,
		}

		let frame = unsafe { capturer.replace_frame(Frame::new()) };

		let mut shared_frame = Arc::new(frame);

		let out_vals: Vec<_> = LEDS.iter()
			.map(|led| {
				let child_frame = shared_frame.clone();
				Future::spawn(move || child_frame.average_color(led)) })
			.collect::<Vec<_>>()
			.into_iter()
			.map(|mut guard| guard.get())
			.collect();

		unsafe { capturer.replace_frame(mem::replace(shared_frame.make_unique(),
			Frame::new())); }

		// println!("{:?}\n", out_vals);
	}
}
<|endoftext|>


<commit_before>#![feature(globs)]

extern crate graphics;
extern crate piston;
extern crate rand;
extern crate native;

use piston::*;

mod snakeapp;
mod object;
mod settings;
mod text;
mod bar;
mod player;
mod snake;
mod action;
mod game_state;
mod character;
mod air_bottle;

#[start]
fn start(argc: int, argv: **u8) -> int {
    // Run GLFW on the main thread.
    native::start(argc, argv, main)
}

fn main() {
    use snakeapp::SnakeApp;
    let mut game_window: GameWindowSDL2 = GameWindow::new(
        GameWindowSettings {
            title: "Sea Snake Escape".to_string(),
            size: [512, 512],
            fullscreen: false,
            exit_on_esc: true,
            background_color: settings::WATER_COLOR,
        }
    );

    let mut app = SnakeApp::new();
    app.load();

    // app.run(&mut game_window, &mut asset_store);
    let mut game_iterator = GameIterator::new(&mut game_window,
        &GameIteratorSettings {
            updates_per_second: 120,
            max_frames_per_second: 60
        });
    loop { match game_iterator.next() { None => { break }, Some(e) => {
        match e {
            Render(args) => {
                let c = graphics::Context::abs(args.width as f64, args.height as f64);
                app.render(&c, args.gl);
            },
            Update(args) => {
                app.update(args.dt);
            },
            KeyPress(args) => {
                app.key_press(args.key);
            },
            KeyRelease(args) => {
                app.key_release(args.key);
            },
            _ => {},
        }
    } } }
}

<commit_msg>Upgraded to latest Piston<commit_after>#![feature(globs)]

extern crate graphics;
extern crate piston;
extern crate rand;
extern crate native;

use piston::{
    GameIterator,
    GameIteratorSettings,
    GameWindowSDL2,
    GameWindowSettings,
    KeyPress,
    KeyRelease,
    Render,
    Update,
};

mod snakeapp;
mod object;
mod settings;
mod text;
mod bar;
mod player;
mod snake;
mod action;
mod game_state;
mod character;
mod air_bottle;

#[start]
fn start(argc: int, argv: **u8) -> int {
    // Run GLFW on the main thread.
    native::start(argc, argv, main)
}

fn main() {
    use snakeapp::SnakeApp;
    let mut game_window = GameWindowSDL2::new(
        GameWindowSettings {
            title: "Sea Snake Escape".to_string(),
            size: [512, 512],
            fullscreen: false,
            exit_on_esc: true,
            background_color: settings::WATER_COLOR,
        }
    );

    let mut app = SnakeApp::new();
    app.load();

    // app.run(&mut game_window, &mut asset_store);
    let mut game_iterator = GameIterator::new(&mut game_window,
        &GameIteratorSettings {
            updates_per_second: 120,
            max_frames_per_second: 60
        });
    loop { match game_iterator.next() { None => { break }, Some(e) => {
        match e {
            Render(args) => {
                let c = graphics::Context::abs(args.width as f64, args.height as f64);
                app.render(&c, args.gl);
            },
            Update(args) => {
                app.update(args.dt);
            },
            KeyPress(args) => {
                app.key_press(args.key);
            },
            KeyRelease(args) => {
                app.key_release(args.key);
            },
            _ => {},
        }
    } } }
}

<|endoftext|>