<commit_before>extern crate camera_controllers;
extern crate gfx;
extern crate piston_window;
extern crate terra;
extern crate vecmath;

use piston_window::*;
use camera_controllers::{FirstPersonSettings, FirstPerson, CameraPerspective,
                         model_view_projection};

use std::fs::File;
use std::io::BufReader;

use terra::terrain::Terrain;
use terra::terrain::dem::Dem;

fn main() {
    let file = File::open("../assets/USGS_NED_1_n62w144_GridFloat.zip").unwrap();
    let dem = Dem::from_gridfloat_zip(&mut BufReader::new(file));

    let mut window: PistonWindow = WindowSettings::new("terra preview", [640, 480])
        .exit_on_esc(true)
        .opengl(OpenGL::V4_5)
        .samples(2)
        .build()
        .unwrap();
    window.set_capture_cursor(true);

    let mut terrain = Terrain::new(dem,
                                   window.factory.clone(),
                                   window.output_color.clone(),
                                   window.output_stencil.clone());
    terrain.generate_textures(&mut window.encoder);

    let get_projection = |w: &PistonWindow| {
        let draw_size = w.window.draw_size();
        CameraPerspective {
                fov: 90.0,
                near_clip: 10.0,
                far_clip: 100000.0,
                aspect_ratio: (draw_size.width as f32) / (draw_size.height as f32),
            }
            .projection()
    };

    let mut projection = get_projection(&window);
    let mut first_person = FirstPerson::new([10000.0, 5500.0, 10000.0],
                                            FirstPersonSettings::keyboard_wasd());
    first_person.settings.speed_vertical = 500.0;
    first_person.settings.speed_horizontal = 5000.0;

    while let Some(e) = window.next() {
        first_person.event(&e);

        if let Some(_) = e.resize_args() {
            projection = get_projection(&window);
        }

        window.draw_3d(&e, |window| {
            let args = e.render_args().unwrap();

            window
                .encoder
                .clear(&window.output_color, [0.3, 0.3, 0.3, 1.0]);
            window.encoder.clear_depth(&window.output_stencil, 1.0);

            let camera = first_person.camera(args.ext_dt);
            terrain.update(model_view_projection(vecmath::mat4_id(),
                                                 camera.orthogonal(),
                                                 projection),
                           [camera.position[0], camera.position[2]]);
            terrain.render(&mut window.encoder);
        });
    }
}
<commit_msg>Preview app now shows the view from ground level<commit_after>extern crate camera_controllers;
extern crate gfx;
extern crate piston_window;
extern crate terra;
extern crate vecmath;

use piston_window::*;
use camera_controllers::{FirstPersonSettings, FirstPerson, CameraPerspective,
                         model_view_projection};

use std::fs::File;
use std::io::BufReader;

use terra::terrain::Terrain;
use terra::terrain::dem::Dem;

fn main() {
    let file = File::open("../assets/USGS_NED_1_n62w144_GridFloat.zip").unwrap();
    let dem = Dem::from_gridfloat_zip(&mut BufReader::new(file));

    let mut window: PistonWindow = WindowSettings::new("terra preview", [640, 480])
        .exit_on_esc(true)
        .opengl(OpenGL::V4_5)
        .samples(2)
        .build()
        .unwrap();
    window.set_capture_cursor(true);

    let mut terrain = Terrain::new(dem,
                                   window.factory.clone(),
                                   window.output_color.clone(),
                                   window.output_stencil.clone());
    terrain.generate_textures(&mut window.encoder);

    let get_projection = |w: &PistonWindow| {
        let draw_size = w.window.draw_size();
        CameraPerspective {
                fov: 90.0,
                near_clip: 0.5,
                far_clip: 100000.0,
                aspect_ratio: (draw_size.width as f32) / (draw_size.height as f32),
            }
            .projection()
    };

    let mut projection = get_projection(&window);
    let mut first_person = FirstPerson::new([0.0, 0.0, 0.0], FirstPersonSettings::keyboard_wasd());
    first_person.settings.speed_horizontal = 100.0;

    while let Some(e) = window.next() {
        first_person.event(&e);

        if let Some(_) = e.resize_args() {
            projection = get_projection(&window);
        }

        window.draw_3d(&e, |window| {
            let args = e.render_args().unwrap();

            window
                .encoder
                .clear(&window.output_color, [0.3, 0.3, 0.3, 1.0]);
            window.encoder.clear_depth(&window.output_stencil, 1.0);

            let mut camera = first_person.camera(args.ext_dt);
            if let Some(h) = terrain.get_height([camera.position[0], camera.position[2]]) {
                camera.position[1] = h + 2.0;
            }
            terrain.update(model_view_projection(vecmath::mat4_id(),
                                                 camera.orthogonal(),
                                                 projection),
                           [camera.position[0], camera.position[2]]);
            terrain.render(&mut window.encoder);
        });
    }
}
<|endoftext|>


<commit_before>use sass::value_part::ValuePart;
use evaluator::Evaluator;

use std::borrow::Cow::Borrowed;
use std::str::FromStr;

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Op {
    Plus,
    Minus,
    Star,
    Slash,
    Percent,
    LeftParen,
    RightParen,
    Comma,
}

impl FromStr for Op {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "+" => Ok(Op::Plus),
            "-" => Ok(Op::Minus),
            "*" => Ok(Op::Star),
            "/" => Ok(Op::Slash),
            "%" => Ok(Op::Percent),
            "(" => Ok(Op::LeftParen),
            ")" => Ok(Op::RightParen),
            "," => Ok(Op::Comma),
            _   => Err(()),
        }
    }
}

impl Op {
    pub fn apply<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>, paren_level: i32) -> ValuePart<'a> {
        match (self, &second) {
            (&Op::Plus, &ValuePart::List(..)) => self.apply_list(first, second),
            (&Op::Slash, _) => self.apply_slash(first, second, paren_level),
            (_, _) => self.apply_math(first, second),
        }
    }

    fn apply_list<'a>(&self, mut first: ValuePart<'a>, mut second: ValuePart<'a>) -> ValuePart<'a> {
        let first_collapsed = match first {
            ValuePart::List(ref mut l) => {
                let mut ve = vec![ValuePart::Operator(Op::LeftParen)];
                l.push(ValuePart::Operator(Op::RightParen));
                ve.append(l);
                Evaluator::new(ve).evaluate()
            },
            _ => first,
        };

        let second_collapsed = match second {
            ValuePart::List(ref mut l) => {
                let mut ve = vec![ValuePart::Operator(Op::LeftParen)];
                l.push(ValuePart::Operator(Op::RightParen));
                ve.append(l);
                Evaluator::new(ve).evaluate()
            },
            _ => second,
        };

        match (first_collapsed, second_collapsed) {
            (ValuePart::Computed(fnum), ValuePart::List(mut slist)) |
            (ValuePart::Number(fnum), ValuePart::List(mut slist)) => {
                let new_first_item_value = format!("{}{}", fnum, slist.remove(0));
                let v = ValuePart::String(new_first_item_value.into());
                let mut ve = vec![v];
                ve.append(&mut slist);
                ValuePart::List(ve)
            },
            (ValuePart::List(mut flist), ValuePart::Computed(snum)) |
            (ValuePart::List(mut flist), ValuePart::Number(snum)) => {
                let new_last_item_value = format!("{}{}",
                    flist.pop().unwrap_or(ValuePart::String(Borrowed(""))),
                    snum
                );
                let v = ValuePart::String(new_last_item_value.into());
                flist.push(v);
                ValuePart::List(flist)
            },
            (ValuePart::List(mut flist), ValuePart::List(slist)) => {
                flist.extend(slist);
                ValuePart::List(flist.clone())
            },
            (f @ ValuePart::Computed(..), s @ ValuePart::Computed(..)) |
            (f @ ValuePart::Computed(..), s @ ValuePart::Number(..)) |
            (f @ ValuePart::Number(..), s @ ValuePart::Computed(..)) => {
                self.apply_math(f, s)
            },
            (unk_first, unk_second) => {
                panic!(
                    "Unknown apply_list match:\n  first: {:?}\n  second: {:?}",
                    unk_first, unk_second
                )
            },
        }
    }

    fn apply_slash<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>, paren_level: i32) -> ValuePart<'a> {
        if paren_level == 0 {
            match first {
                ValuePart::List(mut f) => {
                    let mut ve = vec![ValuePart::Operator(*self), second];
                    f.append(&mut ve);
                    ValuePart::List(f)
                },
                ValuePart::Computed(..) => {
                    self.apply_math(first, second)
                },
                _ => ValuePart::List(vec![first, ValuePart::Operator(*self), second]),
            }
        } else {
            self.apply_math(first, second)
        }
    }

    fn apply_math<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>) -> ValuePart<'a> {
        let (first_num, second_num) = match (first, second) {
            (ValuePart::Number(f), ValuePart::Number(s)) => (f, s),
            (ValuePart::Number(f), ValuePart::Computed(s)) => (f, s),
            (ValuePart::Computed(f), ValuePart::Number(s)) => (f, s),
            (ValuePart::Computed(f), ValuePart::Computed(s)) => (f, s),
            (f, s) => return ValuePart::String(format!("Invalid arguments {:?} {:?}", f, s).into()),
        };
        let result = match *self {
            Op::Plus => first_num + second_num,
            Op::Minus => first_num - second_num,
            Op::Star => first_num * second_num,
            Op::Slash => first_num / second_num,
            Op::Percent => first_num % second_num,
            _ => 0.0,
        };
        ValuePart::Computed(result)
    }

    pub fn same_or_greater_precedence(self, other: Op) -> bool {
        match (self, other) {
            (Op::Plus, Op::Star) |
            (Op::Minus, Op::Star) |
            (Op::Plus, Op::Slash) |
            (Op::Minus, Op::Slash) |
            (Op::LeftParen, _) => false,
            (_, _) => true,
        }
    }
}
<commit_msg>Extract a function for the hacky way I'm forcing list division<commit_after>use sass::value_part::ValuePart;
use evaluator::Evaluator;

use std::borrow::Cow::Borrowed;
use std::str::FromStr;

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Op {
    Plus,
    Minus,
    Star,
    Slash,
    Percent,
    LeftParen,
    RightParen,
    Comma,
}

impl FromStr for Op {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "+" => Ok(Op::Plus),
            "-" => Ok(Op::Minus),
            "*" => Ok(Op::Star),
            "/" => Ok(Op::Slash),
            "%" => Ok(Op::Percent),
            "(" => Ok(Op::LeftParen),
            ")" => Ok(Op::RightParen),
            "," => Ok(Op::Comma),
            _   => Err(()),
        }
    }
}

impl Op {
    pub fn apply<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>, paren_level: i32) -> ValuePart<'a> {
        match (self, &second) {
            (&Op::Plus, &ValuePart::List(..)) => self.apply_list(first, second),
            (&Op::Slash, _) => self.apply_slash(first, second, paren_level),
            (_, _) => self.apply_math(first, second),
        }
    }

    fn force_list_collapse<'a>(&self, mut vp: ValuePart<'a>) -> ValuePart<'a> {
        match vp {
            ValuePart::List(ref mut l) => {
                let mut ve = vec![ValuePart::Operator(Op::LeftParen)];
                l.push(ValuePart::Operator(Op::RightParen));
                ve.append(l);
                Evaluator::new(ve).evaluate()
            },
            _ => vp,
        }
    }

    fn apply_list<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>) -> ValuePart<'a> {
        let first_collapsed  = self.force_list_collapse(first);
        let second_collapsed = self.force_list_collapse(second);

        match (first_collapsed, second_collapsed) {
            (ValuePart::Computed(fnum), ValuePart::List(mut slist)) |
            (ValuePart::Number(fnum), ValuePart::List(mut slist)) => {
                let new_first_item_value = format!("{}{}", fnum, slist.remove(0));
                let v = ValuePart::String(new_first_item_value.into());
                let mut ve = vec![v];
                ve.append(&mut slist);
                ValuePart::List(ve)
            },
            (ValuePart::List(mut flist), ValuePart::Computed(snum)) |
            (ValuePart::List(mut flist), ValuePart::Number(snum)) => {
                let new_last_item_value = format!("{}{}",
                    flist.pop().unwrap_or(ValuePart::String(Borrowed(""))),
                    snum
                );
                let v = ValuePart::String(new_last_item_value.into());
                flist.push(v);
                ValuePart::List(flist)
            },
            (ValuePart::List(mut flist), ValuePart::List(slist)) => {
                flist.extend(slist);
                ValuePart::List(flist.clone())
            },
            (f @ ValuePart::Computed(..), s @ ValuePart::Computed(..)) |
            (f @ ValuePart::Computed(..), s @ ValuePart::Number(..)) |
            (f @ ValuePart::Number(..), s @ ValuePart::Computed(..)) => {
                self.apply_math(f, s)
            },
            (unk_first, unk_second) => {
                panic!(
                    "Unknown apply_list match:\n  first: {:?}\n  second: {:?}",
                    unk_first, unk_second
                )
            },
        }
    }

    fn apply_slash<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>, paren_level: i32) -> ValuePart<'a> {
        if paren_level == 0 {
            match first {
                ValuePart::List(mut f) => {
                    let mut ve = vec![ValuePart::Operator(*self), second];
                    f.append(&mut ve);
                    ValuePart::List(f)
                },
                ValuePart::Computed(..) => {
                    self.apply_math(first, second)
                },
                _ => ValuePart::List(vec![first, ValuePart::Operator(*self), second]),
            }
        } else {
            self.apply_math(first, second)
        }
    }

    fn apply_math<'a>(&self, first: ValuePart<'a>, second: ValuePart<'a>) -> ValuePart<'a> {
        let (first_num, second_num) = match (first, second) {
            (ValuePart::Number(f), ValuePart::Number(s)) => (f, s),
            (ValuePart::Number(f), ValuePart::Computed(s)) => (f, s),
            (ValuePart::Computed(f), ValuePart::Number(s)) => (f, s),
            (ValuePart::Computed(f), ValuePart::Computed(s)) => (f, s),
            (f, s) => return ValuePart::String(format!("Invalid arguments {:?} {:?}", f, s).into()),
        };
        let result = match *self {
            Op::Plus => first_num + second_num,
            Op::Minus => first_num - second_num,
            Op::Star => first_num * second_num,
            Op::Slash => first_num / second_num,
            Op::Percent => first_num % second_num,
            _ => 0.0,
        };
        ValuePart::Computed(result)
    }

    pub fn same_or_greater_precedence(self, other: Op) -> bool {
        match (self, other) {
            (Op::Plus, Op::Star) |
            (Op::Minus, Op::Star) |
            (Op::Plus, Op::Slash) |
            (Op::Minus, Op::Slash) |
            (Op::LeftParen, _) => false,
            (_, _) => true,
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The SAX-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// 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.

#[comment = "Wrapper for libxml2's SAX parser."];
#[crate_id = "github.com/bjz/sax-rs#sax:0.1"];

#[crate_type = "lib"];

#[feature(globs)];

extern crate sync;

use std::cast;
use std::comm::{Receiver, channel};
use std::libc::{c_char, c_int};
use std::str;
use std::io::{File, IoResult};
use std::fmt;
use std::vec_ng::Vec;

use error::ErrorData;

pub mod error;
pub mod ffi;
mod extfn;

/// Events to be sent by the parser.
#[deriving(Eq, Clone)]
pub enum ParseEvent {
    /// The document has begun to be processed.
    StartDocument,
    /// The document processing has finished.
    EndDocument,
    /// An opening tag has was parsed.
    StartElement(~str, Attributes),
    /// A closing tag was parsed.
    EndElement(~str),
    /// Some characters between tags have been recived.
    Characters(~str),
    /// A comment tag was parsed.
    Comment(~str),
    /// A `CDATA` block was parsed.
    CdataBlock(~str),
}

impl fmt::Show for ParseEvent {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            StartDocument => write!(fmt.buf, "START DOCUMENT"),
            EndDocument => write!(fmt.buf, "END DOCUMENT"),
            StartElement(ref name, ref atts) => write!(fmt.buf, "<{}{}>", *name, atts),
            EndElement(ref name) => write!(fmt.buf, "</{}>", *name),
            Characters(ref ch) => write!(fmt.buf, "{}", ch.clone()),
            Comment(ref value) => write!(fmt.buf, "", *value),
            CdataBlock(ref value) => write!(fmt.buf, "<![CDATA[{}]]>", *value),
        }
    }
}

#[deriving(Eq, Clone)]
pub struct Attribute {
    name: ~str,
    value: ~str,
}

/// A list of attributes
#[deriving(Eq, Clone)]
pub struct Attributes(Vec<Attribute>);

impl Attributes {
    unsafe fn from_buf(atts: **ffi::xmlChar) -> Attributes {
        let mut ret = Vec::new();
        let mut ptr = atts as **c_char;
        while !ptr.is_null() && !(*ptr).is_null() {
            ret.push(
                Attribute {
                    name: str::raw::from_c_str(*ptr),
                    value: str::raw::from_c_str(*ptr.offset(1)),
                }
            );
            ptr = ptr.offset(2);
        }
        Attributes(ret)
    }

    pub fn find<'a>(&'a self, name: &str) -> Option<&'a str> {
        let Attributes(ref s) = *self;
        s.iter()
         .find(|att| name == att.name)
         .map(|att| att.value.as_slice())
    }

    pub fn get<'a>(&'a self, name: &str) -> &'a str {
        self.find(name).expect(format!("Could not find an attribute with the name \"{}\"", name))
    }

    pub fn find_clone(&self, name: &str) -> Option<~str> {
        self.find(name).map(|v| v.to_owned())
    }

    pub fn get_clone(&self, name: &str) -> ~str {
        self.get(name).to_owned()
    }
}

impl fmt::Show for Attributes {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let Attributes(ref s) = *self;
        for att in s.iter() {
            try!(write!(fmt.buf, " {}=\"{}\"", att.name, att.value));
        }
        Ok(())
    }
}

/// Either a parse event wrapped in `Ok` or some Error data wrapped in `Err`.
pub type ParseResult = Result<ParseEvent, ErrorData>;

/// Parses the entire XML string.
///
/// # Returns
///
/// A receiver that recieves parse results.
///
/// # Example
///
/// ~~~rust
/// let parser = parse_str("<yo>hullo!</yo>");
/// for result in parser.iter() {
///     match result {
///         Ok(StartDocument) => (),
///         Ok(EndDocument) => break,
///         Ok(event) => println!("{}", event.to_str()),
///         Err(err) => println!("{}", err.to_str()),
///     }
/// }
/// ~~~
#[inline(never)]
pub fn parse_str(src: &str) -> Receiver<ParseResult> {
    // ensure that the xml library is ready for use
    use sync::one::{Once, ONCE_INIT};
    static mut INIT: Once = ONCE_INIT;
    unsafe {
        INIT.doit(|| {
            ffi::xmlInitParser();
            std::rt::at_exit(proc() ffi::xmlCleanupParser());
        })
    }

    let len = src.len() as c_int;
    src.to_c_str().with_ref(|c_str| {
        let (sender, receiver) = channel();
        unsafe {
            ffi::xmlSAXUserParseMemory(&extfn::new_handler(),
                                       cast::transmute(&sender),
                                       c_str, len);
        }
        receiver
    })
}

pub fn parse_file(path: &Path) -> IoResult<Receiver<ParseResult> > {
  File::open(path)
    .and_then( |mut file| {
      file.read_to_str()
    })
    .and_then( |contents| {
      Ok(parse_str(contents))
    })
}

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

    fn get_mock_atts() -> Attributes {
        Attributes(Vec::from_slice([
            Attribute { name: ~"foo", value: ~"0" },
            Attribute { name: ~"bar", value: ~"1" },
            Attribute { name: ~"baz", value: ~"2" }
        ]))
    }

    #[test]
    fn test_att_get() {
        let atts = get_mock_atts();
        assert_eq!(atts.get("foo"), "0");
        assert_eq!(atts.get("bar"), "1");
        assert_eq!(atts.get("baz"), "2");
    }

    #[test]
    fn test_att_find() {
        let atts = get_mock_atts();
        assert_eq!(atts.find("foo"), Some("0"));
        assert_eq!(atts.find("bar"), Some("1"));
        assert_eq!(atts.find("baz"), Some("2"));
    }

    #[test]
    fn test() {
        let sax = parse_str(
            "<hello><this />test</hello>"
        );
        loop {
            match sax.recv() {
                Ok(StartDocument) => (),
                Ok(EndDocument) => break,
                Ok(event) => println!("{}", event.to_str()),
                Err(err) => println!("{}", err.to_str()),
            }
        }
    }
}
<commit_msg>Updated to latest Rust: Removed 'use std::vec_ng::Vec;'<commit_after>// Copyright 2013 The SAX-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// 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.

#[comment = "Wrapper for libxml2's SAX parser."];
#[crate_id = "github.com/bjz/sax-rs#sax:0.1"];

#[crate_type = "lib"];

#[feature(globs)];

extern crate sync;

use std::cast;
use std::comm::{Receiver, channel};
use std::libc::{c_char, c_int};
use std::str;
use std::io::{File, IoResult};
use std::fmt;

use error::ErrorData;

pub mod error;
pub mod ffi;
mod extfn;

/// Events to be sent by the parser.
#[deriving(Eq, Clone)]
pub enum ParseEvent {
    /// The document has begun to be processed.
    StartDocument,
    /// The document processing has finished.
    EndDocument,
    /// An opening tag has was parsed.
    StartElement(~str, Attributes),
    /// A closing tag was parsed.
    EndElement(~str),
    /// Some characters between tags have been recived.
    Characters(~str),
    /// A comment tag was parsed.
    Comment(~str),
    /// A `CDATA` block was parsed.
    CdataBlock(~str),
}

impl fmt::Show for ParseEvent {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            StartDocument => write!(fmt.buf, "START DOCUMENT"),
            EndDocument => write!(fmt.buf, "END DOCUMENT"),
            StartElement(ref name, ref atts) => write!(fmt.buf, "<{}{}>", *name, atts),
            EndElement(ref name) => write!(fmt.buf, "</{}>", *name),
            Characters(ref ch) => write!(fmt.buf, "{}", ch.clone()),
            Comment(ref value) => write!(fmt.buf, "", *value),
            CdataBlock(ref value) => write!(fmt.buf, "<![CDATA[{}]]>", *value),
        }
    }
}

#[deriving(Eq, Clone)]
pub struct Attribute {
    name: ~str,
    value: ~str,
}

/// A list of attributes
#[deriving(Eq, Clone)]
pub struct Attributes(Vec<Attribute>);

impl Attributes {
    unsafe fn from_buf(atts: **ffi::xmlChar) -> Attributes {
        let mut ret = Vec::new();
        let mut ptr = atts as **c_char;
        while !ptr.is_null() && !(*ptr).is_null() {
            ret.push(
                Attribute {
                    name: str::raw::from_c_str(*ptr),
                    value: str::raw::from_c_str(*ptr.offset(1)),
                }
            );
            ptr = ptr.offset(2);
        }
        Attributes(ret)
    }

    pub fn find<'a>(&'a self, name: &str) -> Option<&'a str> {
        let Attributes(ref s) = *self;
        s.iter()
         .find(|att| name == att.name)
         .map(|att| att.value.as_slice())
    }

    pub fn get<'a>(&'a self, name: &str) -> &'a str {
        self.find(name).expect(format!("Could not find an attribute with the name \"{}\"", name))
    }

    pub fn find_clone(&self, name: &str) -> Option<~str> {
        self.find(name).map(|v| v.to_owned())
    }

    pub fn get_clone(&self, name: &str) -> ~str {
        self.get(name).to_owned()
    }
}

impl fmt::Show for Attributes {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let Attributes(ref s) = *self;
        for att in s.iter() {
            try!(write!(fmt.buf, " {}=\"{}\"", att.name, att.value));
        }
        Ok(())
    }
}

/// Either a parse event wrapped in `Ok` or some Error data wrapped in `Err`.
pub type ParseResult = Result<ParseEvent, ErrorData>;

/// Parses the entire XML string.
///
/// # Returns
///
/// A receiver that recieves parse results.
///
/// # Example
///
/// ~~~rust
/// let parser = parse_str("<yo>hullo!</yo>");
/// for result in parser.iter() {
///     match result {
///         Ok(StartDocument) => (),
///         Ok(EndDocument) => break,
///         Ok(event) => println!("{}", event.to_str()),
///         Err(err) => println!("{}", err.to_str()),
///     }
/// }
/// ~~~
#[inline(never)]
pub fn parse_str(src: &str) -> Receiver<ParseResult> {
    // ensure that the xml library is ready for use
    use sync::one::{Once, ONCE_INIT};
    static mut INIT: Once = ONCE_INIT;
    unsafe {
        INIT.doit(|| {
            ffi::xmlInitParser();
            std::rt::at_exit(proc() ffi::xmlCleanupParser());
        })
    }

    let len = src.len() as c_int;
    src.to_c_str().with_ref(|c_str| {
        let (sender, receiver) = channel();
        unsafe {
            ffi::xmlSAXUserParseMemory(&extfn::new_handler(),
                                       cast::transmute(&sender),
                                       c_str, len);
        }
        receiver
    })
}

pub fn parse_file(path: &Path) -> IoResult<Receiver<ParseResult> > {
  File::open(path)
    .and_then( |mut file| {
      file.read_to_str()
    })
    .and_then( |contents| {
      Ok(parse_str(contents))
    })
}

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

    fn get_mock_atts() -> Attributes {
        Attributes(Vec::from_slice([
            Attribute { name: ~"foo", value: ~"0" },
            Attribute { name: ~"bar", value: ~"1" },
            Attribute { name: ~"baz", value: ~"2" }
        ]))
    }

    #[test]
    fn test_att_get() {
        let atts = get_mock_atts();
        assert_eq!(atts.get("foo"), "0");
        assert_eq!(atts.get("bar"), "1");
        assert_eq!(atts.get("baz"), "2");
    }

    #[test]
    fn test_att_find() {
        let atts = get_mock_atts();
        assert_eq!(atts.find("foo"), Some("0"));
        assert_eq!(atts.find("bar"), Some("1"));
        assert_eq!(atts.find("baz"), Some("2"));
    }

    #[test]
    fn test() {
        let sax = parse_str(
            "<hello><this />test</hello>"
        );
        loop {
            match sax.recv() {
                Ok(StartDocument) => (),
                Ok(EndDocument) => break,
                Ok(event) => println!("{}", event.to_str()),
                Err(err) => println!("{}", err.to_str()),
            }
        }
    }
}
<|endoftext|>


<commit_before>use basetypes::*;

pub struct BoardGeometry {
    pub grid: [u8; 120],
    pub piece_grid_deltas: [[i8; 8]; 5],
    pub piece_longrange: [bool; 5],
    pub attacks: [[u64; 64]; 5],
    pub blockers_and_beyond: [[u64; 64]; 5],
    pub squares_at_line: [[u64; 64]; 64],
    pub squares_between_including: [[u64; 64]; 64],
    pub squares_behind_blocker: [[u64; 64]; 64],
}

impl BoardGeometry {
    pub fn new() -> BoardGeometry {
        // We use 10x12 grid (8x8 with guarding markers, 2 at top and
        // bottom, 1 at the sides), so that we can detect out-of-board
        // movements. Each cell in the grid contains the corresponding
        // square number (from 0 to 63) or 0xff (the guarding marker).
        let mut grid = [0xffu8; 120];
        for i in 0..64 {
            grid[BoardGeometry::grid_index_from_square(i)] = i as u8;
        }

        // "piece_deltas" represent the change in the grid-index when
        // sliding a particular piece by one square in a particular
        // direction. We are not concerned with pawns here.
        let mut piece_grid_deltas = [[0i8; 8]; 5];
        piece_grid_deltas[QUEEN] = [-11, -10, -9, -1, 1, 9, 10, 11];
        piece_grid_deltas[ROOK] = [0, -10, 0, -1, 1, 0, 10, 0];
        piece_grid_deltas[BISHOP] = [-11, 0, -9, 0, 0, 9, 0, 11];
        piece_grid_deltas[KNIGHT] = [-21, -19, -12, -8, 8, 12, 19, 21];
        piece_grid_deltas[KING] = [-11, -10, -9, -1, 1, 9, 10, 11];

        // All pieces except knights and kings are long-range (They
        // can slide by more than one square). We are not concerned
        // with pawns here.
        let mut piece_longrange = [true; 5];
        piece_longrange[KNIGHT] = false;
        piece_longrange[KING] = false;

        let mut g = BoardGeometry {
            grid: grid,
            piece_grid_deltas: piece_grid_deltas,
            piece_longrange: piece_longrange,
            attacks: [[0u64; 64]; 5],
            blockers_and_beyond: [[0u64; 64]; 5],
            squares_at_line: [[0u64; 64]; 64],
            squares_between_including: [[0u64; 64]; 64],
            squares_behind_blocker: [[0u64; 64]; 64],
        };

        // "attacks" and "blockers_and_beyond" fields hold attack and
        // blockers bitsets for each piece on each possible square.
        // For example:
        //
        // g.attacks[QUEEN][D4]  g.blockers_and_beyond[QUEEN][D4]
        // . . . 1 . . . 1       . . . . . . . .
        // 1 . . 1 . . 1 .       . . . 1 . . 1 .
        // . 1 . 1 . 1 . .       . 1 . 1 . 1 . .
        // . . 1 1 1 . . .       . . 1 1 1 . . .
        // 1 1 1 Q 1 1 1 1       . 1 1 Q 1 1 1 .
        // . . 1 1 1 . . .       . . 1 1 1 . . .
        // . 1 . 1 . 1 . .       . 1 . 1 . 1 . .
        // 1 . . 1 . . 1 .       . . . . . . . .
        //
        // g.attacks[KNIGHT][D4] g.blockers_and_beyond[KNIGHT][D4]
        // . . . . . . . .       . . . . . . . .
        // . . . . . . . .       . . . . . . . .
        // . . 1 . 1 . . .       . . . . . . . .
        // . 1 . . . 1 . .       . . . . . . . .
        // . . . N . . . .       . . . N . . . .
        // . 1 . . . 1 . .       . . . . . . . .
        // . . 1 . 1 . . .       . . . . . . . .
        // . . . . . . . .       . . . . . . . .
        g.fill_attack_and_blockers_and_beyond_arrays();

        // The "squares_behind_blocker" field holds bitsets that
        // describe all squares hidden behind a blocker from the
        // attacker's position. For example:
        //
        // g.squares_behind_blocker[B2][F6]
        // . . . . . . . 1
        // . . . . . . 1 .
        // . . . . . B . .
        // . . . . . . . .
        // . . . . . . . .
        // . . . . . . . .
        // . A . . . . . .
        // . . . . . . . .
        //
        // The "squares_between_including" field holds bitsets that
        // describe all squares between an attacker an a blocker
        // including the attacker's and blocker's fields
        // themselves. For example:
        //
        // g.squares_between_including[B2][F6]
        // . . . . . . . .
        // . . . . . . . .
        // . . . . . 1 . .
        // . . . . 1 . . .
        // . . . 1 . . . .
        // . . 1 . . . . .
        // . 1 . . . . . .
        // . . . . . . . .
        g.fill_squares_between_including_and_squares_behind_blocker_arrays();

        // The "squares_at_line" field holds bitsets that describe all
        // squares lying at the line determined by the attacker and
        // the blocker. For example:
        //
        // g.squares_at_line[B2][F6]
        // . . . . . . . 1
        // . . . . . . 1 .
        // . . . . . 1 . .
        // . . . . 1 . . .
        // . . . 1 . . . .
        // . . 1 . . . . .
        // . 1 . . . . . .
        // 1 . . . . . . .
        g.fill_squares_at_line_array();

        g
    }

    pub fn grid_index(&self, i: Square) -> usize {
        Self::grid_index_from_square(i)
    }

    #[inline(always)]
    fn grid_index_from_square(i: Square) -> usize {
        ((i / 8) * 10 + (i % 8) + 21)
    }

    fn fill_attack_and_blockers_and_beyond_arrays(&mut self) {
        for piece_type in 0..5 {
            for square in 0..64 {
                let mut attack = 0u64;
                let mut blockers = 0u64;
                for move_direction in 0..8 {
                    let delta = self.piece_grid_deltas[piece_type][move_direction];
                    if delta != 0 {
                        let mut last_mask = 0u64;
                        let mut curr_grid_index = self.grid_index(square);
                        loop {
                            curr_grid_index = (curr_grid_index as i8 + delta) as usize;
                            let curr_square = self.grid[curr_grid_index] as Square;
                            if curr_square != 0xff {
                                last_mask = 1 << curr_square;
                                attack |= last_mask;
                                blockers |= last_mask;
                                if self.piece_longrange[piece_type] {
                                    continue;
                                }
                            }
                            blockers &= !last_mask;
                            break;
                        }
                    }
                }
                self.attacks[piece_type][square] = attack;
                self.blockers_and_beyond[piece_type][square] = blockers;
            }
        }
    }

    fn fill_squares_between_including_and_squares_behind_blocker_arrays(&mut self) {
        for attacker in 0..64 {
            for blocker in 0..64 {
                // Try to find a grid-index increment (delta) that
                // will generate all squares at the line. If the
                // attacker and the blocker happens not to lie at a
                // straight line, then and we simply proceed to the
                // next attacker/blocker pair.
                let rank_diff = rank(blocker) as i8 - rank(attacker) as i8;
                let file_diff = file(blocker) as i8 - file(attacker) as i8;
                let delta = match (rank_diff, file_diff) {
                    (0, 0) => continue,
                    (0, f) => f.signum(),
                    (r, 0) => 10 * r.signum(),
                    (r, f) if r == f => 10 * r.signum() + r.signum(),
                    (r, f) if r == -f => 10 * r.signum() - r.signum(),
                    _ => continue,
                };

                // Starting from the attacker's square update
                // "squares_between_including" until the blocker's
                // square is encountered, then switch to updating
                // "squares_behind_blocker" until the end of the board
                // is reached.
                let mut squares_between_including = 0u64;
                let mut squares_behind_blocker = 0u64;
                let mut curr_grid_index = self.grid_index(attacker);
                let mut blocker_encountered = false;
                loop {
                    let curr_square = self.grid[curr_grid_index] as Square;
                    match curr_square {
                        0xff => {
                            break;
                        }
                        x if x == blocker => {
                            squares_between_including |= 1 << curr_square;
                            blocker_encountered = true;
                        }
                        _ => {
                            if blocker_encountered {
                                squares_behind_blocker |= 1 << curr_square;
                            } else {
                                squares_between_including |= 1 << curr_square;
                            }
                        }
                    }
                    curr_grid_index = (curr_grid_index as i8 + delta) as usize;
                }
                assert!(blocker_encountered);
                self.squares_between_including[attacker][blocker] = squares_between_including;
                self.squares_behind_blocker[attacker][blocker] = squares_behind_blocker;
            }
        }
    }

    fn fill_squares_at_line_array(&mut self) {
        for a in 0..64 {
            for b in 0..64 {
                self.squares_at_line[a][b] = self.squares_between_including[a][b] |
                                             self.squares_behind_blocker[a][b] |
                                             self.squares_behind_blocker[b][a];
            }
        }
    }
}

// Attack (or blockers and beyond) array for all sliding pieces.
pub type SlidersArray = [[u64; 64]; 5];

// The StateInfo struct stores information needed to restore a Position
// object to its previous state when we retract a move. Whenever a move
// is made on the board (by calling Position::do_move), a StateInfo
// object must be passed as a parameter.

// struct StateInfo {
//   Key pawnKey, materialKey;
//   Value npMaterial[COLOR_NB];
//   int castlingRights, rule50, pliesFromNull;
//   Score psq;
//   Square epSquare;

//   Key key;
//   Bitboard checkersBB;
//   PieceType capturedType;
//   StateInfo* previous;
// };

pub type LinesArray = [[u64; 64]; 64];

// pub fn generate_behind_and_between_arrays() -> LinesArray {

// }

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

    #[test]
    fn test_attack_sets() {
        use basetypes::*;
        let g = BoardGeometry::new();
        assert_eq!(g.attacks[KING][A1], 0b11 << 8 | 0b10);
        assert_eq!(g.blockers_and_beyond[KING][A1], 0);
        assert_eq!(g.attacks[ROOK][A1],
                   0b11111110 | 1 << 8 | 1 << 16 | 1 << 24 | 1 << 32 | 1 << 40 | 1 << 48 | 1 << 56);
        assert_eq!(g.blockers_and_beyond[ROOK][A1],
                   0b01111110 | 1 << 8 | 1 << 16 | 1 << 24 | 1 << 32 | 1 << 40 | 1 << 48 | 0 << 56);
        assert_eq!(g.attacks[KING][D4], g.attacks[KING][E4] >> 1);
        assert_eq!(g.attacks[KING][D4], g.attacks[KING][D5] >> 8);
        assert_eq!(g.attacks[KNIGHT][D4], g.attacks[KNIGHT][D5] >> 8);
        assert_eq!(g.attacks[KNIGHT][D4] & g.attacks[KING][D5], 1 << C6 | 1 << E6);
        assert_eq!(g.attacks[ROOK][D4] | g.attacks[BISHOP][D4], g.attacks[QUEEN][D4]);
        assert_eq!(g.attacks[ROOK][D4] & g.attacks[BISHOP][D4], 0);
        assert_eq!(g.attacks[KING][D4] & g.attacks[QUEEN][D4], g.attacks[KING][D4]);
        assert_eq!(g.attacks[BISHOP][E1] & g.attacks[KNIGHT][H1], 1 << F2 | 1 << G3);
    }

    #[test]
    fn test_line_sets() {
        use basetypes::*;
        let g = BoardGeometry::new();
        assert_eq!(g.squares_at_line[B1][G1], 0b11111111);
        assert_eq!(g.squares_at_line[G8][B8], 0b11111111 << 56);
        assert_eq!(g.squares_between_including[B1][G1], 0b01111110);
        assert_eq!(g.squares_between_including[G8][B8], 0b01111110 << 56);
        assert_eq!(g.squares_behind_blocker[B1][G1], 1 << H1);
        assert_eq!(g.squares_behind_blocker[G8][B8], 1 << A8);
        assert_eq!(g.squares_behind_blocker[A1][G7], 1 << H8);
        assert_eq!(g.squares_behind_blocker[H1][B7], 1 << A8);
        assert_eq!(g.squares_behind_blocker[B7][G2], 1 << H1);
        assert_eq!(g.squares_behind_blocker[G7][B2], 1 << A1);
        assert_eq!(g.squares_behind_blocker[D7][D7], 0);
        assert_eq!(g.squares_behind_blocker[D7][F8], 0);
        assert_eq!(g.squares_between_including[A1][A4] | g.squares_behind_blocker[A1][A4],
                   g.squares_at_line[A1][A4]);
    }
}
<commit_msg>Pake grid fields private.<commit_after>use basetypes::*;

pub struct BoardGeometry {
    grid: [u8; 120],
    piece_grid_deltas: [[i8; 8]; 5],
    pub piece_longrange: [bool; 5],
    pub attacks: [[u64; 64]; 5],
    pub blockers_and_beyond: [[u64; 64]; 5],
    pub squares_at_line: [[u64; 64]; 64],
    pub squares_between_including: [[u64; 64]; 64],
    pub squares_behind_blocker: [[u64; 64]; 64],
}

impl BoardGeometry {
    pub fn new() -> BoardGeometry {
        // We use 10x12 grid (8x8 with guarding markers, 2 at top and
        // bottom, 1 at the sides), so that we can detect out-of-board
        // movements. Each cell in the grid contains the corresponding
        // square number (from 0 to 63) or 0xff (the guarding marker).
        let mut grid = [0xffu8; 120];
        for i in 0..64 {
            grid[BoardGeometry::grid_index_from_square(i)] = i as u8;
        }

        // "piece_deltas" represent the change in the grid-index when
        // sliding a particular piece by one square in a particular
        // direction. We are not concerned with pawns here.
        let mut piece_grid_deltas = [[0i8; 8]; 5];
        piece_grid_deltas[QUEEN] = [-11, -10, -9, -1, 1, 9, 10, 11];
        piece_grid_deltas[ROOK] = [0, -10, 0, -1, 1, 0, 10, 0];
        piece_grid_deltas[BISHOP] = [-11, 0, -9, 0, 0, 9, 0, 11];
        piece_grid_deltas[KNIGHT] = [-21, -19, -12, -8, 8, 12, 19, 21];
        piece_grid_deltas[KING] = [-11, -10, -9, -1, 1, 9, 10, 11];

        // All pieces except knights and kings are long-range (They
        // can slide by more than one square). We are not concerned
        // with pawns here.
        let mut piece_longrange = [true; 5];
        piece_longrange[KNIGHT] = false;
        piece_longrange[KING] = false;

        let mut g = BoardGeometry {
            grid: grid,
            piece_grid_deltas: piece_grid_deltas,
            piece_longrange: piece_longrange,
            attacks: [[0u64; 64]; 5],
            blockers_and_beyond: [[0u64; 64]; 5],
            squares_at_line: [[0u64; 64]; 64],
            squares_between_including: [[0u64; 64]; 64],
            squares_behind_blocker: [[0u64; 64]; 64],
        };

        // "attacks" and "blockers_and_beyond" fields hold attack and
        // blockers bitsets for each piece on each possible square.
        // For example:
        //
        // g.attacks[QUEEN][D4]  g.blockers_and_beyond[QUEEN][D4]
        // . . . 1 . . . 1       . . . . . . . .
        // 1 . . 1 . . 1 .       . . . 1 . . 1 .
        // . 1 . 1 . 1 . .       . 1 . 1 . 1 . .
        // . . 1 1 1 . . .       . . 1 1 1 . . .
        // 1 1 1 Q 1 1 1 1       . 1 1 Q 1 1 1 .
        // . . 1 1 1 . . .       . . 1 1 1 . . .
        // . 1 . 1 . 1 . .       . 1 . 1 . 1 . .
        // 1 . . 1 . . 1 .       . . . . . . . .
        //
        // g.attacks[KNIGHT][D4] g.blockers_and_beyond[KNIGHT][D4]
        // . . . . . . . .       . . . . . . . .
        // . . . . . . . .       . . . . . . . .
        // . . 1 . 1 . . .       . . . . . . . .
        // . 1 . . . 1 . .       . . . . . . . .
        // . . . N . . . .       . . . N . . . .
        // . 1 . . . 1 . .       . . . . . . . .
        // . . 1 . 1 . . .       . . . . . . . .
        // . . . . . . . .       . . . . . . . .
        g.fill_attack_and_blockers_and_beyond_arrays();

        // The "squares_behind_blocker" field holds bitsets that
        // describe all squares hidden behind a blocker from the
        // attacker's position. For example:
        //
        // g.squares_behind_blocker[B2][F6]
        // . . . . . . . 1
        // . . . . . . 1 .
        // . . . . . B . .
        // . . . . . . . .
        // . . . . . . . .
        // . . . . . . . .
        // . A . . . . . .
        // . . . . . . . .
        //
        // The "squares_between_including" field holds bitsets that
        // describe all squares between an attacker an a blocker
        // including the attacker's and blocker's fields
        // themselves. For example:
        //
        // g.squares_between_including[B2][F6]
        // . . . . . . . .
        // . . . . . . . .
        // . . . . . 1 . .
        // . . . . 1 . . .
        // . . . 1 . . . .
        // . . 1 . . . . .
        // . 1 . . . . . .
        // . . . . . . . .
        g.fill_squares_between_including_and_squares_behind_blocker_arrays();

        // The "squares_at_line" field holds bitsets that describe all
        // squares lying at the line determined by the attacker and
        // the blocker. For example:
        //
        // g.squares_at_line[B2][F6]
        // . . . . . . . 1
        // . . . . . . 1 .
        // . . . . . 1 . .
        // . . . . 1 . . .
        // . . . 1 . . . .
        // . . 1 . . . . .
        // . 1 . . . . . .
        // 1 . . . . . . .
        g.fill_squares_at_line_array();

        g
    }

    fn grid_index(&self, i: Square) -> usize {
        Self::grid_index_from_square(i)
    }

    #[inline(always)]
    fn grid_index_from_square(i: Square) -> usize {
        ((i / 8) * 10 + (i % 8) + 21)
    }

    fn fill_attack_and_blockers_and_beyond_arrays(&mut self) {
        for piece_type in 0..5 {
            for square in 0..64 {
                let mut attack = 0u64;
                let mut blockers = 0u64;
                for move_direction in 0..8 {
                    let delta = self.piece_grid_deltas[piece_type][move_direction];
                    if delta != 0 {
                        let mut last_mask = 0u64;
                        let mut curr_grid_index = self.grid_index(square);
                        loop {
                            curr_grid_index = (curr_grid_index as i8 + delta) as usize;
                            let curr_square = self.grid[curr_grid_index] as Square;
                            if curr_square != 0xff {
                                last_mask = 1 << curr_square;
                                attack |= last_mask;
                                blockers |= last_mask;
                                if self.piece_longrange[piece_type] {
                                    continue;
                                }
                            }
                            blockers &= !last_mask;
                            break;
                        }
                    }
                }
                self.attacks[piece_type][square] = attack;
                self.blockers_and_beyond[piece_type][square] = blockers;
            }
        }
    }

    fn fill_squares_between_including_and_squares_behind_blocker_arrays(&mut self) {
        for attacker in 0..64 {
            for blocker in 0..64 {
                // Try to find a grid-index increment (delta) that
                // will generate all squares at the line. If the
                // attacker and the blocker happens not to lie at a
                // straight line, then and we simply proceed to the
                // next attacker/blocker pair.
                let rank_diff = rank(blocker) as i8 - rank(attacker) as i8;
                let file_diff = file(blocker) as i8 - file(attacker) as i8;
                let delta = match (rank_diff, file_diff) {
                    (0, 0) => continue,
                    (0, f) => f.signum(),
                    (r, 0) => 10 * r.signum(),
                    (r, f) if r == f => 10 * r.signum() + r.signum(),
                    (r, f) if r == -f => 10 * r.signum() - r.signum(),
                    _ => continue,
                };

                // Starting from the attacker's square update
                // "squares_between_including" until the blocker's
                // square is encountered, then switch to updating
                // "squares_behind_blocker" until the end of the board
                // is reached.
                let mut squares_between_including = 0u64;
                let mut squares_behind_blocker = 0u64;
                let mut curr_grid_index = self.grid_index(attacker);
                let mut blocker_encountered = false;
                loop {
                    let curr_square = self.grid[curr_grid_index] as Square;
                    match curr_square {
                        0xff => {
                            break;
                        }
                        x if x == blocker => {
                            squares_between_including |= 1 << curr_square;
                            blocker_encountered = true;
                        }
                        _ => {
                            if blocker_encountered {
                                squares_behind_blocker |= 1 << curr_square;
                            } else {
                                squares_between_including |= 1 << curr_square;
                            }
                        }
                    }
                    curr_grid_index = (curr_grid_index as i8 + delta) as usize;
                }
                assert!(blocker_encountered);
                self.squares_between_including[attacker][blocker] = squares_between_including;
                self.squares_behind_blocker[attacker][blocker] = squares_behind_blocker;
            }
        }
    }

    fn fill_squares_at_line_array(&mut self) {
        for a in 0..64 {
            for b in 0..64 {
                self.squares_at_line[a][b] = self.squares_between_including[a][b] |
                                             self.squares_behind_blocker[a][b] |
                                             self.squares_behind_blocker[b][a];
            }
        }
    }
}

// Attack (or blockers and beyond) array for all sliding pieces.
pub type SlidersArray = [[u64; 64]; 5];

// The StateInfo struct stores information needed to restore a Position
// object to its previous state when we retract a move. Whenever a move
// is made on the board (by calling Position::do_move), a StateInfo
// object must be passed as a parameter.

// struct StateInfo {
//   Key pawnKey, materialKey;
//   Value npMaterial[COLOR_NB];
//   int castlingRights, rule50, pliesFromNull;
//   Score psq;
//   Square epSquare;

//   Key key;
//   Bitboard checkersBB;
//   PieceType capturedType;
//   StateInfo* previous;
// };

pub type LinesArray = [[u64; 64]; 64];

// pub fn generate_behind_and_between_arrays() -> LinesArray {

// }

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

    #[test]
    fn test_attack_sets() {
        use basetypes::*;
        let g = BoardGeometry::new();
        assert_eq!(g.attacks[KING][A1], 0b11 << 8 | 0b10);
        assert_eq!(g.blockers_and_beyond[KING][A1], 0);
        assert_eq!(g.attacks[ROOK][A1],
                   0b11111110 | 1 << 8 | 1 << 16 | 1 << 24 | 1 << 32 | 1 << 40 | 1 << 48 | 1 << 56);
        assert_eq!(g.blockers_and_beyond[ROOK][A1],
                   0b01111110 | 1 << 8 | 1 << 16 | 1 << 24 | 1 << 32 | 1 << 40 | 1 << 48 | 0 << 56);
        assert_eq!(g.attacks[KING][D4], g.attacks[KING][E4] >> 1);
        assert_eq!(g.attacks[KING][D4], g.attacks[KING][D5] >> 8);
        assert_eq!(g.attacks[KNIGHT][D4], g.attacks[KNIGHT][D5] >> 8);
        assert_eq!(g.attacks[KNIGHT][D4] & g.attacks[KING][D5], 1 << C6 | 1 << E6);
        assert_eq!(g.attacks[ROOK][D4] | g.attacks[BISHOP][D4], g.attacks[QUEEN][D4]);
        assert_eq!(g.attacks[ROOK][D4] & g.attacks[BISHOP][D4], 0);
        assert_eq!(g.attacks[KING][D4] & g.attacks[QUEEN][D4], g.attacks[KING][D4]);
        assert_eq!(g.attacks[BISHOP][E1] & g.attacks[KNIGHT][H1], 1 << F2 | 1 << G3);
    }

    #[test]
    fn test_line_sets() {
        use basetypes::*;
        let g = BoardGeometry::new();
        assert_eq!(g.squares_at_line[B1][G1], 0b11111111);
        assert_eq!(g.squares_at_line[G8][B8], 0b11111111 << 56);
        assert_eq!(g.squares_between_including[B1][G1], 0b01111110);
        assert_eq!(g.squares_between_including[G8][B8], 0b01111110 << 56);
        assert_eq!(g.squares_behind_blocker[B1][G1], 1 << H1);
        assert_eq!(g.squares_behind_blocker[G8][B8], 1 << A8);
        assert_eq!(g.squares_behind_blocker[A1][G7], 1 << H8);
        assert_eq!(g.squares_behind_blocker[H1][B7], 1 << A8);
        assert_eq!(g.squares_behind_blocker[B7][G2], 1 << H1);
        assert_eq!(g.squares_behind_blocker[G7][B2], 1 << A1);
        assert_eq!(g.squares_behind_blocker[D7][D7], 0);
        assert_eq!(g.squares_behind_blocker[D7][F8], 0);
        assert_eq!(g.squares_between_including[A1][A4] | g.squares_behind_blocker[A1][A4],
                   g.squares_at_line[A1][A4]);
    }
}
<|endoftext|>


<commit_before>use sync::{Arc, Weak};

use vec::Vec;
use vec_deque::VecDeque;

use cell::{GlobalCell, GlobalCellRef};

use sync::spin::{InterruptSpinLock, RwLock};

use thread::WaitQueue;

use net::Interface;

use hal::net::discover;

use net::Packet;
use net::defs::Device;

const MAX_QUEUE_SIZE: usize = 512;

pub static STACK: GlobalCell<StackImpl> = GlobalCell::new();

/// Uni.rs network stack
pub struct Stack;

impl Stack {
    #[doc(hidden)]
    pub fn init() {
        STACK.set(StackImpl::new());
    }

    /// Returns interfaces registered in the network stack
    pub fn interfaces<'a>() -> Interfaces<'a> {
        Interfaces {
            imp: STACK.as_ref(),
        }
    }

    #[inline]
    /// Enqueue a packet inside the `rx_queue` and notify `rx_wait`.
    ///
    /// Returns false if the `rx_queue` is full and therefor was not enqueued,
    /// true otherwise.
    ///
    /// Note: This is safe to be called from interrupt context. Indeed the
    /// `rx_queue` is not resizable so no allocation will be performed by this
    /// function.
    pub fn enqueue_rx_packet(intf: Weak<RwLock<Interface>>,
                             packet: Packet) -> bool {
        STACK.as_mut().enqueue_rx_packet(intf, packet)
    }
}

/// Reference over the list of interfaces detected
pub struct Interfaces<'a> {
    imp: GlobalCellRef<'a, StackImpl>,
}

impl<'a> Interfaces<'a> {
    #[inline]
    /// Returns the number of interfaces detected
    pub fn count(&self) -> usize {
        self.imp.interfaces.len()
    }

    #[inline]
    /// Returns the list of interfaces as an immutable slice
    pub fn as_slice(&self) -> &[Arc<RwLock<Interface>>] {
        &self.imp.interfaces[..]
    }
}

pub struct StackImpl {
    /// Interfaces registered
    interfaces: Vec<Arc<RwLock<Interface>>>,
    /// Contains packets to be processed
    rx_queue: InterruptSpinLock<VecDeque<(Weak<RwLock<Interface>>, Packet)>>,
    /// Used to wait for packet to arrive in the rx_queue
    rx_wait: WaitQueue,
}

// rx_wait is Sync
// rx_queue is protected by a spin lock
unsafe impl Sync for StackImpl {}

impl StackImpl {
    pub fn new() -> Self {
        let intfs = discover();

        if intfs.is_empty() {
            println!("Warning: Uni.rs is built with network capabilities but no interface found");
        } else {
            println!("{} interface(s) discovered:", intfs.len());

            for i in &intfs {
                println!("  - {} ({})", i.read().name_ref(),
                         i.read().hw_addr_ref());
            }
        }

        StackImpl {
            interfaces: intfs,
            rx_queue: InterruptSpinLock::new(VecDeque::with_capacity(MAX_QUEUE_SIZE)),
            rx_wait: WaitQueue::new(),
        }
    }

    /// Call refresh on every registered interface
    fn refresh_interfaces(&mut self) {
        for intf in &mut self.interfaces {
            intf.write().refresh();
        }
    }

    pub fn enqueue_rx_packet(&mut self, intf: Weak<RwLock<Interface>>,
                             packet: Packet) -> bool {
        let mut locked_rx_queue = self.rx_queue.lock();

        if locked_rx_queue.len() == MAX_QUEUE_SIZE {
            // Queue is full, we don't want to cause a reallocation in
            // interruption context. So we don't enqueue the packet
            return false;
        }

        // Enqueue the packet
        locked_rx_queue.push_back((intf, packet));

        // Wake up network thread
        self.rx_wait.unblock();

        true
    }
}
<commit_msg>net: Network thread is now started<commit_after>use sync::{Arc, Weak};

use vec::Vec;
use vec_deque::VecDeque;

use cell::{GlobalCell, GlobalCellRef};

use sync::spin::{InterruptSpinLock, RwLock};

use thread::{Scheduler, WaitQueue};

use net::Interface;

use hal::net::discover;

use net::Packet;
use net::defs::Device;

const MAX_QUEUE_SIZE: usize = 512;

pub static STACK: GlobalCell<StackImpl> = GlobalCell::new();

/// Uni.rs network stack
pub struct Stack;

impl Stack {
    #[doc(hidden)]
    pub fn init() {
        STACK.set(StackImpl::new());

        // Spawn the network thread
        Scheduler::spawn(move || {
            StackImpl::network_thread();
        });
    }

    /// Returns interfaces registered in the network stack
    pub fn interfaces<'a>() -> Interfaces<'a> {
        Interfaces {
            imp: STACK.as_ref(),
        }
    }

    #[inline]
    /// Enqueue a packet inside the `rx_queue` and notify `rx_wait`.
    ///
    /// Returns false if the `rx_queue` is full and therefor was not enqueued,
    /// true otherwise.
    ///
    /// Note: This is safe to be called from interrupt context. Indeed the
    /// `rx_queue` is not resizable so no allocation will be performed by this
    /// function.
    pub fn enqueue_rx_packet(intf: Weak<RwLock<Interface>>,
                             packet: Packet) -> bool {
        STACK.as_mut().enqueue_rx_packet(intf, packet)
    }
}

/// Reference over the list of interfaces detected
pub struct Interfaces<'a> {
    imp: GlobalCellRef<'a, StackImpl>,
}

impl<'a> Interfaces<'a> {
    #[inline]
    /// Returns the number of interfaces detected
    pub fn count(&self) -> usize {
        self.imp.interfaces.len()
    }

    #[inline]
    /// Returns the list of interfaces as an immutable slice
    pub fn as_slice(&self) -> &[Arc<RwLock<Interface>>] {
        &self.imp.interfaces[..]
    }
}

pub struct StackImpl {
    /// Interfaces registered
    interfaces: Vec<Arc<RwLock<Interface>>>,
    /// Contains packets to be processed
    rx_queue: InterruptSpinLock<VecDeque<(Weak<RwLock<Interface>>, Packet)>>,
    /// Used to wait for packet to arrive in the rx_queue
    rx_wait: WaitQueue,
}

// rx_wait is Sync
// rx_queue is protected by a spin lock
unsafe impl Sync for StackImpl {}

impl StackImpl {
    pub fn network_thread() {
        // Get a mutable reference from the start so that we don't have to use
        // the GlobalCell for every packet.
        let imp: &mut StackImpl = &mut *STACK.as_mut();

        loop {
            let pkt_opt = imp.rx_queue.lock().pop_front();

            match pkt_opt {
                None => {
                    imp.refresh_interfaces();
                    // No packet to process => wait for one to come
                    wait_event!(imp.rx_wait, !imp.rx_queue.lock().is_empty());
                    imp.refresh_interfaces();
                }
                Some((weak_intf, pkt)) => {
                    // Treat the packet
                    println!("New incoming packet!");
                }
            }
        }
    }

    pub fn new() -> Self {
        let intfs = discover();

        if intfs.is_empty() {
            println!("Warning: Uni.rs is built with network capabilities but no interface found");
        } else {
            println!("{} interface(s) discovered:", intfs.len());

            for i in &intfs {
                println!("  - {} ({})", i.read().name_ref(),
                         i.read().hw_addr_ref());
            }
        }

        StackImpl {
            interfaces: intfs,
            rx_queue: InterruptSpinLock::new(VecDeque::with_capacity(MAX_QUEUE_SIZE)),
            rx_wait: WaitQueue::new(),
        }
    }

    /// Call refresh on every registered interface
    fn refresh_interfaces(&mut self) {
        for intf in &mut self.interfaces {
            intf.write().refresh();
        }
    }

    pub fn enqueue_rx_packet(&mut self, intf: Weak<RwLock<Interface>>,
                             packet: Packet) -> bool {
        let mut locked_rx_queue = self.rx_queue.lock();

        if locked_rx_queue.len() == MAX_QUEUE_SIZE {
            // Queue is full, we don't want to cause a reallocation in
            // interruption context. So we don't enqueue the packet
            return false;
        }

        // Enqueue the packet
        locked_rx_queue.push_back((intf, packet));

        // Wake up network thread
        self.rx_wait.unblock();

        true
    }
}
<|endoftext|>


<commit_before>extern crate byteorder;

use commons::HASH_SIZE;
use pool::{ACTION_REQUEST_DATA, ACTION_REQUEST_DESCRIPTION, ACTION_SEND_DATA, ACTION_SEND_DESCRIPTION, MAGIC_NUMBER,
           PROTOCOL_VERSION};
use pool::Pool;
use self::byteorder::{BigEndian, ByteOrder};
use std::cmp::max;
use std::net::SocketAddr;
use std::net::UdpSocket;
use std::path::PathBuf;
use std::thread::sleep;
use std::time::{Duration, SystemTime};

pub struct Network
{
    socket: UdpSocket,
    client: bool,
    send_address: SocketAddr,
    pool: Pool,
    megabit_per_second: f64,
}

impl Network
{
    fn sanity_check(&self, header: &[u8; 6]) -> bool
    {
        let mut buffer: [u8; 6] = [0; 6];
        BigEndian::write_u32(&mut buffer[0..4], MAGIC_NUMBER);
        BigEndian::write_u16(&mut buffer[4..6], PROTOCOL_VERSION);
        return header.clone() == buffer;
    }

    pub fn run(&mut self)
    {
        if self.client
        {
            let mut finished = false;
            'outer: while !finished
            {
                let mut started = SystemTime::now();
                while started.elapsed().unwrap() < Duration::from_millis(2500)
                {
                    let mut buffer: [u8; 1 << 16] = [0; 1 << 16];
                    let buffer_size = match self.socket.recv_from(&mut buffer)
                    {
                        Err(_) => 0,
                        Ok(n) => n.0,
                    };
                    if buffer_size < 7
                    {
                        continue;
                    }
                    let mut head: [u8; 6] = [0; 6];
                    head.clone_from_slice(&buffer[0..6]);
                    if !self.sanity_check(&head)
                    {
                        continue;
                    }
                    if buffer[6] != ACTION_SEND_DESCRIPTION
                    {
                        continue;
                    }
                    let mut v = Vec::new();
                    v.extend_from_slice(&buffer[7..buffer_size]);
                    finished = self.pool.process_binary_description(&v);
                    if finished
                    {
                        break 'outer;
                    }
                    started = SystemTime::now();
                    println!("Asking for files description: {} left", self.pool.desc_left());
                }
                let mut send_request: Vec<u8> = Vec::new();
                let mut buffer: [u8; 128] = [0; 128];
                // Magic number
                BigEndian::write_u32(&mut buffer[0..4], MAGIC_NUMBER);
                send_request.extend_from_slice(&buffer[0..4]);
                // Protocol version
                BigEndian::write_u16(&mut buffer[0..2], PROTOCOL_VERSION);
                send_request.extend_from_slice(&buffer[0..2]);
                // Action
                send_request.push(ACTION_REQUEST_DESCRIPTION);
                let _ = match self.socket.send_to(send_request.as_slice(), &self.send_address)
                {
                    Err(why) => panic!("Cannot send request for description: {}", why),
                    Ok(n) => n,
                };
            }
        }
        while self.client
        {
            if self.pool.is_complete()
            {
                return;
            }
            let mut buffer: [u8; 1 << 16] = [0; 1 << 16];
            let mut buffer_size;
            let mut count = 0;
            loop
            {
                println!("~{} kibibytes left", self.pool.chunks_left() * 60000 / 1024);
                if count > 40000 / HASH_SIZE
                {
                    break;
                }
                // TODO: if someone flood us with garbage this cycle never ends
                buffer_size = match self.socket.recv_from(&mut buffer)
                {
                    Err(_) => 0,
                    Ok(n) => n.0,
                };
                if buffer_size == 0
                {
                    break;
                }
                if buffer_size < 7
                {
                    continue;
                }
                let mut head: [u8; 6] = [0; 6];
                head.clone_from_slice(&buffer[0..6]);
                if !self.sanity_check(&head)
                {
                    continue;
                }
                if buffer[6] == ACTION_SEND_DATA
                {
                    count += 1;
                    let mut v: Vec<u8> = Vec::new();
                    v.extend_from_slice(&buffer[7..buffer_size]);
                    self.pool.process_binary_data(&v);
                    if self.pool.is_complete()
                    {
                        return;
                    }
                }
            }
            let send_req = self.pool.get_binary_chunk_request();
            let _ = self.socket.send_to(send_req.as_slice(), &self.send_address);
        }
        let mut send_started = SystemTime::now();
        while !self.client
        {
            println!("Queue length: {}", self.pool.get_queue_size());
            let packet = self.pool.get_binary_send_packet();
            if packet.is_none()
            {
                let _ = self.socket.set_nonblocking(false);
            }
            else
            {
                let unwrapped_packet = packet.unwrap();
                let _ = self.socket.send_to(unwrapped_packet.as_slice(), &self.send_address);
                let converted_size: f64 = (unwrapped_packet.len() as f64) * 8.0 / 1000000.0;
                let milli_stop: u64 = (converted_size * 1000.0 / self.megabit_per_second) as u64;
                let _ = self.socket.set_nonblocking(true);
                sleep(Duration::from_millis(milli_stop));
            }
            let mut buffer: [u8; 1 << 16] = [0; 1 << 16];
            let buffer_size = match self.socket.recv_from(&mut buffer)
            {
                Err(_) => 0,
                Ok(n) => n.0,
            };
            if buffer_size < 7
            {
                continue;
            }
            let mut head: [u8; 6] = [0; 6];
            head.clone_from_slice(&buffer[0..6]);
            if !self.sanity_check(&head)
            {
                continue;
            }
            if buffer[6] == ACTION_REQUEST_DATA
            {
                let mut v: Vec<u8> = Vec::new();
                v.extend_from_slice(&buffer[7..buffer_size]);
                self.pool.process_binary_chunk_request(&v);
            }
            if buffer[6] == ACTION_REQUEST_DESCRIPTION || send_started.elapsed().unwrap().as_secs() >= 10
            {
                send_started = SystemTime::now();
                let b = self.pool.generate_binary_description();
                for bv in &b
                {
                    let _ = self.socket.send_to(bv.as_slice(), &self.send_address);
                    sleep(max(Duration::from_millis((480.0 / self.megabit_per_second) as u64), Duration::from_millis(1)));
                }
            }
        }
    }

    pub fn new(files: &Vec<PathBuf>, _client: bool, _send_address: &SocketAddr, _megabit_per_second: f64) -> Network
    {
        let sock = match if _client
        {
            UdpSocket::bind("0.0.0.0:31415")
        }
        else
        {
            UdpSocket::bind("0.0.0.0:31416")
        }
        {
            Err(why) => panic!("Cannot create socket: {}", why),
            Ok(s) => s,
        };
        if _client
        {
            let mut bootstrap_packet: [u8; 1 << 16] = [0; 1 << 16];
            let mut bootstrap_packet_size: usize;
            let mut send_request: Vec<u8> = Vec::new();
            let mut buffer: [u8; 128] = [0; 128];
            // Magic number
            BigEndian::write_u32(&mut buffer[0..4], MAGIC_NUMBER);
            send_request.extend_from_slice(&buffer[0..4]);
            // Protocol version
            BigEndian::write_u16(&mut buffer[0..2], PROTOCOL_VERSION);
            send_request.extend_from_slice(&buffer[0..2]);
            // Action
            send_request.push(ACTION_REQUEST_DESCRIPTION);
            let _ = match sock.set_read_timeout(Some(Duration::from_millis(20)))
            {
                Err(why) => panic!("Cannot set read timeout: {}", why),
                Ok(_) => 0,
            };
            loop
            {
                let _ = match sock.send_to(send_request.as_slice(), &_send_address)
                {
                    Err(why) => panic!("Cannot send request for description: {}", why),
                    Ok(n) => n,
                };
                bootstrap_packet_size = match sock.recv_from(&mut bootstrap_packet)
                {
                    Err(_) => 0,
                    Ok(v) => v.0,
                };
                if bootstrap_packet_size < 7
                {
                    continue;
                }
                if BigEndian::read_u32(&bootstrap_packet[0..4]) != MAGIC_NUMBER
                {
                    continue;
                }
                if BigEndian::read_u16(&bootstrap_packet[4..6]) != PROTOCOL_VERSION
                {
                    println!("Protocol version mismatch");
                    continue;
                }
                if bootstrap_packet[6] != ACTION_SEND_DESCRIPTION
                {
                    continue;
                }
                break;
            }
            let mut vec_boostrap = Vec::new();
            vec_boostrap.extend_from_slice(&bootstrap_packet[7..bootstrap_packet_size]);
            return Network {
                socket: sock,
                client: true,
                send_address: _send_address.clone(),
                pool: Pool::new(files, Some(vec_boostrap)),
                megabit_per_second: _megabit_per_second,
            };
        }
        else
        {
            let _ = match sock.set_broadcast(true)
            {
                Err(why) => panic!("Cannot enable broadcast transmission: {}", why),
                Ok(_) => 0,
            };
            return Network {
                socket: sock,
                client: false,
                send_address: _send_address.clone(),
                pool: Pool::new(files, None),
                megabit_per_second: _megabit_per_second,
            };
        }
    }
}
<commit_msg>Don't spam info on terminal<commit_after>extern crate byteorder;

use commons::HASH_SIZE;
use pool::{ACTION_REQUEST_DATA, ACTION_REQUEST_DESCRIPTION, ACTION_SEND_DATA, ACTION_SEND_DESCRIPTION, MAGIC_NUMBER,
           PROTOCOL_VERSION};
use pool::Pool;
use self::byteorder::{BigEndian, ByteOrder};
use std::cmp::max;
use std::net::SocketAddr;
use std::net::UdpSocket;
use std::path::PathBuf;
use std::thread::sleep;
use std::time::{Duration, SystemTime};

pub struct Network
{
    socket: UdpSocket,
    client: bool,
    send_address: SocketAddr,
    pool: Pool,
    megabit_per_second: f64,
}

impl Network
{
    fn sanity_check(&self, header: &[u8; 6]) -> bool
    {
        let mut buffer: [u8; 6] = [0; 6];
        BigEndian::write_u32(&mut buffer[0..4], MAGIC_NUMBER);
        BigEndian::write_u16(&mut buffer[4..6], PROTOCOL_VERSION);
        return header.clone() == buffer;
    }

    pub fn run(&mut self)
    {
        println!("Program started!");
        if self.client
        {
            let mut finished = false;
            'outer: while !finished
            {
                let mut started = SystemTime::now();
                while started.elapsed().unwrap() < Duration::from_millis(2500)
                {
                    let mut buffer: [u8; 1 << 16] = [0; 1 << 16];
                    let buffer_size = match self.socket.recv_from(&mut buffer)
                    {
                        Err(_) => 0,
                        Ok(n) => n.0,
                    };
                    if buffer_size < 7
                    {
                        continue;
                    }
                    let mut head: [u8; 6] = [0; 6];
                    head.clone_from_slice(&buffer[0..6]);
                    if !self.sanity_check(&head)
                    {
                        continue;
                    }
                    if buffer[6] != ACTION_SEND_DESCRIPTION
                    {
                        continue;
                    }
                    let mut v = Vec::new();
                    v.extend_from_slice(&buffer[7..buffer_size]);
                    finished = self.pool.process_binary_description(&v);
                    if finished
                    {
                        break 'outer;
                    }
                    started = SystemTime::now();
                    println!("Asking for files description: {} left", self.pool.desc_left());
                }
                let mut send_request: Vec<u8> = Vec::new();
                let mut buffer: [u8; 128] = [0; 128];
                // Magic number
                BigEndian::write_u32(&mut buffer[0..4], MAGIC_NUMBER);
                send_request.extend_from_slice(&buffer[0..4]);
                // Protocol version
                BigEndian::write_u16(&mut buffer[0..2], PROTOCOL_VERSION);
                send_request.extend_from_slice(&buffer[0..2]);
                // Action
                send_request.push(ACTION_REQUEST_DESCRIPTION);
                let _ = match self.socket.send_to(send_request.as_slice(), &self.send_address)
                {
                    Err(why) => panic!("Cannot send request for description: {}", why),
                    Ok(n) => n,
                };
            }
        }
        let mut last_print = SystemTime::now();
        while self.client
        {
            if self.pool.is_complete()
            {
                return;
            }
            let mut buffer: [u8; 1 << 16] = [0; 1 << 16];
            let mut buffer_size;
            let mut count = 0;
            loop
            {
                if last_print.elapsed().unwrap().as_secs() > 1
                {
                    last_print = SystemTime::now();
                    println!("~{} kibibytes left", self.pool.chunks_left() * 60000 / 1024);
                }
                if count > 40000 / HASH_SIZE
                {
                    break;
                }
                // TODO: if someone flood us with garbage this cycle never ends
                buffer_size = match self.socket.recv_from(&mut buffer)
                {
                    Err(_) => 0,
                    Ok(n) => n.0,
                };
                if buffer_size == 0
                {
                    break;
                }
                if buffer_size < 7
                {
                    continue;
                }
                let mut head: [u8; 6] = [0; 6];
                head.clone_from_slice(&buffer[0..6]);
                if !self.sanity_check(&head)
                {
                    continue;
                }
                if buffer[6] == ACTION_SEND_DATA
                {
                    count += 1;
                    let mut v: Vec<u8> = Vec::new();
                    v.extend_from_slice(&buffer[7..buffer_size]);
                    self.pool.process_binary_data(&v);
                    if self.pool.is_complete()
                    {
                        return;
                    }
                }
            }
            let send_req = self.pool.get_binary_chunk_request();
            let _ = self.socket.send_to(send_req.as_slice(), &self.send_address);
        }
        let mut send_started = SystemTime::now();
        while !self.client
        {
            if last_print.elapsed().unwrap().as_secs() > 1
            {
                last_print = SystemTime::now();
                println!("Queue length: {}", self.pool.get_queue_size());
            }
            let packet = self.pool.get_binary_send_packet();
            if packet.is_none()
            {
                let _ = self.socket.set_nonblocking(false);
            }
            else
            {
                let unwrapped_packet = packet.unwrap();
                let _ = self.socket.send_to(unwrapped_packet.as_slice(), &self.send_address);
                let converted_size: f64 = (unwrapped_packet.len() as f64) * 8.0 / 1000000.0;
                let milli_stop: u64 = (converted_size * 1000.0 / self.megabit_per_second) as u64;
                let _ = self.socket.set_nonblocking(true);
                sleep(Duration::from_millis(milli_stop));
            }
            let mut buffer: [u8; 1 << 16] = [0; 1 << 16];
            let buffer_size = match self.socket.recv_from(&mut buffer)
            {
                Err(_) => 0,
                Ok(n) => n.0,
            };
            if buffer_size < 7
            {
                continue;
            }
            let mut head: [u8; 6] = [0; 6];
            head.clone_from_slice(&buffer[0..6]);
            if !self.sanity_check(&head)
            {
                continue;
            }
            if buffer[6] == ACTION_REQUEST_DATA
            {
                let mut v: Vec<u8> = Vec::new();
                v.extend_from_slice(&buffer[7..buffer_size]);
                self.pool.process_binary_chunk_request(&v);
            }
            if buffer[6] == ACTION_REQUEST_DESCRIPTION || send_started.elapsed().unwrap().as_secs() >= 10
            {
                send_started = SystemTime::now();
                let b = self.pool.generate_binary_description();
                for bv in &b
                {
                    let _ = self.socket.send_to(bv.as_slice(), &self.send_address);
                    sleep(max(Duration::from_millis((480.0 / self.megabit_per_second) as u64), Duration::from_millis(1)));
                }
            }
        }
    }

    pub fn new(files: &Vec<PathBuf>, _client: bool, _send_address: &SocketAddr, _megabit_per_second: f64) -> Network
    {
        let sock = match if _client
        {
            UdpSocket::bind("0.0.0.0:31415")
        }
        else
        {
            UdpSocket::bind("0.0.0.0:31416")
        }
        {
            Err(why) => panic!("Cannot create socket: {}", why),
            Ok(s) => s,
        };
        if _client
        {
            let mut bootstrap_packet: [u8; 1 << 16] = [0; 1 << 16];
            let mut bootstrap_packet_size: usize;
            let mut send_request: Vec<u8> = Vec::new();
            let mut buffer: [u8; 128] = [0; 128];
            // Magic number
            BigEndian::write_u32(&mut buffer[0..4], MAGIC_NUMBER);
            send_request.extend_from_slice(&buffer[0..4]);
            // Protocol version
            BigEndian::write_u16(&mut buffer[0..2], PROTOCOL_VERSION);
            send_request.extend_from_slice(&buffer[0..2]);
            // Action
            send_request.push(ACTION_REQUEST_DESCRIPTION);
            let _ = match sock.set_read_timeout(Some(Duration::from_millis(20)))
            {
                Err(why) => panic!("Cannot set read timeout: {}", why),
                Ok(_) => 0,
            };
            loop
            {
                let _ = match sock.send_to(send_request.as_slice(), &_send_address)
                {
                    Err(why) => panic!("Cannot send request for description: {}", why),
                    Ok(n) => n,
                };
                bootstrap_packet_size = match sock.recv_from(&mut bootstrap_packet)
                {
                    Err(_) => 0,
                    Ok(v) => v.0,
                };
                if bootstrap_packet_size < 7
                {
                    continue;
                }
                if BigEndian::read_u32(&bootstrap_packet[0..4]) != MAGIC_NUMBER
                {
                    continue;
                }
                if BigEndian::read_u16(&bootstrap_packet[4..6]) != PROTOCOL_VERSION
                {
                    println!("Protocol version mismatch");
                    continue;
                }
                if bootstrap_packet[6] != ACTION_SEND_DESCRIPTION
                {
                    continue;
                }
                break;
            }
            let mut vec_boostrap = Vec::new();
            vec_boostrap.extend_from_slice(&bootstrap_packet[7..bootstrap_packet_size]);
            return Network {
                socket: sock,
                client: true,
                send_address: _send_address.clone(),
                pool: Pool::new(files, Some(vec_boostrap)),
                megabit_per_second: _megabit_per_second,
            };
        }
        else
        {
            let _ = match sock.set_broadcast(true)
            {
                Err(why) => panic!("Cannot enable broadcast transmission: {}", why),
                Ok(_) => 0,
            };
            return Network {
                socket: sock,
                client: false,
                send_address: _send_address.clone(),
                pool: Pool::new(files, None),
                megabit_per_second: _megabit_per_second,
            };
        }
    }
}
<|endoftext|>


<commit_before>use std::f64::EPSILON;

use types::{Objective, DifferentiableObjective};

pub struct Numeric<T: Objective> {
    objective: T
}

impl<T: Objective> Numeric<T> {
    pub fn new(objective: T) -> Self {
        Numeric {
            objective: objective
        }
    }
}

impl<T: Objective> Objective for Numeric<T> {
    fn value(&self, x: &[f64]) -> f64 {
        self.objective.value(x)
    }
}

impl<T: Objective> DifferentiableObjective for Numeric<T> {
    fn gradient(&self, x: &[f64]) -> Vec<f64> {
        let mut x2: Vec<_> = x.iter().cloned().collect();

        const h: f64 = 1.0;// 2.2204460492503131e-10;
        const h2: f64 = h + h;

        (0..x.len()).map(|i| {
            x2[i] = x[i] + h;
            let upper = self.objective.value(&x2);

            x2[i] = x[i] - h;
            let lower = self.objective.value(&x2);

            x2[i] = x[i];

            (upper - lower) / h2
        }).collect()
    }
}
<commit_msg>Start adjusting the numerical diff<commit_after>use std::f64::EPSILON;

use types::{Function, DifferentiableFunction};

const EPSILON: f64 = 2.2204460492503131e-6;

/// Wraps a function for which to provide numeric gradient computation.
pub struct NumericDifferentiation<F: Function> {
    function: F
}

impl<F: Function> NumericalDifferentiation<F> {
    pub fn new(function: F) -> Self {
        NumericalDifferentiation {
            function: function
        }
    }
}

impl<F: Function> Function for NumericDifferentiation<F> {
    fn value(&self, position: &[f64]) -> f64 {
        self.function.value(position)
    }
}

impl<F: Function> DifferentiableObjective for NumericDifferentiation<F> {
    fn gradient(&self, x: &[f64]) -> Vec<f64> {
        let mut x2: Vec<_> = x.iter().cloned().collect();

        const h: f64 = EPSILON;
        const h2: f64 = h + h;

        (0..x.len()).map(|i| {
            x2[i] = x[i] + h;
            let upper = self.objective.value(&x2);

            x2[i] = x[i] - h;
            let lower = self.objective.value(&x2);

            x2[i] = x[i];

            (upper - lower) / h2
        }).collect()
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A trait that can provide the `Span` of the complete contents of a syntax
//! tree node.
//!
//! *This module is available if Syn is built with both the `"parsing"` and
//! `"printing"` features.*
//!
//! # Example
//!
//! Suppose in a procedural macro we have a [`Type`] that we want to assert
//! implements the [`Sync`] trait. Maybe this is the type of one of the fields
//! of a struct for which we are deriving a trait implementation, and we need to
//! be able to pass a reference to one of those fields across threads.
//!
//! [`Type`]: ../enum.Type.html
//! [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
//!
//! If the field type does *not* implement `Sync` as required, we want the
//! compiler to report an error pointing out exactly which type it was.
//!
//! The following macro code takes a variable `ty` of type `Type` and produces a
//! static assertion that `Sync` is implemented for that type.
//!
//! ```
//! # extern crate proc_macro;
//! # extern crate proc_macro2;
//! # extern crate syn;
//! #
//! #[macro_use]
//! extern crate quote;
//!
//! use proc_macro::TokenStream;
//! use proc_macro2::Span;
//! use syn::Type;
//! use syn::spanned::Spanned;
//!
//! # const IGNORE_TOKENS: &str = stringify! {
//! #[proc_macro_derive(MyMacro)]
//! # };
//! pub fn my_macro(input: TokenStream) -> TokenStream {
//!     # let ty = get_a_type();
//!     /* ... */
//!
//!     let assert_sync = quote_spanned! {ty.span()=>
//!         struct _AssertSync where #ty: Sync;
//!     };
//!
//!     /* ... */
//!     # input
//! }
//! #
//! # fn get_a_type() -> Type {
//! #     unimplemented!()
//! # }
//! #
//! # fn main() {}
//! ```
//!
//! By inserting this `assert_sync` fragment into the output code generated by
//! our macro, the user's code will fail to compile if `ty` does not implement
//! `Sync`. The errors they would see look like the following.
//!
//! ```text
//! error[E0277]: the trait bound `*const i32: std::marker::Sync` is not satisfied
//!   --> src/main.rs:10:21
//!    |
//! 10 |     bad_field: *const i32,
//!    |                ^^^^^^^^^^ `*const i32` cannot be shared between threads safely
//! ```
//!
//! In this technique, using the `Type`'s span for the error message makes the
//! error appear in the correct place underlining the right type.

use proc_macro2::{Span, TokenStream};
use quote::ToTokens;

/// A trait that can provide the `Span` of the complete contents of a syntax
/// tree node.
///
/// This trait is automatically implemented for all types that implement
/// [`ToTokens`] from the `quote` crate. It is sealed and cannot be implemented
/// outside of the Syn crate other than by implementing `ToTokens`.
///
/// [`ToTokens`]: https://docs.rs/quote/0.6/quote/trait.ToTokens.html
///
/// See the [module documentation] for an example.
///
/// [module documentation]: index.html
///
/// *This trait is available if Syn is built with both the `"parsing"` and
/// `"printing"` features.*
pub trait Spanned: private::Sealed {
    /// Returns a `Span` covering the complete contents of this syntax tree
    /// node, or [`Span::call_site()`] if this node is empty.
    ///
    /// [`Span::call_site()`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.Span.html#method.call_site
    fn span(&self) -> Span;
}

mod private {
    use quote::ToTokens;
    pub trait Sealed {}
    impl<T: ToTokens> Sealed for T {}
}

impl<T> Spanned for T
where
    T: ToTokens,
{
    #[cfg(procmacro2_semver_exempt)]
    fn span(&self) -> Span {
        let mut tokens = TokenStream::new();
        self.to_tokens(&mut tokens);
        let mut iter = tokens.into_iter();
        let mut span = match iter.next() {
            Some(tt) => tt.span(),
            None => {
                return Span::call_site();
            }
        };
        for tt in iter {
            if let Some(joined) = span.join(tt.span()) {
                span = joined;
            }
        }
        span
    }

    #[cfg(not(procmacro2_semver_exempt))]
    fn span(&self) -> Span {
        let mut tokens = TokenStream::new();
        self.to_tokens(&mut tokens);
        let mut iter = tokens.into_iter();

        // We can't join spans without procmacro2_semver_exempt so just grab the
        // first one.
        match iter.next() {
            Some(tt) => tt.span(),
            None => Span::call_site(),
        }
    }
}
<commit_msg>Check for invalid spans, and if so, use Span::call_site() instead<commit_after>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A trait that can provide the `Span` of the complete contents of a syntax
//! tree node.
//!
//! *This module is available if Syn is built with both the `"parsing"` and
//! `"printing"` features.*
//!
//! # Example
//!
//! Suppose in a procedural macro we have a [`Type`] that we want to assert
//! implements the [`Sync`] trait. Maybe this is the type of one of the fields
//! of a struct for which we are deriving a trait implementation, and we need to
//! be able to pass a reference to one of those fields across threads.
//!
//! [`Type`]: ../enum.Type.html
//! [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
//!
//! If the field type does *not* implement `Sync` as required, we want the
//! compiler to report an error pointing out exactly which type it was.
//!
//! The following macro code takes a variable `ty` of type `Type` and produces a
//! static assertion that `Sync` is implemented for that type.
//!
//! ```
//! # extern crate proc_macro;
//! # extern crate proc_macro2;
//! # extern crate syn;
//! #
//! #[macro_use]
//! extern crate quote;
//!
//! use proc_macro::TokenStream;
//! use proc_macro2::Span;
//! use syn::Type;
//! use syn::spanned::Spanned;
//!
//! # const IGNORE_TOKENS: &str = stringify! {
//! #[proc_macro_derive(MyMacro)]
//! # };
//! pub fn my_macro(input: TokenStream) -> TokenStream {
//!     # let ty = get_a_type();
//!     /* ... */
//!
//!     let assert_sync = quote_spanned! {ty.span()=>
//!         struct _AssertSync where #ty: Sync;
//!     };
//!
//!     /* ... */
//!     # input
//! }
//! #
//! # fn get_a_type() -> Type {
//! #     unimplemented!()
//! # }
//! #
//! # fn main() {}
//! ```
//!
//! By inserting this `assert_sync` fragment into the output code generated by
//! our macro, the user's code will fail to compile if `ty` does not implement
//! `Sync`. The errors they would see look like the following.
//!
//! ```text
//! error[E0277]: the trait bound `*const i32: std::marker::Sync` is not satisfied
//!   --> src/main.rs:10:21
//!    |
//! 10 |     bad_field: *const i32,
//!    |                ^^^^^^^^^^ `*const i32` cannot be shared between threads safely
//! ```
//!
//! In this technique, using the `Type`'s span for the error message makes the
//! error appear in the correct place underlining the right type.

use proc_macro2::{Span, TokenStream};
use quote::ToTokens;

/// A trait that can provide the `Span` of the complete contents of a syntax
/// tree node.
///
/// This trait is automatically implemented for all types that implement
/// [`ToTokens`] from the `quote` crate. It is sealed and cannot be implemented
/// outside of the Syn crate other than by implementing `ToTokens`.
///
/// [`ToTokens`]: https://docs.rs/quote/0.6/quote/trait.ToTokens.html
///
/// See the [module documentation] for an example.
///
/// [module documentation]: index.html
///
/// *This trait is available if Syn is built with both the `"parsing"` and
/// `"printing"` features.*
pub trait Spanned: private::Sealed {
    /// Returns a `Span` covering the complete contents of this syntax tree
    /// node, or [`Span::call_site()`] if this node is empty.
    ///
    /// [`Span::call_site()`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.Span.html#method.call_site
    fn span(&self) -> Span;
}

mod private {
    use quote::ToTokens;
    pub trait Sealed {}
    impl<T: ToTokens> Sealed for T {}
}

// FIXME: This shouldn't be required, since optimally
// spans should never be invalid. This can probably be removed when
// https://github.com/rust-lang/rust/issues/43081 is resolved.
fn check_invalid_span(span: Span) -> Option<Span> {
    let debug = format!("{:?}", span);
    if debug.ends_with("bytes(0..0)") {
        None
    } else {
        Some(span)
    }
}

impl<T> Spanned for T
where
    T: ToTokens,
{
    #[cfg(procmacro2_semver_exempt)]
    fn span(&self) -> Span {
        let mut tokens = TokenStream::new();
        self.to_tokens(&mut tokens);
        tokens.into_iter().fold(None::<Span>, |span, tt| {
            check_invalid_span(tt.span()).map_or(span, |new_span| {
                span.map(|span| span.join(new_span).unwrap_or(span))
            })
        }).unwrap_or(Span::call_site())
    }

    #[cfg(not(procmacro2_semver_exempt))]
    fn span(&self) -> Span {
        let mut tokens = TokenStream::new();
        self.to_tokens(&mut tokens);

        // We can't join spans without procmacro2_semver_exempt so just grab the
        // first one.
        tokens.into_iter().next().and_then(|tt| check_invalid_span(tt.span()))
            .unwrap_or(Span::call_site())
    }
}
<|endoftext|>