<commit_before>extern crate "rust-crypto" as rust_crypto;
extern crate serialize;

use std::io::{TcpListener, TcpStream};
use std::io::{Acceptor, Listener};
use std::io::{File, BufferedStream};
use std::string::String;
use std::os;

use rust_crypto::sha1::Sha1;
use rust_crypto::digest::Digest;
use serialize::base64::{ToBase64, STANDARD};

pub const CR: u8 = b'\r';
pub const LF: u8 = b'\n';
pub const SP: u8 = b' ';
pub const COLON: u8 = b':';
pub const CRLF: &'static [u8] = &[CR,LF];

struct RequestedRoute {
    method: String,
    pathname: String
}

struct ClientHeader {
    key: String,
    value: String
}

enum Payload {
    Text(String)
}

enum Opcode {
    TextOp = 0x1
}

struct Message {
    payload: Payload,
    opcode: Opcode
 }

impl Message {
    fn send (msg: &[u8],
             mut stream: BufferedStream<TcpStream>,
             headers: Vec<ClientHeader>) {
        let payload = match msg {
            String => Payload::Text(msg.to_string())
        };
        let payload = payload;
        let opcode = Opcode::TextOp;
        let length = msg.len() as u8;

        stream.write_u8(0b1000_0000 | opcode as u8).unwrap();
        stream.write_u8(length).unwrap();
        stream.write(msg).unwrap();
    }
}

fn get_header_by_name (header: &[u8], headers: &Vec<ClientHeader>) -> String {
    let mut result = String::new();

    for h in headers.iter() {
        if h.key.as_bytes() == header {
            result = h.value.clone();
            break;
        }
    }

    return result;
}

fn parse_request_line (header: &str) -> RequestedRoute {
    let mut pathname = String::new();
    let mut method = String::new();
    let mut starting = true;
    let mut found_method = false;

    for ch in header.graphemes(true) {
        let cbyte = ch.as_bytes()[0];

        if starting && cbyte != SP {
            method.push_str(ch);
        }
        if starting && cbyte == SP {
            starting = false;
            found_method = true;
            continue;
        }
        if found_method && cbyte != SP {
            pathname.push_str(ch);
        }
        if found_method && cbyte == SP {
            break;
        }

    }

    return RequestedRoute {method: method, pathname: pathname};
}

fn parse_normal_header (header: &str) -> ClientHeader {
    let mut lhs = String::new(); // lhs of ':' in header
    let mut rhs = String::new(); // rhs of ':' in header
    let mut found_colon = false;

    for ch in header.graphemes(true) {
        let cbyte = ch.as_bytes()[0];
        if !found_colon && cbyte == COLON {
            found_colon = true;
            continue;
        }

        if cbyte == CR || cbyte == LF {
            continue;
        }

        if !found_colon {
            lhs.push_str(ch);
        } else {
            rhs.push_str(ch);
        }
    }

    return ClientHeader {
        key:lhs.trim().to_string(),
        value:rhs.trim().to_string()
    };
}

fn get_normal_body (path_on_disk: &str) -> String {
    let path = Path::new(path_on_disk);
    let display = path.display();
    let mut file = match File::open(&path) {
        Ok(f) => f,
        Err(err) => panic!("file error: {}", err)
    };

    let content = match file.read_to_end() {
        Ok(c) => c,
        Err(err) => panic!("{}", err)
    };

    let s = String::from_utf8(content).unwrap();
    return s;
}

fn sec_handshake (from_server: &[u8]) -> String {

    let guid = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

    let mut sha = Sha1::new();

    sha.input(from_server);
    sha.input(guid);
    let mut out = [0u8, ..20];
    sha.result(out.as_mut_slice());

    return out.to_base64(STANDARD);
}

fn ws_handshake (mut stream: BufferedStream<TcpStream>,
                 headers: Vec<ClientHeader>) {

    let header_sec_key = b"Sec-WebSocket-Key";

    let from_server = get_header_by_name(header_sec_key, &headers);
    let accept = sec_handshake(from_server.as_bytes());

    let sec_header = format!("Sec-WebSocket-Accept: {}\r\n", accept);

    stream.write(b"HTTP/1.1 101 Switching Protocols\r\n").unwrap();
    stream.write(b"Upgrade: websocket\r\n").unwrap();
    stream.write(b"Connection: Upgrade\r\n").unwrap();
    stream.write(b"Sec-WebSocket-Version: 13\r\n").unwrap();
    stream.write(b"Sec-WebSocket-Protocol: protocolOne\r\n").unwrap();
    stream.write(sec_header.as_bytes().as_slice()).unwrap();
    stream.write(b"\r\n");

    ws_listen(stream, headers);
}

fn ws_listen(mut stream: BufferedStream<TcpStream>,
             headers: Vec<ClientHeader>) {
    let msg = Message::send(b"hello world", stream, headers);

    let string_msg = "this is a message".to_string();
    let opcode = Opcode::TextOp;
    let payload: Payload = match opcode {
        String => Payload::Text(string_msg)
    };

    let msg2 = box Message {
        payload: payload,
        opcode: opcode
    };
}

fn main () {

    for argument in os::args().iter() {
        println!("arg: {}", argument);
    }

    let addr = "127.0.0.1:8099";

    let listener = TcpListener::bind(addr).unwrap();
    let mut acceptor = listener.listen().unwrap();
    println!("Listening on {}", addr);

    fn handle_client(mut stream: BufferedStream<TcpStream>) {
        let mut body: String = "
You sent it!
".to_string();

        let mut cur_line: String;
        let mut ii = 0u;
        let mut req: RequestedRoute = RequestedRoute {
            pathname: String::new(),
            method: String::new()
        };

        let mut headers: Vec<ClientHeader> = Vec::new();
        loop {
            match stream.read_line() { // XXX: strange unwrap like thing
                Ok(line) => cur_line = line,
                Err(_) => break
            }

            body = body + cur_line + "
";
            if cur_line.as_bytes() == CRLF {
                break;
            }

            if ii == 0u { // the Request-Line is always the first line
                req = parse_request_line(cur_line.as_slice());
                println!("{}", req.pathname);
                ii += 1;
            } else { // this should be  "normal" key-value type header
                headers.push(parse_normal_header(cur_line.as_slice()));
            }

        }

        println!("pathname {} method {}", req.pathname, req.method);

        if req.pathname.as_bytes() == b"/" {
            body = get_normal_body("../html/ws1.html");
        } else if req.pathname.as_bytes() == b"/ws1.js" {
            body = get_normal_body("../html/ws1.js");
        } else if req.pathname.as_bytes() == b"/ws" {
            ws_handshake(stream, headers);
            return;
        }

        let body_length = format!("Content-length: {}", body.len());

        stream.write(b"HTTP/1.1 200 OK\r\n").unwrap();
        stream.write(b"Content-type: text/html\r\n").unwrap();
        stream.write(b"X-header: from bytes\r\n").unwrap();
        stream.write(body_length.into_bytes().as_slice()).unwrap();
        stream.write(b"\r\n\r\n").unwrap();
        stream.write(body.into_bytes().as_slice()).unwrap();
        stream.flush().unwrap();

        println!("Done handling acceptor");
    }

    for stream in acceptor.incoming() {
        match stream {
            Err(e) => { println!("connection failed: {}", e) }
            Ok(stream) => spawn(proc() {
                let bs = BufferedStream::new(stream);
                handle_client(bs)
            })
        }
    }

    drop(acceptor);
}
<commit_msg>use Opcode::TextOp for payload match<commit_after>extern crate "rust-crypto" as rust_crypto;
extern crate serialize;

use std::io::{TcpListener, TcpStream};
use std::io::{Acceptor, Listener};
use std::io::{File, BufferedStream};
use std::string::String;
use std::os;

use rust_crypto::sha1::Sha1;
use rust_crypto::digest::Digest;
use serialize::base64::{ToBase64, STANDARD};

pub const CR: u8 = b'\r';
pub const LF: u8 = b'\n';
pub const SP: u8 = b' ';
pub const COLON: u8 = b':';
pub const CRLF: &'static [u8] = &[CR,LF];

struct RequestedRoute {
    method: String,
    pathname: String
}

struct ClientHeader {
    key: String,
    value: String
}

enum Payload {
    Text(String)
}

enum Opcode {
    TextOp = 0x1
}

struct Message {
    payload: Payload,
    opcode: Opcode
 }

impl Message {
    fn send (msg: &[u8],
             mut stream: BufferedStream<TcpStream>,
             headers: Vec<ClientHeader>) {
        let payload = match msg {
            String => Payload::Text(msg.to_string())
        };
        let payload = payload;
        let opcode = Opcode::TextOp;
        let length = msg.len() as u8;

        stream.write_u8(0b1000_0000 | opcode as u8).unwrap();
        stream.write_u8(length).unwrap();
        stream.write(msg).unwrap();
    }
}

fn get_header_by_name (header: &[u8], headers: &Vec<ClientHeader>) -> String {
    let mut result = String::new();

    for h in headers.iter() {
        if h.key.as_bytes() == header {
            result = h.value.clone();
            break;
        }
    }

    return result;
}

fn parse_request_line (header: &str) -> RequestedRoute {
    let mut pathname = String::new();
    let mut method = String::new();
    let mut starting = true;
    let mut found_method = false;

    for ch in header.graphemes(true) {
        let cbyte = ch.as_bytes()[0];

        if starting && cbyte != SP {
            method.push_str(ch);
        }
        if starting && cbyte == SP {
            starting = false;
            found_method = true;
            continue;
        }
        if found_method && cbyte != SP {
            pathname.push_str(ch);
        }
        if found_method && cbyte == SP {
            break;
        }

    }

    return RequestedRoute {method: method, pathname: pathname};
}

fn parse_normal_header (header: &str) -> ClientHeader {
    let mut lhs = String::new(); // lhs of ':' in header
    let mut rhs = String::new(); // rhs of ':' in header
    let mut found_colon = false;

    for ch in header.graphemes(true) {
        let cbyte = ch.as_bytes()[0];
        if !found_colon && cbyte == COLON {
            found_colon = true;
            continue;
        }

        if cbyte == CR || cbyte == LF {
            continue;
        }

        if !found_colon {
            lhs.push_str(ch);
        } else {
            rhs.push_str(ch);
        }
    }

    return ClientHeader {
        key:lhs.trim().to_string(),
        value:rhs.trim().to_string()
    };
}

fn get_normal_body (path_on_disk: &str) -> String {
    let path = Path::new(path_on_disk);
    let display = path.display();
    let mut file = match File::open(&path) {
        Ok(f) => f,
        Err(err) => panic!("file error: {}", err)
    };

    let content = match file.read_to_end() {
        Ok(c) => c,
        Err(err) => panic!("{}", err)
    };

    let s = String::from_utf8(content).unwrap();
    return s;
}

fn sec_handshake (from_server: &[u8]) -> String {

    let guid = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

    let mut sha = Sha1::new();

    sha.input(from_server);
    sha.input(guid);
    let mut out = [0u8, ..20];
    sha.result(out.as_mut_slice());

    return out.to_base64(STANDARD);
}

fn ws_handshake (mut stream: BufferedStream<TcpStream>,
                 headers: Vec<ClientHeader>) {

    let header_sec_key = b"Sec-WebSocket-Key";

    let from_server = get_header_by_name(header_sec_key, &headers);
    let accept = sec_handshake(from_server.as_bytes());

    let sec_header = format!("Sec-WebSocket-Accept: {}\r\n", accept);

    stream.write(b"HTTP/1.1 101 Switching Protocols\r\n").unwrap();
    stream.write(b"Upgrade: websocket\r\n").unwrap();
    stream.write(b"Connection: Upgrade\r\n").unwrap();
    stream.write(b"Sec-WebSocket-Version: 13\r\n").unwrap();
    stream.write(b"Sec-WebSocket-Protocol: protocolOne\r\n").unwrap();
    stream.write(sec_header.as_bytes().as_slice()).unwrap();
    stream.write(b"\r\n");

    ws_listen(stream, headers);
}

fn ws_listen(mut stream: BufferedStream<TcpStream>,
             headers: Vec<ClientHeader>) {
    let msg = Message::send(b"hello world", stream, headers);

    let string_msg = "this is a message".to_string();
    let opcode = Opcode::TextOp;
    let payload: Payload = match opcode {
        Opcode::TextOp => Payload::Text(string_msg),
    };

    let msg2 = box Message {
        payload: payload,
        opcode: opcode
    };

    //msg2.send(stream, headers);
}

fn main () {

    for argument in os::args().iter() {
        println!("arg: {}", argument);
    }

    let addr = "127.0.0.1:8099";

    let listener = TcpListener::bind(addr).unwrap();
    let mut acceptor = listener.listen().unwrap();
    println!("Listening on {}", addr);

    fn handle_client(mut stream: BufferedStream<TcpStream>) {
        let mut body: String = "
You sent it!
".to_string();

        let mut cur_line: String;
        let mut ii = 0u;
        let mut req: RequestedRoute = RequestedRoute {
            pathname: String::new(),
            method: String::new()
        };

        let mut headers: Vec<ClientHeader> = Vec::new();
        loop {
            match stream.read_line() { // XXX: strange unwrap like thing
                Ok(line) => cur_line = line,
                Err(_) => break
            }

            body = body + cur_line + "
";
            if cur_line.as_bytes() == CRLF {
                break;
            }

            if ii == 0u { // the Request-Line is always the first line
                req = parse_request_line(cur_line.as_slice());
                println!("{}", req.pathname);
                ii += 1;
            } else { // this should be  "normal" key-value type header
                headers.push(parse_normal_header(cur_line.as_slice()));
            }

        }

        println!("pathname {} method {}", req.pathname, req.method);

        if req.pathname.as_bytes() == b"/" {
            body = get_normal_body("../html/ws1.html");
        } else if req.pathname.as_bytes() == b"/ws1.js" {
            body = get_normal_body("../html/ws1.js");
        } else if req.pathname.as_bytes() == b"/ws" {
            ws_handshake(stream, headers);
            return;
        }

        let body_length = format!("Content-length: {}", body.len());

        stream.write(b"HTTP/1.1 200 OK\r\n").unwrap();
        stream.write(b"Content-type: text/html\r\n").unwrap();
        stream.write(b"X-header: from bytes\r\n").unwrap();
        stream.write(body_length.into_bytes().as_slice()).unwrap();
        stream.write(b"\r\n\r\n").unwrap();
        stream.write(body.into_bytes().as_slice()).unwrap();
        stream.flush().unwrap();

        println!("Done handling acceptor");
    }

    for stream in acceptor.incoming() {
        match stream {
            Err(e) => { println!("connection failed: {}", e) }
            Ok(stream) => spawn(proc() {
                let bs = BufferedStream::new(stream);
                handle_client(bs)
            })
        }
    }

    drop(acceptor);
}
<|endoftext|>


<commit_before>use std::slice::bytes::copy_memory;

use mmu::Memory;
use cpu::Cpu;
use graphics;
use timer;

#[deriving(Copy)]
pub enum DeviceMode {
    GameBoy,
    SuperGameBoy,
    GameBoyColor,
}

pub struct Emulator<F> {
    pub mem: Memory,
    cpu: Cpu,
    cycles: i32,
    extern_fn: F,
}

impl<F> Emulator<F> where F: FnMut(&mut Cpu, &mut Memory) {
    pub fn new(extern_fn: F) -> Emulator<F> {
        Emulator {
            mem: Memory::new(),
            cpu: Cpu::new(),
            cycles: 0,
            extern_fn: extern_fn,
        }
    }

    pub fn load_cart(&mut self, data: &[u8]) {
        for (i, chunk) in data.chunks(0x4000).enumerate() {
            copy_memory(&mut self.mem.rom[i], chunk);
        }
    }

    pub fn start(&mut self) {
        self.cpu.start_up();
        self.mem.start_up(DeviceMode::GameBoy);
    }

    /// Run the emulator for one frame
    pub fn frame(&mut self) {
        if self.mem.crashed | self.cpu.crashed {
            return;
        }

        while self.cycles <= graphics::timings::FULL_FRAME as i32 {
            (self.extern_fn)(&mut self.cpu, &mut self.mem);

            let instruction_time = self.cpu.step(&mut self.mem);
            timer::step(&mut self.mem, instruction_time);
            graphics::step(&mut self.mem, instruction_time);
            self.cycles += instruction_time as i32;
        }
        self.cycles -= graphics::timings::FULL_FRAME as i32;
    }

    /// Returns the internal display
    pub fn display(&mut self) -> &[u8] {
        &self.mem.gpu.framebuffer
    }
}

<commit_msg>Allow mutable borrows to the gpu framebuffer.<commit_after>use std::slice::bytes::copy_memory;

use mmu::Memory;
use cpu::Cpu;
use graphics;
use timer;

#[deriving(Copy)]
pub enum DeviceMode {
    GameBoy,
    SuperGameBoy,
    GameBoyColor,
}

pub struct Emulator<F> {
    pub mem: Memory,
    cpu: Cpu,
    cycles: i32,
    extern_fn: F,
}

impl<F> Emulator<F> where F: FnMut(&mut Cpu, &mut Memory) {
    pub fn new(extern_fn: F) -> Emulator<F> {
        Emulator {
            mem: Memory::new(),
            cpu: Cpu::new(),
            cycles: 0,
            extern_fn: extern_fn,
        }
    }

    pub fn load_cart(&mut self, data: &[u8]) {
        for (i, chunk) in data.chunks(0x4000).enumerate() {
            copy_memory(&mut self.mem.rom[i], chunk);
        }
    }

    pub fn start(&mut self) {
        self.cpu.start_up();
        self.mem.start_up(DeviceMode::GameBoy);
    }

    /// Run the emulator for one frame
    pub fn frame(&mut self) {
        if self.mem.crashed | self.cpu.crashed {
            return;
        }

        while self.cycles <= graphics::timings::FULL_FRAME as i32 {
            (self.extern_fn)(&mut self.cpu, &mut self.mem);

            let instruction_time = self.cpu.step(&mut self.mem);
            timer::step(&mut self.mem, instruction_time);
            graphics::step(&mut self.mem, instruction_time);
            self.cycles += instruction_time as i32;
        }
        self.cycles -= graphics::timings::FULL_FRAME as i32;
    }

    /// Returns the internal display
    pub fn display(&self) -> &[u8] {
        &self.mem.gpu.framebuffer
    }

    pub fn display_mut(&mut self) -> &mut [u8] {
        &mut self.mem.gpu.framebuffer
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2015, Sam Payson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
// associated documentation files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge, publish, distribute,
// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// TODO: Remove this when things stabilize.
#![allow(dead_code)]

use encoding::Quantifier::*;

#[derive(Copy,Eq,PartialEq)]
pub enum Type {
	Int8,
	Int16,
	Int32,
	Int64,

	UInt8,
	UInt16,
	UInt32,
	UInt64,

	Fixed32,
	Fixed64,

	Float32,
	Float64,

	Bytes,
	String,

	Bool,

	Enum,

    // A `Record` is any type which is encoded as >= FirstUnused (as specified in encoding.rex).
    // The `index` field gives an index into the `depends` field of the CompleteEncoding which
    // provides encoding information for this type.
    Record{index: usize},
}

#[derive(Eq,PartialEq,Ord,PartialOrd,Copy)]
pub struct FieldID(u64);

impl Type {
	pub fn from_usize(x: usize) -> Type {
        let first_unused = 16;

		match x {
			 0 => Type::Int8,
			 1 => Type::Int16,
			 2 => Type::Int32,
			 3 => Type::Int64,

			 4 => Type::UInt8,
			 5 => Type::UInt16,
			 6 => Type::UInt32,
			 7 => Type::UInt64,

			 8 => Type::Fixed32,
			 9 => Type::Fixed64,

			10 => Type::Float32,
			11 => Type::Float64,

			12 => Type::Bytes,
			13 => Type::String,

			14 => Type::Bool,

			15 => Type::Enum,

            xx => Type::Record{index: xx - first_unused},
		}
	}
}

// The Quantifier type gives the multiplicity of a field. A Required field has exactly 1 element, an
// Optional field has 0 or 1 elements, and a Repeated field has 0 or more elements.
#[derive(Debug,Copy,PartialEq,Eq)]
pub enum Quantifier {
	Required = 0,
	Optional = 1,
	Repeated = 2,
}

#[derive(PartialEq,Eq)]
pub struct FieldEncoding {
	// Integer id of this field within its containing record.
	pub id: FieldID,

	// Name of this field in the .rex file, not used in the encoding.
	pub name: String,

	// Is this field Required, Optional (opt), or Repeated (rep)?
	pub quant: Quantifier,

	// Type of this field.
	pub typ: Type,

    // The bounds field is the product of all bounds in an array field. So for example, the field
    //
    //     1 matrix : [3][3]float32
    //
    // would have a bounds field of 3*3 = 9.
    //
    // The bounds field is not present for non-array types.
	pub bounds: Option<usize>,
}

#[derive(PartialEq,Eq)]
pub struct RecordEncoding {
	// Name of the record type in the .rex file, not used in the encoding.
	pub name: String,

	// Required fields of this record type, sorted by id.
	pub req_fields: Vec<FieldEncoding>,

	// Optional and repeated fields of this record type, sorted by id.
	pub opt_rep_fields: Vec<FieldEncoding>,
}

impl RecordEncoding {
	fn sort_fields(&mut self) {
		self.req_fields.sort_by(|a, b| a.id.cmp(&b.id));
		self.opt_rep_fields.sort_by(|a, b| a.id.cmp(&b.id));
	}
}

// A CompleteEncoding provides all of the information necessary to parse a particular record type
// (and every record type that it can contain).
#[derive(PartialEq,Eq)]
pub struct CompleteEncoding {
	// The record type that this CompleteEncoding describes.
	pub target:  RecordEncoding,

	// Encodings for all dependencies of target. If a field has a type (t >= Type::FirstUnused),
	// then a RecordEncoding for that type is at depends[t - Type::FirstUnused].
	pub depends: Vec<RecordEncoding>,
}

impl CompleteEncoding {
	pub fn sort_fields(&mut self) {
		self.target.sort_fields();

		for dep in self.depends.iter_mut() {
			dep.sort_fields();
		}
	}
}

// These are indices into COMPLETE_ENC.depends, below. See docs for that field on the
// CompleteEncoding type.
const FIELD_ENCODING_TYP:  Type = Type::Record{index: 0};
const RECORD_ENCODING_TYP: Type = Type::Record{index: 1};

lazy_static! {

	// I apologize in advance for the confusing-ness of this comment.
	//
	// Encodings for records are themselves encoded, so we need to solve the chicken/egg problem in
	// order to be able to interpret the encodings of encodings :3.
	//
	// We do this by providing a pre-decoded encoding for encodings. That's what this lovely
	// structure is.
	pub static ref COMPLETE_ENC: CompleteEncoding = CompleteEncoding {
		target: RecordEncoding {
			name: "CompleteEncoding".to_string(),
			req_fields: vec![

				FieldEncoding {
					id:     FieldID(1),
					name:   "target".to_string(),
					quant:  Required,
					typ:    RECORD_ENCODING_TYP,
					bounds: None
				},
			],

			opt_rep_fields: vec![

				FieldEncoding {
					id:     FieldID(2),
					quant:  Repeated,
					name:   "depends".to_string(),
					typ:    RECORD_ENCODING_TYP,
					bounds: None
				},
			],
		},

		depends: vec![

			RecordEncoding {
				name: "FieldEncoding".to_string(),
				req_fields: vec![

					FieldEncoding {
						id:     FieldID(1),
						name:   "id".to_string(),
						quant:  Required,
						typ:    Type::UInt64,
						bounds: None
					},

					FieldEncoding {
						id:     FieldID(2),
						name:   "name".to_string(),
						quant:  Required,
						typ:    Type::String,
						bounds: None
					},

					FieldEncoding {
						id:     FieldID(3),
						name:   "quant".to_string(),
						quant:  Required,
						typ:    Type::Enum,
						bounds: None
					},

					FieldEncoding {
						id:     FieldID(4),
						name:   "typ".to_string(),
						quant:  Required,
						typ:    Type::Enum,
						bounds: None
					},

					FieldEncoding {
						id:     FieldID(5),
						name:   "bounds".to_string(),
						quant:  Required,
						typ:    Type::UInt64,
						bounds: None
					},
				],
				opt_rep_fields: vec![]
			},

			RecordEncoding {
				name: "RecordEncoding".to_string(),
				req_fields: vec![
					FieldEncoding {
						id:     FieldID(1),
						name:   "name".to_string(),
						quant:  Required,
						typ:    Type::String,
						bounds: None
					},
				],

				opt_rep_fields: vec![
					FieldEncoding {
						id:     FieldID(2),
						name:   "req_fields".to_string(),
						quant:  Repeated,
						typ:    FIELD_ENCODING_TYP,
						bounds: None
					},

					FieldEncoding {
						id:     FieldID(3),
						name:   "opt_rep_fields".to_string(),
						quant:  Repeated,
						typ:    FIELD_ENCODING_TYP,
						bounds: None
					},
				],
			},
		],
	};
}
<commit_msg>Tabs to spaces.<commit_after>// Copyright (c) 2015, Sam Payson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
// associated documentation files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge, publish, distribute,
// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// TODO: Remove this when things stabilize.
#![allow(dead_code)]

use encoding::Quantifier::*;

#[derive(Copy,Eq,PartialEq)]
pub enum Type {
    Int8,
    Int16,
    Int32,
    Int64,

    UInt8,
    UInt16,
    UInt32,
    UInt64,

    Fixed32,
    Fixed64,

    Float32,
    Float64,

    Bytes,
    String,

    Bool,

    Enum,

    // A `Record` is any type which is encoded as >= FirstUnused (as specified in encoding.rex).
    // The `index` field gives an index into the `depends` field of the CompleteEncoding which
    // provides encoding information for this type.
    Record{index: usize},
}

#[derive(Eq,PartialEq,Ord,PartialOrd,Copy)]
pub struct FieldID(u64);

impl Type {
    pub fn from_usize(x: usize) -> Type {
        let first_unused = 16;

        match x {
             0 => Type::Int8,
             1 => Type::Int16,
             2 => Type::Int32,
             3 => Type::Int64,

             4 => Type::UInt8,
             5 => Type::UInt16,
             6 => Type::UInt32,
             7 => Type::UInt64,

             8 => Type::Fixed32,
             9 => Type::Fixed64,

            10 => Type::Float32,
            11 => Type::Float64,

            12 => Type::Bytes,
            13 => Type::String,

            14 => Type::Bool,

            15 => Type::Enum,

            xx => Type::Record{index: xx - first_unused},
        }
    }
}

// The Quantifier type gives the multiplicity of a field. A Required field has exactly 1 element, an
// Optional field has 0 or 1 elements, and a Repeated field has 0 or more elements.
#[derive(Debug,Copy,PartialEq,Eq)]
pub enum Quantifier {
    Required = 0,
    Optional = 1,
    Repeated = 2,
}

#[derive(PartialEq,Eq)]
pub struct FieldEncoding {
    // Integer id of this field within its containing record.
    pub id: FieldID,

    // Name of this field in the .rex file, not used in the encoding.
    pub name: String,

    // Is this field Required, Optional (opt), or Repeated (rep)?
    pub quant: Quantifier,

    // Type of this field.
    pub typ: Type,

    // The bounds field is the product of all bounds in an array field. So for example, the field
    //
    //     1 matrix : [3][3]float32
    //
    // would have a bounds field of 3*3 = 9.
    //
    // The bounds field is not present for non-array types.
    pub bounds: Option<usize>,
}

#[derive(PartialEq,Eq)]
pub struct RecordEncoding {
    // Name of the record type in the .rex file, not used in the encoding.
    pub name: String,

    // Required fields of this record type, sorted by id.
    pub req_fields: Vec<FieldEncoding>,

    // Optional and repeated fields of this record type, sorted by id.
    pub opt_rep_fields: Vec<FieldEncoding>,
}

impl RecordEncoding {
    fn sort_fields(&mut self) {
        self.req_fields.sort_by(|a, b| a.id.cmp(&b.id));
        self.opt_rep_fields.sort_by(|a, b| a.id.cmp(&b.id));
    }
}

// A CompleteEncoding provides all of the information necessary to parse a particular record type
// (and every record type that it can contain).
#[derive(PartialEq,Eq)]
pub struct CompleteEncoding {
    // The record type that this CompleteEncoding describes.
    pub target:  RecordEncoding,

    // Encodings for all dependencies of target. If a field has a type (t >= Type::FirstUnused),
    // then a RecordEncoding for that type is at depends[t - Type::FirstUnused].
    pub depends: Vec<RecordEncoding>,
}

impl CompleteEncoding {
    pub fn sort_fields(&mut self) {
        self.target.sort_fields();

        for dep in self.depends.iter_mut() {
            dep.sort_fields();
        }
    }
}

// These are indices into COMPLETE_ENC.depends, below. See docs for that field on the
// CompleteEncoding type.
const FIELD_ENCODING_TYP:  Type = Type::Record{index: 0};
const RECORD_ENCODING_TYP: Type = Type::Record{index: 1};

lazy_static! {

    // I apologize in advance for the confusing-ness of this comment.
    //
    // Encodings for records are themselves encoded, so we need to solve the chicken/egg problem in
    // order to be able to interpret the encodings of encodings :3.
    //
    // We do this by providing a pre-decoded encoding for encodings. That's what this lovely
    // structure is.
    pub static ref COMPLETE_ENC: CompleteEncoding = CompleteEncoding {
        target: RecordEncoding {
            name: "CompleteEncoding".to_string(),
            req_fields: vec![

                FieldEncoding {
                    id:     FieldID(1),
                    name:   "target".to_string(),
                    quant:  Required,
                    typ:    RECORD_ENCODING_TYP,
                    bounds: None
                },
            ],

            opt_rep_fields: vec![

                FieldEncoding {
                    id:     FieldID(2),
                    quant:  Repeated,
                    name:   "depends".to_string(),
                    typ:    RECORD_ENCODING_TYP,
                    bounds: None
                },
            ],
        },

        depends: vec![

            RecordEncoding {
                name: "FieldEncoding".to_string(),
                req_fields: vec![

                    FieldEncoding {
                        id:     FieldID(1),
                        name:   "id".to_string(),
                        quant:  Required,
                        typ:    Type::UInt64,
                        bounds: None
                    },

                    FieldEncoding {
                        id:     FieldID(2),
                        name:   "name".to_string(),
                        quant:  Required,
                        typ:    Type::String,
                        bounds: None
                    },

                    FieldEncoding {
                        id:     FieldID(3),
                        name:   "quant".to_string(),
                        quant:  Required,
                        typ:    Type::Enum,
                        bounds: None
                    },

                    FieldEncoding {
                        id:     FieldID(4),
                        name:   "typ".to_string(),
                        quant:  Required,
                        typ:    Type::Enum,
                        bounds: None
                    },

                    FieldEncoding {
                        id:     FieldID(5),
                        name:   "bounds".to_string(),
                        quant:  Required,
                        typ:    Type::UInt64,
                        bounds: None
                    },
                ],
                opt_rep_fields: vec![]
            },

            RecordEncoding {
                name: "RecordEncoding".to_string(),
                req_fields: vec![
                    FieldEncoding {
                        id:     FieldID(1),
                        name:   "name".to_string(),
                        quant:  Required,
                        typ:    Type::String,
                        bounds: None
                    },
                ],

                opt_rep_fields: vec![
                    FieldEncoding {
                        id:     FieldID(2),
                        name:   "req_fields".to_string(),
                        quant:  Repeated,
                        typ:    FIELD_ENCODING_TYP,
                        bounds: None
                    },

                    FieldEncoding {
                        id:     FieldID(3),
                        name:   "opt_rep_fields".to_string(),
                        quant:  Repeated,
                        typ:    FIELD_ENCODING_TYP,
                        bounds: None
                    },
                ],
            },
        ],
    };
}
<|endoftext|>


<commit_before>use scene::{BoxedScene, Scene, SceneChangeEvent, SceneName};
use engine::EngineData;
use text_renderer::TextRenderer;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::surface::Surface;
use std::io::Result;
use std::path::Path;
use uorustlibs::art::{ArtReader, Art};
use uorustlibs::hues::{HueReader, HueGroup, Hue};
use uorustlibs::color::Color as ColorTrait;
use uorustlibs::map::{MapReader, Block};

use std::io::{Error, };
use sdl2::render::{Renderer, Texture, TextureQuery};
use sdl2::rect::Rect;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;

const MAX_BLOCKS_WIDTH: usize = 1024 / 8;
const MAX_BLOCKS_HEIGHT: usize = 768 / 8;
const STEP_X: usize = MAX_BLOCKS_WIDTH / 4;
const STEP_Y: usize = MAX_BLOCKS_HEIGHT / 4;

pub struct MapScene {
    reader: Result<MapReader>,
    x: u32,
    y: u32,
    texture: Option<Texture>
}

impl MapScene {
    pub fn new<'a>(renderer: &mut Renderer, engine_data: &mut EngineData<'a>) -> BoxedScene<SceneName, EngineData<'a>> {
        let mut scene = Box::new(MapScene {
            reader: MapReader::new(&Path::new("./assets/map0.mul"), 768, 512),
            x: 0,
            y: 0,
            texture: None
        });
        scene.draw_page(renderer, engine_data);
        scene
    }

    pub fn draw_page(&mut self, renderer: &mut Renderer, engine_data: &mut EngineData) {
        let mut blocks = vec![];

        match self.reader {
            Ok(ref mut reader) => {
                for y in 0..MAX_BLOCKS_HEIGHT {
                    for x in 0..MAX_BLOCKS_WIDTH {
                        let block = reader.read_block_from_coordinates(self.x + x as u32, self.y + y as u32);
                        blocks.push(block);
                    }
                }
            },
            _ => ()
        };
        let mut surface = Surface::new(1024, 768, PixelFormatEnum::RGBA8888).unwrap();
        for y in 0..MAX_BLOCKS_HEIGHT {
            for x in 0..MAX_BLOCKS_WIDTH {
                match blocks[x + (y * MAX_BLOCKS_WIDTH)] {
                    Ok(ref block) => {
                        let block_surface = self.draw_block(block);
                        block_surface.blit(None, &mut surface, Some(Rect::new(x as i32 * 8, y as i32* 8, block_surface.width(), block_surface.height())));
                    },
                    _ => ()
                }
            }
        }
        self.texture = Some(renderer.create_texture_from_surface(&surface).unwrap());
    }

    pub fn draw_block(&self, block: &Block) -> Surface {
        let mut surface = Surface::new(8, 8, PixelFormatEnum::RGBA8888).unwrap();
        surface.with_lock_mut(|bitmap| {
            let mut read_idx = 0;

            for y in 0..8 {
                for x in 0..8 {
                    let target = (x + (y * 8));
                    let height = (block.cells[target].altitude as i16 + 128) as u8;
                    bitmap[target * 4] = 255;
                    bitmap[target * 4 + 1] = height;
                    bitmap[target * 4 + 2] = height;
                    bitmap[target * 4 + 3] = height;
                }
            };
        });
        surface
    }
}

impl<'a> Scene<SceneName, EngineData<'a>> for MapScene {
    fn render(&self, renderer: &mut Renderer, engine_data: &mut EngineData) {
        renderer.clear();
        match self.texture {
            Some(ref texture) => {
                renderer.copy(texture, None, None).unwrap();
            },
            None => ()
        };
        renderer.present();
    }

    fn handle_event(&mut self, event: &Event, renderer: &mut Renderer, engine_data: &mut EngineData) -> Option<SceneChangeEvent<SceneName>> {
        match *event {
            Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                Some(SceneChangeEvent::PopScene)
            },
            Event::KeyDown { keycode: Some(Keycode::Left), .. } => {
                if self.x >= STEP_X as u32 {
                    self.x -= STEP_X as u32;
                    self.draw_page(renderer, engine_data);
                }
                None
            },
            Event::KeyDown { keycode: Some(Keycode::Right), .. } => {
                self.x += STEP_X as u32;
                self.draw_page(renderer, engine_data);
                None
            },
            Event::KeyDown { keycode: Some(Keycode::Up), .. } => {
                if self.y >= STEP_Y as u32 {
                    self.y -= STEP_Y as u32;
                    self.draw_page(renderer, engine_data);
                }
                None
            },
            Event::KeyDown { keycode: Some(Keycode::Down), .. } => {
                self.y += STEP_Y as u32;
                self.draw_page(renderer, engine_data);
                None
            },
             _ => None
        }
    }
}
<commit_msg>Framework for different view styles<commit_after>use scene::{BoxedScene, Scene, SceneChangeEvent, SceneName};
use engine::EngineData;
use text_renderer::TextRenderer;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::surface::Surface;
use std::io::Result;
use std::path::Path;
use uorustlibs::art::{ArtReader, Art};
use uorustlibs::hues::{HueReader, HueGroup, Hue};
use uorustlibs::color::Color as ColorTrait;
use uorustlibs::map::{MapReader, Block};

use std::io::{Error, };
use sdl2::render::{Renderer, Texture, TextureQuery};
use sdl2::rect::Rect;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;

const MAX_BLOCKS_WIDTH: usize = 1024 / 8;
const MAX_BLOCKS_HEIGHT: usize = 768 / 8;
const STEP_X: usize = MAX_BLOCKS_WIDTH / 4;
const STEP_Y: usize = MAX_BLOCKS_HEIGHT / 4;

enum MapRenderMode {
    HeightMap
}

pub struct MapScene {
    map_reader: Result<MapReader>,
    x: u32,
    y: u32,
    mode: MapRenderMode,
    texture: Option<Texture>
}

pub fn draw_block(block: &Block) -> Surface {
    let mut surface = Surface::new(8, 8, PixelFormatEnum::RGBA8888).unwrap();
    surface.with_lock_mut(|bitmap| {
        let mut read_idx = 0;

        for y in 0..8 {
            for x in 0..8 {
                let target = (x + (y * 8));
                let height = (block.cells[target].altitude as i16 + 128) as u8;
                bitmap[target * 4] = 255;
                bitmap[target * 4 + 1] = height;
                bitmap[target * 4 + 2] = height;
                bitmap[target * 4 + 3] = height;
            }
        };
    });
    surface
}

pub fn draw_region<F>(blocks: &Vec<Result<Block>>, renderer: F) -> Surface
    where F: Fn(&Block) -> Surface {
    let mut surface = Surface::new(1024, 768, PixelFormatEnum::RGBA8888).unwrap();
    for y in 0..MAX_BLOCKS_HEIGHT {
        for x in 0..MAX_BLOCKS_WIDTH {
            match blocks[x + (y * MAX_BLOCKS_WIDTH)] {
                Ok(ref block) => {
                    let block_surface = renderer(block);
                    block_surface.blit(None, &mut surface, Some(Rect::new(x as i32 * 8, y as i32* 8, block_surface.width(), block_surface.height()))).unwrap();
                },
                _ => ()
            }
        }
    }
    surface
}

impl MapScene {
    pub fn new<'a>(renderer: &mut Renderer, engine_data: &mut EngineData<'a>) -> BoxedScene<SceneName, EngineData<'a>> {
        let mut scene = Box::new(MapScene {
            map_reader: MapReader::new(&Path::new("./assets/map0.mul"), 768, 512),
            x: 0,
            y: 0,
            texture: None,
            mode: MapRenderMode::HeightMap
        });
        scene.draw_page(renderer, engine_data);
        scene
    }

    pub fn get_blocks(&mut self) -> Vec<Result<Block>> {
        let mut blocks = vec![];

        match self.map_reader {
            Ok(ref mut map_reader) => {
                for y in 0..MAX_BLOCKS_HEIGHT {
                    for x in 0..MAX_BLOCKS_WIDTH {
                        let block = map_reader.read_block_from_coordinates(self.x + x as u32, self.y + y as u32);
                        blocks.push(block);
                    }
                }
            },
            _ => ()
        };
        blocks
    }

    pub fn draw_page(&mut self, renderer: &mut Renderer, engine_data: &mut EngineData) {
        let blocks = self.get_blocks();
        let block_drawer = match self.mode {
            MapRenderMode::HeightMap => draw_block
        };
        let surface = draw_region(&blocks, block_drawer);
        self.texture = Some(renderer.create_texture_from_surface(&surface).unwrap())
    }
}

impl<'a> Scene<SceneName, EngineData<'a>> for MapScene {
    fn render(&self, renderer: &mut Renderer, engine_data: &mut EngineData) {
        renderer.clear();
        match self.texture {
            Some(ref texture) => {
                renderer.copy(texture, None, None).unwrap();
            },
            None => ()
        };
        renderer.present();
    }

    fn handle_event(&mut self, event: &Event, renderer: &mut Renderer, engine_data: &mut EngineData) -> Option<SceneChangeEvent<SceneName>> {
        match *event {
            Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                Some(SceneChangeEvent::PopScene)
            },
            Event::KeyDown { keycode: Some(Keycode::Left), .. } => {
                if self.x >= STEP_X as u32 {
                    self.x -= STEP_X as u32;
                    self.draw_page(renderer, engine_data);
                }
                None
            },
            Event::KeyDown { keycode: Some(Keycode::Right), .. } => {
                self.x += STEP_X as u32;
                self.draw_page(renderer, engine_data);
                None
            },
            Event::KeyDown { keycode: Some(Keycode::Up), .. } => {
                if self.y >= STEP_Y as u32 {
                    self.y -= STEP_Y as u32;
                    self.draw_page(renderer, engine_data);
                }
                None
            },
            Event::KeyDown { keycode: Some(Keycode::Down), .. } => {
                self.y += STEP_Y as u32;
                self.draw_page(renderer, engine_data);
                None
            },
            Event::KeyDown { keycode: Some(Keycode::Num1), .. } => {
                self.mode = MapRenderMode::HeightMap;
                self.draw_page(renderer, engine_data);
                None
            },
             _ => None
        }
    }
}
<|endoftext|>


<commit_before>use super::moves::Plies;
use super::square::{File, Rank, Square};
use super::pos::{Position, Kingside, Queenside};
use super::piece;
use super::color::Color;

use std::collections::HashMap;

pub fn fen_to_position(fen: &str) -> Result<Position, &str> {
    let fields: Vec<&str> = fen.split(' ').collect();
    if fields.len() < 6 {
        return Err("Not enough fields in FEN input.");
    };
    let mut pos_str = "".to_string();
    for ch in fields[0].chars() {
        match ch {
            '0' ... '9' => {
                for _ in range(0, ch as uint - '0' as uint) {
                    pos_str.push('1')
                }
            }
            _ => pos_str.push(ch)
        }
    }
    let mut pos = Position::new();
    let (mut rank, mut file) = (7, 0);
    let mut decode = HashMap::new();
    decode.insert('P', piece::WP);
    decode.insert('K', piece::WK);
    decode.insert('Q', piece::WQ);
    decode.insert('B', piece::WB);
    decode.insert('N', piece::WN);
    decode.insert('R', piece::WR);
    decode.insert('p', piece::BP);
    decode.insert('k', piece::BK);
    decode.insert('q', piece::BQ);
    decode.insert('b', piece::BB);
    decode.insert('n', piece::BN);
    decode.insert('r', piece::BR);
    for ch in fields[0].chars() {
        if ch == '/' {
            rank = rank - 1;
            file = 0;
        } else {
            match decode.get(&ch) {
                None => return Err("Unexpected charactor found."),
                Some(val) => {
                    pos.set_at_mut(Square::new(File(file),Rank(rank)), *val);
                    file = file + 1;
                }
            }
        }
    }
    let side_to_move = fields[1].char_at(0);
    match side_to_move {
        'w' => pos.set_side_to_move_mut(Color::White),
        'b' => pos.set_side_to_move_mut(Color::Black),
        _ => return Err("Invalid side to move."),
    };
    let castle = fields[2];
    pos.set_castle_mut(Kingside,  Color::White, castle.char_at(0) == 'K');
    pos.set_castle_mut(Queenside, Color::White, castle.char_at(1) == 'Q');
    pos.set_castle_mut(Kingside,  Color::Black, castle.char_at(2) == 'k');
    pos.set_castle_mut(Queenside, Color::Black, castle.char_at(3) == 'q');
    let en_passant_char = fields[3].char_at(0);
    if en_passant_char != '-' {
        pos.set_en_passant_mut(Some(File(en_passant_char as u8 - 'a' as u8)));
    }
    match fields[4].parse::<u8>() {
        None => return Err("Invalid number of plies."),
        Some(val) => pos.set_ply_count_mut(Plies(val)),
    }
    Ok(pos)
}
<commit_msg>Add "start_pos()"<commit_after>use super::moves::Plies;
use super::square::{File, Rank, Square};
use super::pos::{Position, Kingside, Queenside};
use super::piece;
use super::color::Color;

use std::collections::HashMap;

pub fn start_pos() -> Position {
    fen_to_position("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1").unwrap()
}

pub fn fen_to_position(fen: &str) -> Result<Position, &str> {
    let fields: Vec<&str> = fen.split(' ').collect();
    if fields.len() < 6 {
        return Err("Not enough fields in FEN input.");
    };
    let mut pos_str = "".to_string();
    for ch in fields[0].chars() {
        match ch {
            '0' ... '9' => {
                for _ in range(0, ch as uint - '0' as uint) {
                    pos_str.push('1')
                }
            }
            _ => pos_str.push(ch)
        }
    }
    let mut pos = Position::new();
    let (mut rank, mut file) = (7, 0);
    let mut decode = HashMap::new();
    decode.insert('P', piece::WP);
    decode.insert('K', piece::WK);
    decode.insert('Q', piece::WQ);
    decode.insert('B', piece::WB);
    decode.insert('N', piece::WN);
    decode.insert('R', piece::WR);
    decode.insert('p', piece::BP);
    decode.insert('k', piece::BK);
    decode.insert('q', piece::BQ);
    decode.insert('b', piece::BB);
    decode.insert('n', piece::BN);
    decode.insert('r', piece::BR);
    for ch in fields[0].chars() {
        if ch == '/' {
            rank = rank - 1;
            file = 0;
        } else {
            match decode.get(&ch) {
                None => return Err("Unexpected charactor found."),
                Some(val) => {
                    pos.set_at_mut(Square::new(File(file),Rank(rank)), *val);
                    file = file + 1;
                }
            }
        }
    }
    let side_to_move = fields[1].char_at(0);
    match side_to_move {
        'w' => pos.set_side_to_move_mut(Color::White),
        'b' => pos.set_side_to_move_mut(Color::Black),
        _ => return Err("Invalid side to move."),
    };
    let castle = fields[2];
    pos.set_castle_mut(Kingside,  Color::White, castle.char_at(0) == 'K');
    pos.set_castle_mut(Queenside, Color::White, castle.char_at(1) == 'Q');
    pos.set_castle_mut(Kingside,  Color::Black, castle.char_at(2) == 'k');
    pos.set_castle_mut(Queenside, Color::Black, castle.char_at(3) == 'q');
    let en_passant_char = fields[3].char_at(0);
    if en_passant_char != '-' {
        pos.set_en_passant_mut(Some(File(en_passant_char as u8 - 'a' as u8)));
    }
    match fields[4].parse::<u8>() {
        None => return Err("Invalid number of plies."),
        Some(val) => pos.set_ply_count_mut(Plies(val)),
    }
    Ok(pos)
}
<|endoftext|>


<commit_before>use super::{GroundMaterial, HeightType};
use prop;

/// Represents one pillar of hexgonal shape in the game world.
///
/// A pillar consists of multiple sections (each of which has a material) and
/// optionally props (plants, objects, ...).
#[derive(Clone, Default, Debug)]
pub struct HexPillar {
    sections: Vec<PillarSection>,
    props: Vec<Prop>,
}

impl HexPillar {
    /// Creates a dummy pillar for early testing. FIXME: remove
    pub fn dummy() -> Self {
        HexPillar {
            sections: vec![PillarSection::new(GroundMaterial::Dirt, HeightType(0), HeightType(50))],
            props: vec![],
        }
    }

    /// Returns a slice of this pillar's sections.
    pub fn sections(&self) -> &[PillarSection] {
        &self.sections
    }

    /// Returns a slice of this pillar's props.
    pub fn props(&self) -> &[Prop] {
        &self.props
    }
}

/// Represents one section of a hex pillar.
#[derive(Clone, Debug)]
pub struct PillarSection {
    pub ground: GroundMaterial,
    pub bottom: HeightType,
    pub top: HeightType,
}

impl PillarSection {
    /// Creates a new pillar section and asserts `bottom < top`.
    pub fn new(ground: GroundMaterial, bottom: HeightType, top: HeightType) -> Self {
        assert!(bottom < top, "attempt to create an invalid pillar section");

        PillarSection {
            ground: ground,
            bottom: bottom,
            top: top,
        }
    }
}

/// A prop in a hex pillar
#[derive(Clone, Debug)]
pub struct Prop {
    /// The height/baseline at which the prop starts
    pub baseline: HeightType,
    /// The actual prop data
    pub prop: PropType,
}

/// Represents one of many different prop types
#[derive(Clone, Debug)]
pub enum PropType {
    Plant(prop::Plant),
}
<commit_msg>Add a plant to the dummy hex pillar (for testing)<commit_after>use super::{GroundMaterial, HeightType};
use prop;

/// Represents one pillar of hexgonal shape in the game world.
///
/// A pillar consists of multiple sections (each of which has a material) and
/// optionally props (plants, objects, ...).
#[derive(Clone, Default, Debug)]
pub struct HexPillar {
    sections: Vec<PillarSection>,
    props: Vec<Prop>,
}

impl HexPillar {
    /// Creates a dummy pillar for early testing. FIXME: remove
    pub fn dummy() -> Self {
        HexPillar {
            sections: vec![PillarSection::new(GroundMaterial::Dirt, HeightType(0), HeightType(50))],
            props: vec![Prop {
                            baseline: HeightType(50),
                            prop: PropType::Plant(prop::Plant {
                                height: 5.0,
                                stem_width: 0.5,
                            }),
                        }],
        }
    }

    /// Returns a slice of this pillar's sections.
    pub fn sections(&self) -> &[PillarSection] {
        &self.sections
    }

    /// Returns a slice of this pillar's props.
    pub fn props(&self) -> &[Prop] {
        &self.props
    }
}

/// Represents one section of a hex pillar.
#[derive(Clone, Debug)]
pub struct PillarSection {
    pub ground: GroundMaterial,
    pub bottom: HeightType,
    pub top: HeightType,
}

impl PillarSection {
    /// Creates a new pillar section and asserts `bottom < top`.
    pub fn new(ground: GroundMaterial, bottom: HeightType, top: HeightType) -> Self {
        assert!(bottom < top, "attempt to create an invalid pillar section");

        PillarSection {
            ground: ground,
            bottom: bottom,
            top: top,
        }
    }
}

/// A prop in a hex pillar
#[derive(Clone, Debug)]
pub struct Prop {
    /// The height/baseline at which the prop starts
    pub baseline: HeightType,
    /// The actual prop data
    pub prop: PropType,
}

/// Represents one of many different prop types
#[derive(Clone, Debug)]
pub enum PropType {
    Plant(prop::Plant),
}
<|endoftext|>


<commit_before>use card;
use std::fmt;

mod tests;

pub struct Hand {
    pub cards: Vec<card::Card>
}

impl Hand {
    pub fn new(mut cards: Vec<card::Card>) -> Hand {
        cards.sort();
        Hand {
            cards: cards
        }
    }

    pub fn has_flush(&self) -> bool {
        let suit: card::Suit = self.cards.get(0).unwrap().suit.clone();
        for card in &self.cards {
            if card.suit != suit {
                return false
            }
        }
        true
    }
}

impl fmt::Display for Hand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {} {} {} {}", self.cards.get(0).unwrap(),
                                    self.cards.get(1).unwrap(),
                                    self.cards.get(2).unwrap(),
                                    self.cards.get(3).unwrap(),
                                    self.cards.get(4).unwrap())
    }
}

#[derive(Debug, PartialEq)]
pub enum PokerHand {
    HighCard      = 0,
    OnePair       = 1,
    TwoPair       = 2,
    Trips         = 3,
    Straight      = 4,
    Flush         = 5,
    FullHouse     = 6,
    Quads         = 7,
    StraightFlush = 8,
}
<commit_msg>Redefined PokerHand enum<commit_after>use card;
use std::fmt;

mod tests;

pub struct Hand {
    pub cards: Vec<card::Card>
}

impl Hand {
    pub fn new(mut cards: Vec<card::Card>) -> Hand {
        cards.sort();
        Hand {
            cards: cards
        }
    }

    pub fn has_flush(&self) -> bool {
        let suit: card::Suit = self.cards.get(0).unwrap().suit.clone();
        for card in &self.cards {
            if card.suit != suit {
                return false
            }
        }
        true
    }
}

impl fmt::Display for Hand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {} {} {} {}", self.cards.get(0).unwrap(),
                                    self.cards.get(1).unwrap(),
                                    self.cards.get(2).unwrap(),
                                    self.cards.get(3).unwrap(),
                                    self.cards.get(4).unwrap())
    }
}

#[derive(Debug, PartialEq)]
pub enum PokerHand {
    HighCard((card::Card)),
    OnePair((card::Card, card::Card)),
    TwoPair((card::Card, card::Card), (card::Card)),
    Trips((card::Card, card::Card, card::Card)),
    Straight((card::Card, card::Card, card::Card, card::Card, card::Card)),
    Flush((card::Card, card::Card, card::Card, card::Card, card::Card)),
    FullHouse((card::Card, card::Card, card::Card), (card::Card, card::Card)),
    Quads((card::Card, card::Card, card::Card, card::Card)),
    StraightFlush((card::Card, card::Card, card::Card, card::Card, card::Card)),
}

impl PokerHand {
    fn raw_value(&self) -> u32 {
        match *self {
            PokerHand::HighCard(_) => 0,
            PokerHand::OnePair(_) => 1,
            PokerHand::TwoPair(_, _) => 2,
            PokerHand::Trips(_) => 3,
            PokerHand::Straight(_) => 4,
            PokerHand::Flush(_) => 5,
            PokerHand::FullHouse(_, _) => 6,
            PokerHand::Quads(_) => 7,
            PokerHand::StraightFlush(_) => 8,
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2016 Élisabeth HENRY.
//
// This file is part of Crowbook.
//
// Crowbook is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received ba copy of the GNU Lesser General Public License
// along with Crowbook.  If not, see <http://www.gnu.org/licenses/>.

use escape::escape_html;
use token::Token;
use book::Book;
use number::Number;
use error::Result;
use toc::Toc;
use resource_handler::ResourceHandler;
use std::borrow::Cow;
use templates::html;

use mustache;
use rustc_serialize::base64::{self, ToBase64};

/// Renders HTML document in a standalone file.
///
/// Also used by `EpubRenderer` and `HtmlDirRenderer`.
#[derive(Debug)]
pub struct HtmlRenderer<'a> {
    book: &'a Book,
    table_head: bool,
    footnote_number: u32,
    epub3: bool,
    verbatim: bool,
    link_number: u32,

    // fields used by EpubRenderer so marked public but hidden
    #[doc(hidden)]
    pub toc: Toc,
    #[doc(hidden)]
    pub footnotes: Vec<(String, String)>,
    #[doc(hidden)]
    pub current_chapter: [i32;6],
    #[doc(hidden)]
    pub current_numbering: i32,
    #[doc(hidden)]
    pub current_hide: bool,
    #[doc(hidden)]
    pub filename: String,
    #[doc(hidden)]
    pub handler: ResourceHandler<'a>,
}

impl<'a> HtmlRenderer<'a> {
    /// Creates a new HTML renderer
    pub fn new(book: &'a Book) -> HtmlRenderer<'a> {
        let mut html = HtmlRenderer {
            book: book,
            toc: Toc::new(),
            link_number: 0,
            current_chapter: [0, 0, 0, 0, 0, 0],
            current_numbering: book.options.get_i32("numbering").unwrap(),
            current_hide: false,
            table_head: false,
            footnote_number: 0,
            footnotes: vec!(),
            epub3: false,
            verbatim: false,
            filename: String::new(),
            handler: ResourceHandler::new(&book.logger),
        };
        html.handler.set_images_mapping(true);
        html.handler.set_base64(true);
        html
    }

    /// Render books as a standalone HTML file
    pub fn render_book(&mut self) -> Result<String> {
        let menu_svg = html::MENU_SVG.to_base64(base64::STANDARD);
        let menu_svg = format!("data:image/svg+xml;base64,{}", menu_svg);

        for (i, filename) in self.book.filenames.iter().enumerate() {
            self.handler.add_link(filename.clone(), format!("#chapter-{}", i));
        }
        let mut content = String::new();

        let mut titles = vec!();
        let mut chapters = vec!();

        for (i, &(n, ref v)) in self.book.chapters.iter().enumerate() {
            self.current_hide = false;
            let book_numbering = self.book.options.get_i32("numbering").unwrap();
            match n {
                Number::Unnumbered => self.current_numbering = 0,
                Number::Default => self.current_numbering = book_numbering,
                Number::Specified(n) => {
                    self.current_numbering = book_numbering;
                    self.current_chapter[0] = n - 1;
                },
                Number::Hidden => {
                    self.current_numbering = 0;
                    self.current_hide = true;
                },
            }

            let mut title = String::new();
            for token in v {
                match *token {
                    Token::Header(1, ref vec) => {
                        if self.current_hide || self.current_numbering == 0 {
                            title = self.render_vec(vec);
                        } else {
                            title = try!(self.book.get_header(
                                self.current_chapter[0] + 1,
                                &self.render_vec(vec)));
                        }
                        break;
                    },
                    _ => {
                        continue;
                    }
                }
            }
            titles.push(title);

            chapters.push(format!(
                "

  {}

",
                i,
                self.render_html(v)));
        }

        for (i, chapter) in chapters.iter().enumerate() {
            if i != 0 {
                content.push_str(&format!(
                    "

  « {}

",
                    i - 1,
                    i,
                    i - 1,
                    titles[i -1]));
            }
            content.push_str(chapter);
            if i < titles.len() - 1 {
                content.push_str(&format!(
                    "

  {} »

",
                    i + 1,
                    i,
                    i + 1,
                    titles[i + 1]));
            }
        }

        let toc = self.toc.render();

        // If display_toc, display the toc inline
        if self.book.options.get_bool("display_toc").unwrap() {
            content = format!(
                "
{}

{}

{}",
                self.book.options.get_str("toc_name").unwrap(),
                &toc,
                content);
        }

        // Render the CSS
        let template_css = mustache::compile_str(try!(self.book.get_template("html.css")).as_ref());
        let data = self.book.get_mapbuilder("none")
            .insert_bool(self.book.options.get_str("lang").unwrap(), true)
            .build();
        let mut res:Vec<u8> = vec!();
        template_css.render_data(&mut res, &data);
        let css = String::from_utf8_lossy(&res);

        // Render the HTML document
        let data = self.book.get_mapbuilder("none")
            .insert_str("content", content)
            .insert_str("toc", toc)
            .insert_str("script", self.book.get_template("html.script").unwrap())
            .insert_bool(self.book.options.get_str("lang").unwrap(), true)
            .insert_str("style", css.as_ref())
            .insert_str("menu_svg", menu_svg)
            .build();
        let template = mustache::compile_str(try!(self.book.get_template("html.template")).as_ref());
        let mut res = vec!();
        template.render_data(&mut res, &data);
        Ok(String::from_utf8_lossy(&res).into_owned())
    }

    /// Renders a chapter to HTML
    pub fn render_html(&mut self, tokens: &[Token])-> String {
        let mut res = String::new();
        for token in tokens {
            res.push_str(&self.parse_token(&token));
            self.render_side_notes(&mut res);
        }
        self.render_end_notes(&mut res);
        res
    }

    /// Increase a header
    fn inc_header(&mut self, n: i32) {
        let n = n as usize;
        assert!(n < self.current_chapter.len());
        self.current_chapter[n] += 1;
        for i in n+1..self.current_chapter.len() {
            self.current_chapter[i] = 0;
        }
    }

    /// Returns a "x.y.z"
    fn get_numbers(&self) -> String {
        let mut output = String::new();
        for i in 0..self.current_chapter.len() {
            if self.current_chapter[i] == 0 {
                if i == self.current_chapter.len() - 1 {
                    break;
                }
                let bools:Vec<_> = self.current_chapter[i+1..].iter().map(|x| *x != 0).collect();
                if !bools.contains(&true) {
                    break;
                }
            }
            output.push_str(&format!("{}.", self.current_chapter[i])); //todo
        }
        output
    }

    /// Display side notes if option is to true
    ///
    /// Only public because EpubRenderer uses it
    #[doc(hidden)]
    pub fn render_side_notes(&mut self, res: &mut String) {
        if self.book.options.get_bool("side_notes").unwrap() {
            for (note_number, footnote) in self.footnotes.drain(..) {
                res.push_str(&format!("
\n{} {}\n
\n", note_number, footnote));
            }
        }
    }

    /// Display end notes, if side_notes option is set to false
    ///
    /// Only public because EpubRenderer uses it
    #[doc(hidden)]
    pub fn render_end_notes(&mut self, res: &mut String) {
        if !self.footnotes.is_empty() {
            res.push_str("
Notes
");
            res.push_str("
");
            for (note_number, footnote) in self.footnotes.drain(..) {
                res.push_str(&format!("
{}	{}
\n", note_number, footnote));
            }
            res.push_str("
");
        }
    }

    /// Transform a vector of `Token`s to HTML format.
    ///
    /// Only public becauses `EpubRenderer` uses it
    #[doc(hidden)]
    pub fn render_vec(&mut self, tokens: &[Token]) -> String {
        let mut res = String::new();

        for token in tokens {
            res.push_str(&self.parse_token(&token));
        }
        res
    }

    /// Parse a single token.
    ///
    /// Only public because EpubRenderer uses it
    #[doc(hidden)]
    pub fn parse_token(&mut self, token: &Token) -> String {
        match *token {
            Token::Str(ref text) => if self.verbatim {
                escape_html(text)
            } else {
                escape_html(&self.book.clean(text.clone()))
            },
            Token::Paragraph(ref vec) => format!("
{}
\n", self.render_vec(vec)),
            Token::Header(n, ref vec) => {
                if self.current_numbering >= n {
                    self.inc_header(n - 1);
                }
                self.link_number += 1;
                let s = if n == 1 && self.current_numbering >= 1 {
                    let chapter = self.current_chapter[0];
                    self.book.get_header(chapter, &self.render_vec(vec)).unwrap()
                } else if self.current_numbering >= n {
                    format!("{} {}", self.get_numbers(), self.render_vec(vec))
                } else {
                    self.render_vec(vec)
                };
                if n <= self.book.options.get_i32("numbering").unwrap() {
                    self.toc.add(n,
                                 format!("{}#link-{}",
                                            self.filename,
                                            self.link_number),
                                 s.clone());
                }
                if n == 1 && self.current_hide {
                    format!("", self.link_number)
                } else {
                    format!("<h{} id = \"link-{}\">{}</h{}>\n",
                            n, self.link_number, s, n)
                }
            },
            Token::Emphasis(ref vec) => format!("{}", self.render_vec(vec)),
            Token::Strong(ref vec) => format!("{}", self.render_vec(vec)),
            Token::Code(ref vec) => format!("{}", self.render_vec(vec)),
            Token::BlockQuote(ref vec) => format!("
{}
\n", self.render_vec(vec)),
            Token::CodeBlock(ref language, ref vec) => {
                self.verbatim = true;
                let s = self.render_vec(vec);
                let output = if language.is_empty() {
                    format!("
{}
\n", s)
                } else {
                    format!("
{}
\n", language, s)
                };
                self.verbatim = false;
                output
            },
            Token::Rule => String::from("
***
\n"),
            Token::SoftBreak => String::from(" "),
            Token::HardBreak => String::from("
\n"),
            Token::List(ref vec) => format!("
\n{}
\n", self.render_vec(vec)),
            Token::OrderedList(n, ref vec) => format!("
\n{}
\n",
                                                      if n == 1 {
                                                          String::new()
                                                      } else {
                                                          format!(" start = \"{}\"", n)
                                                      },
                                                      self.render_vec(vec)),
            Token::Item(ref vec) => format!("
{}
\n", self.render_vec(vec)),
            Token::Link(ref url, ref title, ref vec) => {
                let url: String = if ResourceHandler::is_local(url) {
                    self.handler.get_link(url).to_owned()
                } else {
                    url.clone()
                };

                format!("{}", url,
                        if title.is_empty() {
                            String::new()
                        } else {
                            format!(" title = \"{}\"", title)
                        },
                        self.render_vec(vec))
            },
            Token::Image(ref url, ref title, ref alt) => {
                let content = self.render_vec(alt);
                let url = self.handler.map_image(Cow::Borrowed(url));
                format!("",
                        url,
                        title,
                        content)
            },
            Token::Table(_, ref vec) => format!("

\n{}

\n", self.render_vec(vec)),
            Token::TableRow(ref vec) => format!("
\n{}
\n", self.render_vec(vec)),
            Token::TableCell(ref vec) => {
                let tag = if self.table_head {"th"} else {"td"};
                format!("<{}>{}</{}>", tag, self.render_vec(vec), tag)
            },
            Token::TableHead(ref vec) => {
                self.table_head = true;
                let s = self.render_vec(vec);
                self.table_head = false;
                format!("
\n{}
\n", s)
            },
            Token::Footnote(ref vec) => {
                self.footnote_number += 1;
                let number = self.footnote_number;
                assert!(!vec.is_empty());

                let note_number = format!("

  [{}]

", number, number);

                let inner = format!("{}",
                                    if self.epub3 {r#"epub:type="footnote"#}else{""},
                                    number, self.render_vec(vec));
                self.footnotes.push((note_number, inner));

                format!("{}",
                        if self.epub3 {"epub:type = \"noteref\""} else {""},
                        number, number, number)
            },
        }
    }
}

<commit_msg>Fix javascript links in navigation bar<commit_after>// Copyright (C) 2016 Élisabeth HENRY.
//
// This file is part of Crowbook.
//
// Crowbook is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received ba copy of the GNU Lesser General Public License
// along with Crowbook.  If not, see <http://www.gnu.org/licenses/>.

use escape::escape_html;
use token::Token;
use book::Book;
use number::Number;
use error::Result;
use toc::Toc;
use resource_handler::ResourceHandler;
use std::borrow::Cow;
use templates::html;

use mustache;
use rustc_serialize::base64::{self, ToBase64};

/// Renders HTML document in a standalone file.
///
/// Also used by `EpubRenderer` and `HtmlDirRenderer`.
#[derive(Debug)]
pub struct HtmlRenderer<'a> {
    book: &'a Book,
    table_head: bool,
    footnote_number: u32,
    epub3: bool,
    verbatim: bool,
    link_number: u32,
    add_script: bool,

    // fields used by EpubRenderer so marked public but hidden
    #[doc(hidden)]
    pub toc: Toc,
    #[doc(hidden)]
    pub footnotes: Vec<(String, String)>,
    #[doc(hidden)]
    pub current_chapter: [i32;6],
    #[doc(hidden)]
    pub current_numbering: i32,
    #[doc(hidden)]
    pub current_hide: bool,
    #[doc(hidden)]
    pub filename: String,
    #[doc(hidden)]
    pub handler: ResourceHandler<'a>,
}

impl<'a> HtmlRenderer<'a> {
    /// Creates a new HTML renderer
    pub fn new(book: &'a Book) -> HtmlRenderer<'a> {
        let mut html = HtmlRenderer {
            book: book,
            toc: Toc::new(),
            link_number: 0,
            current_chapter: [0, 0, 0, 0, 0, 0],
            current_numbering: book.options.get_i32("numbering").unwrap(),
            add_script: false,
            current_hide: false,
            table_head: false,
            footnote_number: 0,
            footnotes: vec!(),
            epub3: false,
            verbatim: false,
            filename: String::new(),
            handler: ResourceHandler::new(&book.logger),
        };
        html.handler.set_images_mapping(true);
        html.handler.set_base64(true);
        html
    }

    /// Render books as a standalone HTML file
    pub fn render_book(&mut self) -> Result<String> {
        self.add_script = true;
        let menu_svg = html::MENU_SVG.to_base64(base64::STANDARD);
        let menu_svg = format!("data:image/svg+xml;base64,{}", menu_svg);

        for (i, filename) in self.book.filenames.iter().enumerate() {
            self.handler.add_link(filename.clone(), format!("#chapter-{}", i));
        }
        let mut content = String::new();

        let mut titles = vec!();
        let mut chapters = vec!();

        for (i, &(n, ref v)) in self.book.chapters.iter().enumerate() {
            self.current_hide = false;
            let book_numbering = self.book.options.get_i32("numbering").unwrap();
            match n {
                Number::Unnumbered => self.current_numbering = 0,
                Number::Default => self.current_numbering = book_numbering,
                Number::Specified(n) => {
                    self.current_numbering = book_numbering;
                    self.current_chapter[0] = n - 1;
                },
                Number::Hidden => {
                    self.current_numbering = 0;
                    self.current_hide = true;
                },
            }

            let mut title = String::new();
            for token in v {
                match *token {
                    Token::Header(1, ref vec) => {
                        if self.current_hide || self.current_numbering == 0 {
                            title = self.render_vec(vec);
                        } else {
                            title = try!(self.book.get_header(
                                self.current_chapter[0] + 1,
                                &self.render_vec(vec)));
                        }
                        break;
                    },
                    _ => {
                        continue;
                    }
                }
            }
            titles.push(title);

            chapters.push(format!(
                "

  {}

",
                i,
                self.render_html(v)));
        }

        for (i, chapter) in chapters.iter().enumerate() {
            if i != 0 {
                content.push_str(&format!(
                    "

  « {}

",
                    i - 1,
                    i,
                    i - 1,
                    titles[i -1]));
            }
            content.push_str(chapter);
            if i < titles.len() - 1 {
                content.push_str(&format!(
                    "

  {} »

",
                    i + 1,
                    i,
                    i + 1,
                    titles[i + 1]));
            }
        }

        let toc = self.toc.render();

        // If display_toc, display the toc inline
        if self.book.options.get_bool("display_toc").unwrap() {
            content = format!(
                "
{}

{}

{}",
                self.book.options.get_str("toc_name").unwrap(),
                &toc,
                content);
        }

        // Render the CSS
        let template_css = mustache::compile_str(try!(self.book.get_template("html.css")).as_ref());
        let data = self.book.get_mapbuilder("none")
            .insert_bool(self.book.options.get_str("lang").unwrap(), true)
            .build();
        let mut res:Vec<u8> = vec!();
        template_css.render_data(&mut res, &data);
        let css = String::from_utf8_lossy(&res);

        // Render the HTML document
        let data = self.book.get_mapbuilder("none")
            .insert_str("content", content)
            .insert_str("toc", toc)
            .insert_str("script", self.book.get_template("html.script").unwrap())
            .insert_bool(self.book.options.get_str("lang").unwrap(), true)
            .insert_str("style", css.as_ref())
            .insert_str("menu_svg", menu_svg)
            .build();
        let template = mustache::compile_str(try!(self.book.get_template("html.template")).as_ref());
        let mut res = vec!();
        template.render_data(&mut res, &data);
        Ok(String::from_utf8_lossy(&res).into_owned())
    }

    /// Renders a chapter to HTML
    pub fn render_html(&mut self, tokens: &[Token])-> String {
        let mut res = String::new();
        for token in tokens {
            res.push_str(&self.parse_token(&token));
            self.render_side_notes(&mut res);
        }
        self.render_end_notes(&mut res);
        res
    }

    /// Increase a header
    fn inc_header(&mut self, n: i32) {
        let n = n as usize;
        assert!(n < self.current_chapter.len());
        self.current_chapter[n] += 1;
        for i in n+1..self.current_chapter.len() {
            self.current_chapter[i] = 0;
        }
    }

    /// Returns a "x.y.z"
    fn get_numbers(&self) -> String {
        let mut output = String::new();
        for i in 0..self.current_chapter.len() {
            if self.current_chapter[i] == 0 {
                if i == self.current_chapter.len() - 1 {
                    break;
                }
                let bools:Vec<_> = self.current_chapter[i+1..].iter().map(|x| *x != 0).collect();
                if !bools.contains(&true) {
                    break;
                }
            }
            output.push_str(&format!("{}.", self.current_chapter[i])); //todo
        }
        output
    }

    /// Display side notes if option is to true
    ///
    /// Only public because EpubRenderer uses it
    #[doc(hidden)]
    pub fn render_side_notes(&mut self, res: &mut String) {
        if self.book.options.get_bool("side_notes").unwrap() {
            for (note_number, footnote) in self.footnotes.drain(..) {
                res.push_str(&format!("
\n{} {}\n
\n", note_number, footnote));
            }
        }
    }

    /// Display end notes, if side_notes option is set to false
    ///
    /// Only public because EpubRenderer uses it
    #[doc(hidden)]
    pub fn render_end_notes(&mut self, res: &mut String) {
        if !self.footnotes.is_empty() {
            res.push_str("
Notes
");
            res.push_str("
");
            for (note_number, footnote) in self.footnotes.drain(..) {
                res.push_str(&format!("
{}	{}
\n", note_number, footnote));
            }
            res.push_str("
");
        }
    }

    /// Transform a vector of `Token`s to HTML format.
    ///
    /// Only public becauses `EpubRenderer` uses it
    #[doc(hidden)]
    pub fn render_vec(&mut self, tokens: &[Token]) -> String {
        let mut res = String::new();

        for token in tokens {
            res.push_str(&self.parse_token(&token));
        }
        res
    }

    /// Parse a single token.
    ///
    /// Only public because EpubRenderer uses it
    #[doc(hidden)]
    pub fn parse_token(&mut self, token: &Token) -> String {
        match *token {
            Token::Str(ref text) => if self.verbatim {
                escape_html(text)
            } else {
                escape_html(&self.book.clean(text.clone()))
            },
            Token::Paragraph(ref vec) => format!("
{}
\n", self.render_vec(vec)),
            Token::Header(n, ref vec) => {
                if self.current_numbering >= n {
                    self.inc_header(n - 1);
                }
                self.link_number += 1;
                let s = if n == 1 && self.current_numbering >= 1 {
                    let chapter = self.current_chapter[0];
                    self.book.get_header(chapter, &self.render_vec(vec)).unwrap()
                } else if self.current_numbering >= n {
                    format!("{} {}", self.get_numbers(), self.render_vec(vec))
                } else {
                    self.render_vec(vec)
                };
                if n <= self.book.options.get_i32("numbering").unwrap() {
                    if self.add_script {
                        self.toc.add(n,
                                     format!("{}#link-{}\" onclick = \"javascript:showChapter({})",
                                             self.filename,
                                             self.link_number,
                                             self.current_chapter[0] - 1
                                             ),
                                     s.clone());
                    } else {
                        self.toc.add(n,
                                     format!("{}#link-{}",
                                             self.filename,
                                             self.link_number),
                                     s.clone());
                    }

                }
                if n == 1 && self.current_hide {
                    format!("", self.link_number)
                } else {
                    format!("<h{} id = \"link-{}\">{}</h{}>\n",
                            n, self.link_number, s, n)
                }
            },
            Token::Emphasis(ref vec) => format!("{}", self.render_vec(vec)),
            Token::Strong(ref vec) => format!("{}", self.render_vec(vec)),
            Token::Code(ref vec) => format!("{}", self.render_vec(vec)),
            Token::BlockQuote(ref vec) => format!("
{}
\n", self.render_vec(vec)),
            Token::CodeBlock(ref language, ref vec) => {
                self.verbatim = true;
                let s = self.render_vec(vec);
                let output = if language.is_empty() {
                    format!("
{}
\n", s)
                } else {
                    format!("
{}
\n", language, s)
                };
                self.verbatim = false;
                output
            },
            Token::Rule => String::from("
***
\n"),
            Token::SoftBreak => String::from(" "),
            Token::HardBreak => String::from("
\n"),
            Token::List(ref vec) => format!("
\n{}
\n", self.render_vec(vec)),
            Token::OrderedList(n, ref vec) => format!("
\n{}
\n",
                                                      if n == 1 {
                                                          String::new()
                                                      } else {
                                                          format!(" start = \"{}\"", n)
                                                      },
                                                      self.render_vec(vec)),
            Token::Item(ref vec) => format!("
{}
\n", self.render_vec(vec)),
            Token::Link(ref url, ref title, ref vec) => {
                let url: String = if ResourceHandler::is_local(url) {
                    self.handler.get_link(url).to_owned()
                } else {
                    url.clone()
                };

                format!("{}", url,
                        if title.is_empty() {
                            String::new()
                        } else {
                            format!(" title = \"{}\"", title)
                        },
                        self.render_vec(vec))
            },
            Token::Image(ref url, ref title, ref alt) => {
                let content = self.render_vec(alt);
                let url = self.handler.map_image(Cow::Borrowed(url));
                format!("",
                        url,
                        title,
                        content)
            },
            Token::Table(_, ref vec) => format!("

\n{}

\n", self.render_vec(vec)),
            Token::TableRow(ref vec) => format!("
\n{}
\n", self.render_vec(vec)),
            Token::TableCell(ref vec) => {
                let tag = if self.table_head {"th"} else {"td"};
                format!("<{}>{}</{}>", tag, self.render_vec(vec), tag)
            },
            Token::TableHead(ref vec) => {
                self.table_head = true;
                let s = self.render_vec(vec);
                self.table_head = false;
                format!("
\n{}
\n", s)
            },
            Token::Footnote(ref vec) => {
                self.footnote_number += 1;
                let number = self.footnote_number;
                assert!(!vec.is_empty());

                let note_number = format!("

  [{}]

", number, number);

                let inner = format!("{}",
                                    if self.epub3 {r#"epub:type="footnote"#}else{""},
                                    number, self.render_vec(vec));
                self.footnotes.push((note_number, inner));

                format!("{}",
                        if self.epub3 {"epub:type = \"noteref\""} else {""},
                        number, number, number)
            },
        }
    }
}

<|endoftext|>


<commit_before>use getopts::{Options,Matches};
use std::net::{TcpListener,TcpStream};
use std::io::{Read,BufStream,BufRead};
use std::old_io::{LineBufferedWriter,stdio};

pub fn nc_listen(matches: &Matches) {
    // append port to localhost IP address
    let mut s = String::from_str("127.0.0.1:");
    s.push_str(matches.free[0].as_slice());
    let listener = TcpListener::bind(s.as_slice()).unwrap();
    // block until we get connection
    let mut writer = LineBufferedWriter::new(stdio::stdout());
    match listener.accept() {
        Ok((stream, socket_addr)) => {
            // nc doesn't handle multiple connections, so no need to do `handle_client`
            // in thread.
            handle_client(stream, &mut writer);
        },
        Err(f) => {
            panic!(f.to_string());
        }
    }
}

fn handle_client(stream: TcpStream, writer: &mut Writer) {
    let mut buf_stream = BufStream::new(stream);
    let mut read_buf = [0; 4096];
    loop {
        match(buf_stream.read(&mut read_buf)) {
            Ok(n) => {
                if n > 0 {
                    writer.write_all(&read_buf.slice_to(n)).unwrap();
                }
                else {
                    return;
                }
            }
            Err(f) => {
                panic!(f.to_string());
            }
        }
    }
}
<commit_msg>wip on listener, builds<commit_after>extern crate mio;
use getopts::{Options,Matches};
use std::io::{Read,BufStream,BufRead};
use std::old_io::{LineBufferedWriter,stdio};

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

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

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

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

impl Handler for ServerHandler {
    type Timeout = usize;
    type Message = ();

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

pub fn nc_listen(matches: &Matches) {
    // append port to localhost IP address
    let mut s = String::from_str("127.0.0.1:");
    s.push_str(matches.free[0].as_slice());
    let listener = TcpListener::bind(s.as_slice()).unwrap();
    // block until we get connection
    let mut writer = LineBufferedWriter::new(stdio::stdout());
    match listener.accept() {
        Ok((stream, socket_addr)) => {
            // nc doesn't handle multiple connections, so no need to do `handle_client`
            // in thread.
            handle_client(stream, &mut writer);
        },
        Err(f) => {
            panic!(f.to_string());
        }
    }
}

fn handle_client(stream: TcpStream, writer: &mut Writer) {
    let mut buf_stream = BufStream::new(stream);
    let mut read_buf = [0; 4096];
    loop {
        match(buf_stream.read(&mut read_buf)) {
            Ok(n) => {
                if n > 0 {
                    writer.write_all(&read_buf.slice_to(n)).unwrap();
                }
                else {
                    return;
                }
            }
            Err(f) => {
                panic!(f.to_string());
            }
        }
    }
}
<|endoftext|>