<commit_before>//! Methods for converting shapes into triangles.

use std;
use {Matrix2d, Rectangle};

#[inline(always)]
fn tx(m: &Matrix2d, x: f64, y: f64) -> f32 {
    (m[0] * x + m[1] * y + m[2]) as f32
}

#[inline(always)]
fn ty(m: &Matrix2d, x: f64, y: f64) -> f32 {
    (m[3] * x + m[4] * y + m[5]) as f32
}

/// Streams an ellipse specified by a resolution.
#[inline(always)]
pub fn with_ellipse_tri_list_xy_rgba_f32(
    resolution: uint,
    m: &Matrix2d,
    rect: &Rectangle,
    color: [f32, ..4],
    f: |vertices: &[f32], colors: &[f32]|) {

    let (x, y, w, h) = (rect[0], rect[1], rect[2], rect[3]);
    let (cw, ch) = (0.5 * w, 0.5 * h);
    let (cx, cy) = (x + cw, y + ch);
    let n = resolution;
    let mut i = 0u;
    stream_polygon_tri_list_xy_rgba_f32(m, || {
        if i >= n { return None; }

        let angle = i as f64 / n as f64 * std::f64::consts::PI_2;
        i += 1;
        Some([cx + angle.cos() * cw, cy + angle.sin() * ch])
    }, color, f);
}

/// Streams a polygon into tri list with color per vertex.
/// Uses buffers that fit inside L1 cache.
pub fn stream_polygon_tri_list_xy_rgba_f32(
    m: &Matrix2d,
    polygon: || -> Option<[f64, ..2]>,
    color: [f32, ..4],
    f: |vertices: &[f32], colors: &[f32]|) {

    let mut vertices: [f32, ..740] = [0.0, ..740];
    let mut colors: [f32, ..1480] = [0.0, ..1480];
    // Draw first triangle for testing.
    // Get the first point which will be used a lot.
    let fp = match polygon() { None => return, Some(val) => val };
    let (fx, fy) = (tx(m, fp[0], fp[1]), ty(m, fp[0], fp[1]));
    let gp = match polygon() { None => return, Some(val) => val };
    let (gx, gy) = (tx(m, gp[0], gp[1]), ty(m, gp[0], gp[1]));
    let mut gx = gx;
    let mut gy = gy;
    let mut i = 0;
    'read_vertices: loop {
        // Set the first point in triangle to use the beginning.
        let ind_out = i * 2 * 3;
        vertices[ind_out + 0] = fx;
        vertices[ind_out + 1] = fy;
        let ind_out = i * 4 * 3;
        colors[ind_out + 0] = color[0];
        colors[ind_out + 1] = color[1];
        colors[ind_out + 2] = color[2];
        colors[ind_out + 3] = color[3];

        // Copy vertex.
        let ind_out = i * 2 * 3 + 2;
        let p =
            match polygon() {
                None => break 'read_vertices,
                Some(val) => val,
            };
        let x = tx(m, p[0], p[1]);
        let y = ty(m, p[0], p[1]);

        vertices[ind_out + 0] = gx;
        vertices[ind_out + 1] = gy;
        vertices[ind_out + 2] = x;
        vertices[ind_out + 3] = y;
        gx = x;
        gy = y;
        let ind_out = i * 4 * 3 + 4;
        colors[ind_out + 0] = color[0];
        colors[ind_out + 1] = color[1];
        colors[ind_out + 2] = color[2];
        colors[ind_out + 3] = color[3];
        colors[ind_out + 4] = color[0];
        colors[ind_out + 5] = color[1];
        colors[ind_out + 6] = color[2];
        colors[ind_out + 7] = color[3];

        i += 1;
        // Buffer is full.
        if i * 2 * 3 + 2 == vertices.len() {
            // Send chunk and start over.
            f(vertices.slice(0, i * 2 * 3),
                colors.slice(0, i * 4 * 3));
            i = 0;
        }
    }

    if i > 0 {
        f(vertices.slice(0, i * 2 * 3),
            colors.slice(0, i * 4 * 3));
    }
}

/// Splits polygon into convex segments with one color per vertex.
/// Create a buffer that fits into L1 cache with 1KB overhead.
pub fn with_polygon_tri_list_xy_rgba_f32(
    m: &Matrix2d,
    polygon: &[f64],
    color: [f32, ..4],
    f: |vertices: &[f32], colors: &[f32]|) {

    let n = polygon.len();
    let mut i = 0;
    stream_polygon_tri_list_xy_rgba_f32(
        m, || {
            if i >= n { return None; }

            let j = i;
            i += 2;
            Some([polygon[j], polygon[j+1]])
        }, color, f);
}

/// Creates triangle list vertices from rectangle.
pub fn rect_tri_list_xy_f32(m: &Matrix2d, rect: &Rectangle) -> [f32, ..12] {
    let (x, y, w, h) = (rect[0], rect[1], rect[2], rect[3]);
    let (x2, y2) = (x + w, y + h);
    [tx(m,x,y), ty(m,x,y), tx(m,x2,y), ty(m,x2,y), tx(m,x,y2), ty(m,x,y2),
     tx(m,x2,y), ty(m,x2,y), tx(m,x2,y2), ty(m,x2,y2), tx(m,x,y2), ty(m,x,y2)]
}

/// Creates triangle list colors from rectangle.
pub fn rect_tri_list_rgba_f32(color: [f32, ..4]) -> [f32, ..48] {
    let (r, g, b, a) = (color[0], color[1], color[2], color[3]);
    [r, g, b, a, // 0
     r, g, b, a, // 1
     r, g, b, a, // 2
     r, g, b, a, // 3
     r, g, b, a, // 4
     r, g, b, a, // 5
     r, g, b, a, // 6
     r, g, b, a, // 7
     r, g, b, a, // 8
     r, g, b, a, // 9
     r, g, b, a, // 10
     r, g, b, a]
}

<commit_msg>Added `with_round_rectangle_tri_list_xy_rgba_f32`<commit_after>//! Methods for converting shapes into triangles.

use std;
use {Matrix2d, Rectangle, RoundRectangle};

#[inline(always)]
fn tx(m: &Matrix2d, x: f64, y: f64) -> f32 {
    (m[0] * x + m[1] * y + m[2]) as f32
}

#[inline(always)]
fn ty(m: &Matrix2d, x: f64, y: f64) -> f32 {
    (m[3] * x + m[4] * y + m[5]) as f32
}

/// Streams an ellipse specified by a resolution.
#[inline(always)]
pub fn with_ellipse_tri_list_xy_rgba_f32(
    resolution: uint,
    m: &Matrix2d,
    rect: &Rectangle,
    color: [f32, ..4],
    f: |vertices: &[f32], colors: &[f32]|) {

    let (x, y, w, h) = (rect[0], rect[1], rect[2], rect[3]);
    let (cw, ch) = (0.5 * w, 0.5 * h);
    let (cx, cy) = (x + cw, y + ch);
    let n = resolution;
    let mut i = 0u;
    stream_polygon_tri_list_xy_rgba_f32(m, || {
        if i >= n { return None; }

        let angle = i as f64 / n as f64 * std::f64::consts::PI_2;
        i += 1;
        Some([cx + angle.cos() * cw, cy + angle.sin() * ch])
    }, color, f);
}

/// Streams a round rectangle.
#[inline(always)]
pub fn with_round_rectangle_tri_list_xy_rgba_f32(
    resolution_corner: uint,
    m: &Matrix2d,
    round_rect: &RoundRectangle,
    color: [f32, ..4],
    f: |vertices: &[f32], colors: &[f32]|) {

    let (x, y, w, h, radius) = (
        round_rect[0],
        round_rect[1],
        round_rect[2],
        round_rect[3],
        round_rect[4]
    );
    let n = resolution_corner * 4 + 4;
    let mut i = 0u;
    stream_polygon_tri_list_xy_rgba_f32(m, || {
        if i < n { return None; }

        let j = i;
        i += 1;
        match j {
            j if j >= resolution_corner * 3 => {
                let angle = j as f64 / (n - 3) as f64 * std::f64::consts::PI_2;
                let (cx, cy) = (x + w - radius, y + radius);
                Some([cx + angle.cos() * radius, cy + angle.sin() * radius])
            },
            j if j >= resolution_corner * 2 => {
                let angle = j as f64 / (n - 2) as f64 * std::f64::consts::PI_2;
                let (cx, cy) = (x + radius, y + radius);
                Some([cx + angle.cos() * radius, cy + angle.sin() * radius])
            },
            j if j >= resolution_corner * 1 => {
                let angle = j as f64 / (n - 1) as f64 * std::f64::consts::PI_2;
                let (cx, cy) = (x + radius, y + h - radius);
                Some([cx + angle.cos() * radius, cy + angle.sin() * radius])
            },
            j => {
                let angle = j as f64 / (n - 0) as f64 * std::f64::consts::PI_2;
                let (cx, cy) = (x + w - radius, y + h - radius);
                Some([cx + angle.cos() * radius, cy + angle.sin() * radius])
            },
        }
    }, color, f);
}

/// Streams a polygon into tri list with color per vertex.
/// Uses buffers that fit inside L1 cache.
pub fn stream_polygon_tri_list_xy_rgba_f32(
    m: &Matrix2d,
    polygon: || -> Option<[f64, ..2]>,
    color: [f32, ..4],
    f: |vertices: &[f32], colors: &[f32]|) {

    let mut vertices: [f32, ..740] = [0.0, ..740];
    let mut colors: [f32, ..1480] = [0.0, ..1480];
    // Draw first triangle for testing.
    // Get the first point which will be used a lot.
    let fp = match polygon() { None => return, Some(val) => val };
    let (fx, fy) = (tx(m, fp[0], fp[1]), ty(m, fp[0], fp[1]));
    let gp = match polygon() { None => return, Some(val) => val };
    let (gx, gy) = (tx(m, gp[0], gp[1]), ty(m, gp[0], gp[1]));
    let mut gx = gx;
    let mut gy = gy;
    let mut i = 0;
    'read_vertices: loop {
        // Set the first point in triangle to use the beginning.
        let ind_out = i * 2 * 3;
        vertices[ind_out + 0] = fx;
        vertices[ind_out + 1] = fy;
        let ind_out = i * 4 * 3;
        colors[ind_out + 0] = color[0];
        colors[ind_out + 1] = color[1];
        colors[ind_out + 2] = color[2];
        colors[ind_out + 3] = color[3];

        // Copy vertex.
        let ind_out = i * 2 * 3 + 2;
        let p =
            match polygon() {
                None => break 'read_vertices,
                Some(val) => val,
            };
        let x = tx(m, p[0], p[1]);
        let y = ty(m, p[0], p[1]);

        vertices[ind_out + 0] = gx;
        vertices[ind_out + 1] = gy;
        vertices[ind_out + 2] = x;
        vertices[ind_out + 3] = y;
        gx = x;
        gy = y;
        let ind_out = i * 4 * 3 + 4;
        colors[ind_out + 0] = color[0];
        colors[ind_out + 1] = color[1];
        colors[ind_out + 2] = color[2];
        colors[ind_out + 3] = color[3];
        colors[ind_out + 4] = color[0];
        colors[ind_out + 5] = color[1];
        colors[ind_out + 6] = color[2];
        colors[ind_out + 7] = color[3];

        i += 1;
        // Buffer is full.
        if i * 2 * 3 + 2 == vertices.len() {
            // Send chunk and start over.
            f(vertices.slice(0, i * 2 * 3),
                colors.slice(0, i * 4 * 3));
            i = 0;
        }
    }

    if i > 0 {
        f(vertices.slice(0, i * 2 * 3),
            colors.slice(0, i * 4 * 3));
    }
}

/// Splits polygon into convex segments with one color per vertex.
/// Create a buffer that fits into L1 cache with 1KB overhead.
pub fn with_polygon_tri_list_xy_rgba_f32(
    m: &Matrix2d,
    polygon: &[f64],
    color: [f32, ..4],
    f: |vertices: &[f32], colors: &[f32]|) {

    let n = polygon.len();
    let mut i = 0;
    stream_polygon_tri_list_xy_rgba_f32(
        m, || {
            if i >= n { return None; }

            let j = i;
            i += 2;
            Some([polygon[j], polygon[j+1]])
        }, color, f);
}

/// Creates triangle list vertices from rectangle.
pub fn rect_tri_list_xy_f32(m: &Matrix2d, rect: &Rectangle) -> [f32, ..12] {
    let (x, y, w, h) = (rect[0], rect[1], rect[2], rect[3]);
    let (x2, y2) = (x + w, y + h);
    [tx(m,x,y), ty(m,x,y), tx(m,x2,y), ty(m,x2,y), tx(m,x,y2), ty(m,x,y2),
     tx(m,x2,y), ty(m,x2,y), tx(m,x2,y2), ty(m,x2,y2), tx(m,x,y2), ty(m,x,y2)]
}

/// Creates triangle list colors from rectangle.
pub fn rect_tri_list_rgba_f32(color: [f32, ..4]) -> [f32, ..48] {
    let (r, g, b, a) = (color[0], color[1], color[2], color[3]);
    [r, g, b, a, // 0
     r, g, b, a, // 1
     r, g, b, a, // 2
     r, g, b, a, // 3
     r, g, b, a, // 4
     r, g, b, a, // 5
     r, g, b, a, // 6
     r, g, b, a, // 7
     r, g, b, a, // 8
     r, g, b, a, // 9
     r, g, b, a, // 10
     r, g, b, a]
}

<|endoftext|>


<commit_before>use std::thread;
use std::process;
use std::time::Instant;
use std::sync::{mpsc, Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};

use fps_clock::FpsClock;
use piston_window::{
    PistonWindow,
    WindowSettings,
    math,
};

use renderer::Renderer;
use animation::{Animation, MoveAnimation, RotateAnimation, AnimationStatus};
use state::{TurtleState, DrawingState, Path, Pen};
use radians::{self, Radians};
use {Speed, Color, Distance};

/// Types that will be shared with another thread
pub type Shared<T> = Arc<RwLock<T>>;
/// Alias to help make the types more understandable without exposing as many implementation details
pub type ReadOnlyRef<'a, T> = RwLockReadGuard<'a, T>;
pub type MutableRef<'a, T> = RwLockWriteGuard<'a, T>;

/// A structure that provides read-only access to shared state
pub struct ReadOnly {
    turtle: Shared<TurtleState>,
    drawing: Shared<DrawingState>,
    /// A temporary path for use during animations
    temporary_path: Shared<Option<Path>>,
}

impl ReadOnly {
    pub fn turtle(&self) -> ReadOnlyRef<TurtleState> {
        self.turtle.read().expect("bug: Lock was poisoned")
    }

    pub fn drawing(&self) -> ReadOnlyRef<DrawingState> {
        self.drawing.read().expect("bug: Lock was poisoned")
    }

    pub fn temporary_path(&self) -> ReadOnlyRef<Option<Path>> {
        self.temporary_path.read().expect("bug: Lock was poisoned")
    }
}

pub struct TurtleWindow {
    thread_handle: Option<thread::JoinHandle<()>>,
    /// Channel for sending completed paths so they can be stored and re-rendered
    /// in the rendering thread
    paths_channel: mpsc::Sender<Path>,

    turtle: Shared<TurtleState>,
    drawing: Shared<DrawingState>,
    /// A temporary path for use during animations
    temporary_path: Shared<Option<Path>>,
}

impl TurtleWindow {
    pub fn new() -> TurtleWindow {
        let (paths_tx, paths_rx) = mpsc::channel();

        let mut turtle_window = Self {
            thread_handle: None,
            paths_channel: paths_tx,
            turtle: Arc::new(RwLock::new(TurtleState {
                position: [0., 0.],
                heading: Radians::from_degrees_value(90.),
                speed: Speed::Five,
                visible: true,
            })),
            drawing: Arc::new(RwLock::new(DrawingState {
                pen: Pen {
                    enabled: true,
                    thickness: 1.,
                    color: Color::Black,
                },
                background: Color::White,
            })),
            temporary_path: Arc::new(RwLock::new(None)),
        };

        let read_only = turtle_window.read_only();
        let handle = thread::spawn(move || {
            let mut window: PistonWindow = WindowSettings::new(
                "Turtle", [800, 600]
            ).exit_on_esc(true).build().unwrap();

            Renderer::new().run(&mut window, paths_rx, read_only);
        });

        turtle_window.thread_handle = Some(handle);
        turtle_window
    }

    /// Provide a read-only version of the state
    pub fn read_only(&self) -> ReadOnly {
        ReadOnly {
            turtle: self.turtle.clone(),
            drawing: self.drawing.clone(),
            temporary_path: self.temporary_path.clone(),
        }
    }

    /// Provides read-only access to the turtle state
    pub fn turtle(&self) -> ReadOnlyRef<TurtleState> {
        self.turtle.read().expect("bug: Lock was poisoned")
    }

    /// Provides mutable access to the turtle state
    pub fn turtle_mut(&self) -> MutableRef<TurtleState> {
        self.turtle.write().expect("bug: Lock was poisoned")
    }

    /// Provides read-only access to the drawing
    pub fn drawing(&self) -> ReadOnlyRef<DrawingState> {
        self.drawing.read().expect("bug: Lock was poisoned")
    }

    /// Provides mutable access to the drawing
    pub fn drawing_mut(&self) -> MutableRef<DrawingState> {
        self.drawing.write().expect("bug: Lock was poisoned")
    }

    fn set_temporary_path(&self, path: Option<Path>) {
        let mut temp = self.temporary_path.write().expect("bug: Lock was poisoned");
        *temp = path;
    }

    /// Move the turtle forward by the given distance. To move backwards, use a negative distance.
    ///
    /// The turtle's motion will be animated based on the speed
    pub fn forward(&self, distance: Distance) {
        if distance == 0. {
            return;
        }

        let TurtleState {position: start, heading, speed, ..} = *self.turtle();
        let x = distance * heading.cos();
        let y = distance * heading.sin();
        let end = math::add(start, [x, y]);

        let speed = speed.to_absolute(); // px per second
        let total_millis = distance / speed * 1000.;

        let animation = MoveAnimation {
            path: Path {
                start,
                end,
                pen: self.drawing().pen.clone(),
            },
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    /// Rotate the turtle in place by the given angle in the given direction of rotation
    pub fn rotate(&self, angle: Radians, clockwise: bool) {
        if angle == radians::ZERO {
            return;
        }

        let TurtleState {heading, speed, ..} = *self.turtle();
        let speed = speed.to_rotation(); // radians per second
        let total_millis = angle / speed * 1000.;
        let total_millis = total_millis.value();

        let animation = RotateAnimation {
            start: heading,
            delta_angle: angle,
            clockwise,
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    fn play_animation<A: Animation>(&self, animation: A) {
        let mut fps = FpsClock::new(60);
        loop {
            // We want to keep the lock for as little time as possible
            let status = {
                let mut turtle = self.turtle_mut();
                animation.advance(&mut *turtle)
            };
            match status {
                AnimationStatus::Running(path) => self.set_temporary_path(path),
                AnimationStatus::Complete(path) => {
                    if let Some(path) = path {
                        self.set_temporary_path(None);
                        match self.paths_channel.send(path) {
                            Ok(_) => {},
                            /// The channel is closed which means the window was closed
                            Err(_) => {
                                // quit immediately
                                process::exit(0);
                            },
                        };
                    }

                    break;
                },
            }

            fps.tick();
        }
    }
}

impl Drop for TurtleWindow {
    fn drop(&mut self) {
        if let Some(handle) = self.thread_handle.take() {
            handle.join().unwrap();
        }
    }
}
<commit_msg>Enforcing proper mutability on methods that should require it<commit_after>use std::thread;
use std::process;
use std::time::Instant;
use std::sync::{mpsc, Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};

use fps_clock::FpsClock;
use piston_window::{
    PistonWindow,
    WindowSettings,
    math,
};

use renderer::Renderer;
use animation::{Animation, MoveAnimation, RotateAnimation, AnimationStatus};
use state::{TurtleState, DrawingState, Path, Pen};
use radians::{self, Radians};
use {Speed, Color, Distance};

/// Types that will be shared with another thread
pub type Shared<T> = Arc<RwLock<T>>;
/// Alias to help make the types more understandable without exposing as many implementation details
pub type ReadOnlyRef<'a, T> = RwLockReadGuard<'a, T>;
pub type MutableRef<'a, T> = RwLockWriteGuard<'a, T>;

/// A structure that provides read-only access to shared state
pub struct ReadOnly {
    turtle: Shared<TurtleState>,
    drawing: Shared<DrawingState>,
    /// A temporary path for use during animations
    temporary_path: Shared<Option<Path>>,
}

impl ReadOnly {
    pub fn turtle(&self) -> ReadOnlyRef<TurtleState> {
        self.turtle.read().expect("bug: Lock was poisoned")
    }

    pub fn drawing(&self) -> ReadOnlyRef<DrawingState> {
        self.drawing.read().expect("bug: Lock was poisoned")
    }

    pub fn temporary_path(&self) -> ReadOnlyRef<Option<Path>> {
        self.temporary_path.read().expect("bug: Lock was poisoned")
    }
}

pub struct TurtleWindow {
    thread_handle: Option<thread::JoinHandle<()>>,
    /// Channel for sending completed paths so they can be stored and re-rendered
    /// in the rendering thread
    paths_channel: mpsc::Sender<Path>,

    turtle: Shared<TurtleState>,
    drawing: Shared<DrawingState>,
    /// A temporary path for use during animations
    temporary_path: Shared<Option<Path>>,
}

impl TurtleWindow {
    pub fn new() -> TurtleWindow {
        let (paths_tx, paths_rx) = mpsc::channel();

        let mut turtle_window = Self {
            thread_handle: None,
            paths_channel: paths_tx,
            turtle: Arc::new(RwLock::new(TurtleState {
                position: [0., 0.],
                heading: Radians::from_degrees_value(90.),
                speed: Speed::Five,
                visible: true,
            })),
            drawing: Arc::new(RwLock::new(DrawingState {
                pen: Pen {
                    enabled: true,
                    thickness: 1.,
                    color: Color::Black,
                },
                background: Color::White,
            })),
            temporary_path: Arc::new(RwLock::new(None)),
        };

        let read_only = turtle_window.read_only();
        let handle = thread::spawn(move || {
            let mut window: PistonWindow = WindowSettings::new(
                "Turtle", [800, 600]
            ).exit_on_esc(true).build().unwrap();

            Renderer::new().run(&mut window, paths_rx, read_only);
        });

        turtle_window.thread_handle = Some(handle);
        turtle_window
    }

    /// Provide a read-only version of the state
    pub fn read_only(&self) -> ReadOnly {
        ReadOnly {
            turtle: self.turtle.clone(),
            drawing: self.drawing.clone(),
            temporary_path: self.temporary_path.clone(),
        }
    }

    /// Provides read-only access to the turtle state
    pub fn turtle(&self) -> ReadOnlyRef<TurtleState> {
        self.turtle.read().expect("bug: Lock was poisoned")
    }

    /// Provides mutable access to the turtle state
    pub fn turtle_mut(&mut self) -> MutableRef<TurtleState> {
        self.turtle.write().expect("bug: Lock was poisoned")
    }

    /// Provides read-only access to the drawing
    pub fn drawing(&self) -> ReadOnlyRef<DrawingState> {
        self.drawing.read().expect("bug: Lock was poisoned")
    }

    /// Provides mutable access to the drawing
    pub fn drawing_mut(&mut self) -> MutableRef<DrawingState> {
        self.drawing.write().expect("bug: Lock was poisoned")
    }

    fn set_temporary_path(&mut self, path: Option<Path>) {
        let mut temp = self.temporary_path.write().expect("bug: Lock was poisoned");
        *temp = path;
    }

    /// Move the turtle forward by the given distance. To move backwards, use a negative distance.
    ///
    /// The turtle's motion will be animated based on the speed
    pub fn forward(&mut self, distance: Distance) {
        if distance == 0. {
            return;
        }

        let TurtleState {position: start, heading, speed, ..} = *self.turtle();
        let x = distance * heading.cos();
        let y = distance * heading.sin();
        let end = math::add(start, [x, y]);

        let speed = speed.to_absolute(); // px per second
        let total_millis = distance / speed * 1000.;

        let animation = MoveAnimation {
            path: Path {
                start,
                end,
                pen: self.drawing().pen.clone(),
            },
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    /// Rotate the turtle in place by the given angle in the given direction of rotation
    pub fn rotate(&mut self, angle: Radians, clockwise: bool) {
        if angle == radians::ZERO {
            return;
        }

        let TurtleState {heading, speed, ..} = *self.turtle();
        let speed = speed.to_rotation(); // radians per second
        let total_millis = angle / speed * 1000.;
        let total_millis = total_millis.value();

        let animation = RotateAnimation {
            start: heading,
            delta_angle: angle,
            clockwise,
            timer: Instant::now(),
            total_millis,
        };

        self.play_animation(animation);
    }

    fn play_animation<A: Animation>(&mut self, animation: A) {
        let mut fps = FpsClock::new(60);
        loop {
            // We want to keep the lock for as little time as possible
            let status = {
                let mut turtle = self.turtle_mut();
                animation.advance(&mut *turtle)
            };
            match status {
                AnimationStatus::Running(path) => self.set_temporary_path(path),
                AnimationStatus::Complete(path) => {
                    if let Some(path) = path {
                        self.set_temporary_path(None);
                        match self.paths_channel.send(path) {
                            Ok(_) => {},
                            /// The channel is closed which means the window was closed
                            Err(_) => {
                                // quit immediately
                                process::exit(0);
                            },
                        };
                    }

                    break;
                },
            }

            fps.tick();
        }
    }
}

impl Drop for TurtleWindow {
    fn drop(&mut self) {
        if let Some(handle) = self.thread_handle.take() {
            handle.join().unwrap();
        }
    }
}
<|endoftext|>


<commit_before>/*
 * Cymbalum, Molecular Simulation in Rust
 * Copyright (C) 2015 Guillaume Fraux
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/
*/

use std::ops::{Add, Sub, Mul, Div};

/// 3 dimensional vector type, implementing all usual operations
#[derive(Copy, Clone)]
pub struct Vector3D {
    /// First component of the vector
    pub x: f64,
    /// Second component of the vector
    pub y: f64,
    /// Third component of the vector
    pub z: f64,
}

impl Vector3D {
    /// Create a new Vector3D with components `x`, `y`, `z`
    pub fn new(x: f64, y: f64, z: f64) -> Vector3D {
        Vector3D{x: x, y: y, z: z}
    }
}

/// Add two vectors
impl Add for Vector3D {
    type Output = Vector3D;
    fn add(self, other: Vector3D) -> Vector3D {
        Vector3D::new(self.x + other.x, self.y + other.y, self.z + other.z)
    }
}

/// Substract two vectors
impl Sub for Vector3D {
    type Output = Vector3D;
    fn sub(self, other: Vector3D) -> Vector3D {
        Vector3D::new(self.x - other.x, self.y - other.y, self.z - other.z)
    }
}

/// Multiply by a scalar on the right hand side
impl Mul<f64> for Vector3D {
    type Output = Vector3D;
    fn mul(self, other: f64) -> Vector3D {
        Vector3D::new(self.x * other, self.y * other, self.z * other)
    }
}

/// Multiply by a scalar on the left hand side
impl Mul<Vector3D> for f64 {
    type Output = Vector3D;
    fn mul(self, other: Vector3D) -> Vector3D {
        Vector3D::new(self * other.x, self * other.y, self * other.z)
    }
}

/// Scalar product between vectors
impl Mul<Vector3D> for Vector3D {
    type Output = f64;
    fn mul(self, other: Vector3D) -> f64 {
        self.x * other.x + self.y * other.y + self.z * other.z
    }
}

impl Div<f64> for Vector3D {
    type Output = Vector3D;
    fn div(self, other: f64) -> Vector3D {
        Vector3D::new(self.x / other, self.y / other, self.z / other)
    }
}

/******************************************************************************/

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

    #[test]
    fn add() {
        let a = Vector3D::new(2.0, 3.5, 4.8);
        let b = Vector3D::new(6.1, -8.5, 7.3);

        let c = a + b;
        assert_eq!(c.x, 8.1);
        assert_eq!(c.y, -5.0);
        assert_eq!(c.z, 12.1);
    }

    #[test]
    fn sub() {
        let a = Vector3D::new(2.0, 3.5, 4.8);
        let b = Vector3D::new(6.1, -8.5, 7.3);

        let c = a - b;
        assert_eq!(c.x, -4.1);
        assert_eq!(c.y, 12.0);
        assert_eq!(c.z, -2.5);
    }

    #[test]
    fn mul() {
        let a = Vector3D::new(2.0, 3.5, 4.8);
        let b = 2.0;

        let c = b * a;
        assert_eq!(c.x, 4.0);
        assert_eq!(c.y, 7.0);
        assert_eq!(c.z, 9.6);

        let b = 1.5;
        let c = a * b;
        assert_eq!(c.x, 3.0);
        assert_eq!(c.y, 5.25);
        assert_eq!(c.z, 7.199999999999999);
    }

    #[test]
    fn dot_product() {
        let a = Vector3D::new(2.1, 3.5, 4.8);
        let b = Vector3D::new(6.1, -8.5, 7.3);

        let c = a * b;
        assert_eq!(c, 18.1);
    }
}
<commit_msg>Add norm and tensorial product functions<commit_after>/*
 * Cymbalum, Molecular Simulation in Rust
 * Copyright (C) 2015 Guillaume Fraux
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/
*/

use std::ops::{Add, Sub, Mul, Div};
use super::matrix::Matrix3;

/// 3 dimensional vector type, implementing all usual operations
#[derive(Copy, Clone)]
pub struct Vector3D {
    /// First component of the vector
    pub x: f64,
    /// Second component of the vector
    pub y: f64,
    /// Third component of the vector
    pub z: f64,
}

impl Vector3D {
    /// Create a new Vector3D with components `x`, `y`, `z`
    pub fn new(x: f64, y: f64, z: f64) -> Vector3D {
        Vector3D{x: x, y: y, z: z}
    }
    /// Return the squared euclidean norm of a Vector3D
    #[inline]
    pub fn norm2(&self) -> f64 {
        (*self) * (*self)
    }
    /// Return the euclidean norm of a Vector3D
    #[inline]
    pub fn norm(&self) -> f64 {
        f64::sqrt(self.norm2())
    }
    /// Normalize a Vector3D
    #[inline]
    pub fn normalize(&self) -> Vector3D {
        *self / self.norm()
    }
    /// Tensorial product between vectors
    pub fn tensorial(&self, other: &Vector3D) -> Matrix3 {
        Matrix3::new(self.x * other.x, self.x * other.y, self.x * other.z,
                     self.y * other.x, self.y * other.y, self.y * other.z,
                     self.z * other.x, self.z * other.y, self.z * other.z)
    }
}

/// Add two vectors
impl Add for Vector3D {
    type Output = Vector3D;
    fn add(self, other: Vector3D) -> Vector3D {
        Vector3D::new(self.x + other.x, self.y + other.y, self.z + other.z)
    }
}

/// Substract two vectors
impl Sub for Vector3D {
    type Output = Vector3D;
    fn sub(self, other: Vector3D) -> Vector3D {
        Vector3D::new(self.x - other.x, self.y - other.y, self.z - other.z)
    }
}

/// Multiply by a scalar on the right hand side
impl Mul<f64> for Vector3D {
    type Output = Vector3D;
    fn mul(self, other: f64) -> Vector3D {
        Vector3D::new(self.x * other, self.y * other, self.z * other)
    }
}

/// Multiply by a scalar on the left hand side
impl Mul<Vector3D> for f64 {
    type Output = Vector3D;
    fn mul(self, other: Vector3D) -> Vector3D {
        Vector3D::new(self * other.x, self * other.y, self * other.z)
    }
}

/// Scalar product between vectors
impl Mul<Vector3D> for Vector3D {
    type Output = f64;
    fn mul(self, other: Vector3D) -> f64 {
        self.x * other.x + self.y * other.y + self.z * other.z
    }
}

impl Div<f64> for Vector3D {
    type Output = Vector3D;
    fn div(self, other: f64) -> Vector3D {
        Vector3D::new(self.x / other, self.y / other, self.z / other)
    }
}

/******************************************************************************/

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

    #[test]
    fn add() {
        let a = Vector3D::new(2.0, 3.5, 4.8);
        let b = Vector3D::new(6.1, -8.5, 7.3);

        let c = a + b;
        assert_eq!(c.x, 8.1);
        assert_eq!(c.y, -5.0);
        assert_eq!(c.z, 12.1);
    }

    #[test]
    fn sub() {
        let a = Vector3D::new(2.0, 3.5, 4.8);
        let b = Vector3D::new(6.1, -8.5, 7.3);

        let c = a - b;
        assert_eq!(c.x, -4.1);
        assert_eq!(c.y, 12.0);
        assert_eq!(c.z, -2.5);
    }

    #[test]
    fn mul() {
        let a = Vector3D::new(2.0, 3.5, 4.8);
        let b = 2.0;

        let c = b * a;
        assert_eq!(c.x, 4.0);
        assert_eq!(c.y, 7.0);
        assert_eq!(c.z, 9.6);

        let b = 1.5;
        let c = a * b;
        assert_eq!(c.x, 3.0);
        assert_eq!(c.y, 5.25);
        assert_eq!(c.z, 7.199999999999999);
    }

    #[test]
    fn dot_product() {
        let a = Vector3D::new(2.1, 3.5, 4.8);
        let b = Vector3D::new(6.1, -8.5, 7.3);

        let c = a * b;
        assert_eq!(c, 18.1);
    }
}
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

use std::mem::{size_of, transmute_copy};
use std::cmp;

/// Read `$size` of bytes from `$src`, and reinterpret them
/// as type `$ty`, in little-endian order. `$ty` must implement
/// the `Default` trait. Otherwise this won't compile.
/// This is copied and modified from byteorder crate.
macro_rules! read_num_bytes {
  ($ty:ty, $size:expr, $src:expr) => ({
    assert!($size <= $src.len());
    let mut data: $ty = Default::default();
    unsafe {
      ::std::ptr::copy_nonoverlapping(
        $src.as_ptr(),
        &mut data as *mut $ty as *mut u8,
        $size);
    }
    data
  });
}

/// Return the ceil of value/divisor
#[inline]
pub fn ceil(value: i64, divisor: i64) -> i64 {
  let mut result = value / divisor;
  if value % divisor != 0 { result += 1 };
  result
}

/// Returns the `num_bits` least-significant bits of `v`
#[inline]
pub fn trailing_bits(v: u64, num_bits: usize) -> u64 {
  if num_bits == 0 {
    return 0;
  }
  if num_bits >= 64 {
    return v;
  }
  let n = 64 - num_bits;
  (v << n) >> n
}

#[inline]
pub fn set_array_bit(bits: &mut [u8], i: usize) {
  bits[i / 8] |= 1 << (i % 8);
}

#[inline]
pub fn unset_array_bit(bits: &mut [u8], i: usize) {
  bits[i / 8] &= !(1 << (i % 8));
}

/// Maximum byte length for a VLQ encoded integer
const MAX_VLQ_BYTE_LEN: usize = 5;

pub struct BitReader<'a> {
  /// The byte buffer to read from, passed in by client
  buffer: &'a [u8],

  /// Bytes are memcpy'd from `buffer` and values are read from this variable.
  /// This is faster than reading values byte by byte directly from `buffer`
  buffered_values: u64,

  /// Current byte offset in `buffer`
  byte_offset: usize,

  /// Current bit offset in `buffered_values`
  bit_offset: usize,

  /// Total number of bytes in `buffer`
  total_bytes: usize
}

impl<'a> BitReader<'a> {
  pub fn new(buffer: &'a [u8]) -> Self {
    let total_bytes = buffer.len();
    let num_bytes = cmp::min(8, total_bytes);
    let buffered_values = read_num_bytes!(u64, num_bytes, buffer);
    BitReader {
      buffer: buffer, buffered_values: buffered_values,
      byte_offset: 0, bit_offset: 0, total_bytes: total_bytes
    }
  }

  #[inline]
  pub fn reset(&mut self, buffer: &'a [u8]) {
    self.buffer = buffer;
    self.total_bytes = buffer.len();
    let num_bytes = cmp::min(8, self.total_bytes);
    self.buffered_values = read_num_bytes!(u64, num_bytes, buffer);
    self.byte_offset = 0;
    self.bit_offset = 0;
  }

  #[inline]
  pub fn get_value<T: Default>(&mut self, num_bits: usize) -> Option<T> {
    assert!(num_bits <= 32);
    assert!(num_bits <= size_of::<T>() * 8);

    if self.byte_offset * 8 + self.bit_offset + num_bits > self.total_bytes * 8 {
      return None;
    }

    //
    // |...|.........|...........|
    //     ^         ^           ^
    //     num_bits  bit_offset  byte_offset
    //
    let mut v = trailing_bits(self.buffered_values, self.bit_offset + num_bits) >> self.bit_offset;
    self.bit_offset += num_bits;

    if self.bit_offset >= 64 {
      self.byte_offset += 8;
      self.bit_offset -= 64;

      let bytes_to_read = cmp::min(self.total_bytes - self.byte_offset, 8);
      self.buffered_values = read_num_bytes!(
        u64, bytes_to_read, self.buffer[self.byte_offset..]);

      v |= trailing_bits(self.buffered_values, self.bit_offset) << (num_bits - self.bit_offset);
    }

    // TODO: better to avoid copying here
    let result: T = unsafe {
      transmute_copy::<u64, T>(&v)
    };
    Some(result)
  }

  /// Read a `num_bytes`-sized value from this buffer and return it.
  /// `T` needs to be a little-endian native type. The value is assumed to
  /// be byte aligned so the bit reader will be advanced to the start of
  /// the next byte before reading the value. Return `None` if there's not
  /// enough bytes left.
  #[inline]
  pub fn get_aligned<T: Default>(&mut self, num_bytes: usize) -> Option<T> {
    let bytes_read = ceil(self.bit_offset as i64, 8) as usize;
    if self.byte_offset + bytes_read + num_bytes > self.total_bytes {
      // Not enough bytes left
      return None
    }

    // Advance byte_offset to next unread byte and read num_bytes
    self.byte_offset += bytes_read;
    let v = read_num_bytes!(T, num_bytes, self.buffer[self.byte_offset..]);
    self.byte_offset += num_bytes;

    // Reset buffered_values
    self.bit_offset = 0;
    let bytes_remaining = cmp::min(self.total_bytes - self.byte_offset, 8);
    self.buffered_values = read_num_bytes!(
      u64, bytes_remaining, self.buffer[self.byte_offset..]);
    Some(v)
  }

  /// Read a VLQ encoded (in little endian order) int from the stream.
  /// The encoded int must start at the beginning of a byte.
  /// Returns `None` if the number of bytes exceed `MAX_VLQ_BYTE_LEN`, or
  /// there's not enough bytes in the stream.
  #[inline]
  pub fn get_vlq_int(&mut self) -> Option<i32> {
    let mut num_bytes = 0;
    let mut shift = 0;
    let mut v: i32 = 0;
    while let Some(byte) = self.get_aligned::<u8>(1) {
      num_bytes += 1;
      if num_bytes >= MAX_VLQ_BYTE_LEN {
        return None
      }
      v |= ((byte & 0x7F) as i32) << shift;
      shift += 7;
      if byte & 0x80 == 0 {
        return Some(v);
      }
    }
    return None;
  }
}

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

  #[test]
  fn test_ceil() {
    assert_eq!(ceil(0, 1), 0);
    assert_eq!(ceil(1, 1), 1);
    assert_eq!(ceil(1, 2), 1);
    assert_eq!(ceil(1, 8), 1);
    assert_eq!(ceil(7, 8), 1);
    assert_eq!(ceil(8, 8), 1);
    assert_eq!(ceil(9, 8), 2);
    assert_eq!(ceil(9, 9), 1);
    assert_eq!(ceil(10000000000, 10), 1000000000);
    assert_eq!(ceil(10, 10000000000), 1);
    assert_eq!(ceil(10000000000, 1000000000), 10);
  }

  #[test]
  fn test_bit_reader_get_value() {
    let buffer = vec![255, 0];
    let mut bit_reader = BitReader::new(&buffer);
    let v1 = bit_reader.get_value::<i32>(1);
    assert!(v1.is_some());
    assert_eq!(v1.unwrap(), 1);
    let v2 = bit_reader.get_value::<i32>(2);
    assert!(v2.is_some());
    assert_eq!(v2.unwrap(), 3);
    let v3 = bit_reader.get_value::<i32>(3);
    assert!(v3.is_some());
    assert_eq!(v3.unwrap(), 7);
    let v4 = bit_reader.get_value::<i32>(4);
    assert!(v4.is_some());
    assert_eq!(v4.unwrap(), 3);
  }

  #[test]
  fn test_bit_reader_get_value_boundary() {
    let buffer = vec![10, 0, 0, 0, 20, 0, 30, 0, 0, 0, 40, 0];
    let mut bit_reader = BitReader::new(&buffer);
    let v1 = bit_reader.get_value::<i64>(32);
    assert!(v1.is_some());
    assert_eq!(v1.unwrap(), 10);
    let v2 = bit_reader.get_value::<i16>(16);
    assert!(v2.is_some());
    assert_eq!(v2.unwrap(), 20);
    let v3 = bit_reader.get_value::<i32>(32);
    assert!(v3.is_some());
    assert_eq!(v3.unwrap(), 30);
    let v4 = bit_reader.get_value::<i32>(16);
    assert!(v4.is_some());
    assert_eq!(v4.unwrap(), 40);
  }

  #[test]
  fn test_bit_reader_get_aligned() {
    // 01110101 11001011
    let buffer: Vec<u8> = vec!(0x75, 0xCB);
    let mut bit_reader = BitReader::new(&buffer);
    let v1 = bit_reader.get_value::<i32>(3);
    assert!(v1.is_some());
    assert_eq!(v1.unwrap(), 5);
    let v2 = bit_reader.get_aligned::<i32>(1);
    assert!(v2.is_some());
    assert_eq!(v2.unwrap(), 203);
    let v3 = bit_reader.get_value::<i32>(1);
    assert!(v3.is_none());

    bit_reader.reset(&buffer);
    let v4 = bit_reader.get_aligned::<i32>(3);
    assert!(v4.is_none());
  }

  #[test]
  fn test_bit_reader_get_vlq_int() {
    // 10001001 00000001 11110010 10110101 00000110
    let buffer: Vec<u8> = vec!(0x89, 0x01, 0xF2, 0xB5, 0x06);
    let mut bit_reader = BitReader::new(&buffer);
    let v1 = bit_reader.get_vlq_int();
    assert!(v1.is_some());
    assert_eq!(v1.unwrap(), 137);
    let v2 = bit_reader.get_vlq_int();
    assert!(v2.is_some());
    assert_eq!(v2.unwrap(), 105202);
  }

  #[test]
  fn test_set_array_bit() {
    let mut buffer = vec![0, 0, 0];
    set_array_bit(&mut buffer[..], 1);
    assert_eq!(buffer, vec![2, 0, 0]);
    set_array_bit(&mut buffer[..], 4);
    assert_eq!(buffer, vec![18, 0, 0]);
    unset_array_bit(&mut buffer[..], 1);
    assert_eq!(buffer, vec![16, 0, 0]);
    set_array_bit(&mut buffer[..], 10);
    assert_eq!(buffer, vec![16, 4, 0]);
    set_array_bit(&mut buffer[..], 10);
    assert_eq!(buffer, vec![16, 4, 0]);
    set_array_bit(&mut buffer[..], 11);
    assert_eq!(buffer, vec![16, 12, 0]);
    unset_array_bit(&mut buffer[..], 10);
    assert_eq!(buffer, vec![16, 8, 0]);
  }

}
<commit_msg>Add BitReader::get_zigzag_vlq_int() and tests<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

use std::mem::{size_of, transmute_copy};
use std::cmp;

/// Read `$size` of bytes from `$src`, and reinterpret them
/// as type `$ty`, in little-endian order. `$ty` must implement
/// the `Default` trait. Otherwise this won't compile.
/// This is copied and modified from byteorder crate.
macro_rules! read_num_bytes {
  ($ty:ty, $size:expr, $src:expr) => ({
    assert!($size <= $src.len());
    let mut data: $ty = Default::default();
    unsafe {
      ::std::ptr::copy_nonoverlapping(
        $src.as_ptr(),
        &mut data as *mut $ty as *mut u8,
        $size);
    }
    data
  });
}

/// Return the ceil of value/divisor
#[inline]
pub fn ceil(value: i64, divisor: i64) -> i64 {
  let mut result = value / divisor;
  if value % divisor != 0 { result += 1 };
  result
}

/// Returns the `num_bits` least-significant bits of `v`
#[inline]
pub fn trailing_bits(v: u64, num_bits: usize) -> u64 {
  if num_bits == 0 {
    return 0;
  }
  if num_bits >= 64 {
    return v;
  }
  let n = 64 - num_bits;
  (v << n) >> n
}

#[inline]
pub fn set_array_bit(bits: &mut [u8], i: usize) {
  bits[i / 8] |= 1 << (i % 8);
}

#[inline]
pub fn unset_array_bit(bits: &mut [u8], i: usize) {
  bits[i / 8] &= !(1 << (i % 8));
}

/// Maximum byte length for a VLQ encoded integer
const MAX_VLQ_BYTE_LEN: usize = 5;

pub struct BitReader<'a> {
  /// The byte buffer to read from, passed in by client
  buffer: &'a [u8],

  /// Bytes are memcpy'd from `buffer` and values are read from this variable.
  /// This is faster than reading values byte by byte directly from `buffer`
  buffered_values: u64,

  /// Current byte offset in `buffer`
  byte_offset: usize,

  /// Current bit offset in `buffered_values`
  bit_offset: usize,

  /// Total number of bytes in `buffer`
  total_bytes: usize
}

impl<'a> BitReader<'a> {
  pub fn new(buffer: &'a [u8]) -> Self {
    let total_bytes = buffer.len();
    let num_bytes = cmp::min(8, total_bytes);
    let buffered_values = read_num_bytes!(u64, num_bytes, buffer);
    BitReader {
      buffer: buffer, buffered_values: buffered_values,
      byte_offset: 0, bit_offset: 0, total_bytes: total_bytes
    }
  }

  #[inline]
  pub fn reset(&mut self, buffer: &'a [u8]) {
    self.buffer = buffer;
    self.total_bytes = buffer.len();
    let num_bytes = cmp::min(8, self.total_bytes);
    self.buffered_values = read_num_bytes!(u64, num_bytes, buffer);
    self.byte_offset = 0;
    self.bit_offset = 0;
  }

  #[inline]
  pub fn get_value<T: Default>(&mut self, num_bits: usize) -> Option<T> {
    assert!(num_bits <= 32);
    assert!(num_bits <= size_of::<T>() * 8);

    if self.byte_offset * 8 + self.bit_offset + num_bits > self.total_bytes * 8 {
      return None;
    }

    //
    // |...|.........|...........|
    //     ^         ^           ^
    //     num_bits  bit_offset  byte_offset
    //
    let mut v = trailing_bits(self.buffered_values, self.bit_offset + num_bits) >> self.bit_offset;
    self.bit_offset += num_bits;

    if self.bit_offset >= 64 {
      self.byte_offset += 8;
      self.bit_offset -= 64;

      let bytes_to_read = cmp::min(self.total_bytes - self.byte_offset, 8);
      self.buffered_values = read_num_bytes!(
        u64, bytes_to_read, self.buffer[self.byte_offset..]);

      v |= trailing_bits(self.buffered_values, self.bit_offset) << (num_bits - self.bit_offset);
    }

    // TODO: better to avoid copying here
    let result: T = unsafe {
      transmute_copy::<u64, T>(&v)
    };
    Some(result)
  }

  /// Read a `num_bytes`-sized value from this buffer and return it.
  /// `T` needs to be a little-endian native type. The value is assumed to
  /// be byte aligned so the bit reader will be advanced to the start of
  /// the next byte before reading the value. Return `None` if there's not
  /// enough bytes left.
  #[inline]
  pub fn get_aligned<T: Default>(&mut self, num_bytes: usize) -> Option<T> {
    let bytes_read = ceil(self.bit_offset as i64, 8) as usize;
    if self.byte_offset + bytes_read + num_bytes > self.total_bytes {
      // Not enough bytes left
      return None
    }

    // Advance byte_offset to next unread byte and read num_bytes
    self.byte_offset += bytes_read;
    let v = read_num_bytes!(T, num_bytes, self.buffer[self.byte_offset..]);
    self.byte_offset += num_bytes;

    // Reset buffered_values
    self.bit_offset = 0;
    let bytes_remaining = cmp::min(self.total_bytes - self.byte_offset, 8);
    self.buffered_values = read_num_bytes!(
      u64, bytes_remaining, self.buffer[self.byte_offset..]);
    Some(v)
  }

  /// Read a VLQ encoded (in little endian order) int from the stream.
  /// The encoded int must start at the beginning of a byte.
  /// Returns `None` if the number of bytes exceed `MAX_VLQ_BYTE_LEN`, or
  /// there's not enough bytes in the stream.
  #[inline]
  pub fn get_vlq_int(&mut self) -> Option<i32> {
    let mut num_bytes = 0;
    let mut shift = 0;
    let mut v: i32 = 0;
    while let Some(byte) = self.get_aligned::<u8>(1) {
      num_bytes += 1;
      if num_bytes >= MAX_VLQ_BYTE_LEN {
        return None
      }
      v |= ((byte & 0x7F) as i32) << shift;
      shift += 7;
      if byte & 0x80 == 0 {
        return Some(v);
      }
    }
    return None;
  }

  /// Read a zigzag-VLQ encoded (in little endian order) int from the stream
  /// Zigzag-VLQ is a variant of VLQ encoding where negative and positive
  /// numbers are encoded in a zigzag fashion.
  /// See: https://developers.google.com/protocol-buffers/docs/encoding
  ///
  /// The encoded int must start at the beginning of a byte.
  /// Returns `None` if the number of bytes exceed `MAX_VLQ_BYTE_LEN`, or
  /// there's not enough bytes in the stream.
  #[inline]
  pub fn get_zigzag_vlq_int(&mut self) -> Option<i32> {
    self.get_vlq_int().map(|v| {
      let u = v as u32;
      ((u >> 1) as i32 ^ -((u & 1) as i32))
    })
  }
}

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

  #[test]
  fn test_ceil() {
    assert_eq!(ceil(0, 1), 0);
    assert_eq!(ceil(1, 1), 1);
    assert_eq!(ceil(1, 2), 1);
    assert_eq!(ceil(1, 8), 1);
    assert_eq!(ceil(7, 8), 1);
    assert_eq!(ceil(8, 8), 1);
    assert_eq!(ceil(9, 8), 2);
    assert_eq!(ceil(9, 9), 1);
    assert_eq!(ceil(10000000000, 10), 1000000000);
    assert_eq!(ceil(10, 10000000000), 1);
    assert_eq!(ceil(10000000000, 1000000000), 10);
  }

  #[test]
  fn test_bit_reader_get_value() {
    let buffer = vec![255, 0];
    let mut bit_reader = BitReader::new(&buffer);
    let v1 = bit_reader.get_value::<i32>(1);
    assert!(v1.is_some());
    assert_eq!(v1.unwrap(), 1);
    let v2 = bit_reader.get_value::<i32>(2);
    assert!(v2.is_some());
    assert_eq!(v2.unwrap(), 3);
    let v3 = bit_reader.get_value::<i32>(3);
    assert!(v3.is_some());
    assert_eq!(v3.unwrap(), 7);
    let v4 = bit_reader.get_value::<i32>(4);
    assert!(v4.is_some());
    assert_eq!(v4.unwrap(), 3);
  }

  #[test]
  fn test_bit_reader_get_value_boundary() {
    let buffer = vec![10, 0, 0, 0, 20, 0, 30, 0, 0, 0, 40, 0];
    let mut bit_reader = BitReader::new(&buffer);
    let v1 = bit_reader.get_value::<i64>(32);
    assert!(v1.is_some());
    assert_eq!(v1.unwrap(), 10);
    let v2 = bit_reader.get_value::<i16>(16);
    assert!(v2.is_some());
    assert_eq!(v2.unwrap(), 20);
    let v3 = bit_reader.get_value::<i32>(32);
    assert!(v3.is_some());
    assert_eq!(v3.unwrap(), 30);
    let v4 = bit_reader.get_value::<i32>(16);
    assert!(v4.is_some());
    assert_eq!(v4.unwrap(), 40);
  }

  #[test]
  fn test_bit_reader_get_aligned() {
    // 01110101 11001011
    let buffer: Vec<u8> = vec!(0x75, 0xCB);
    let mut bit_reader = BitReader::new(&buffer);
    let v1 = bit_reader.get_value::<i32>(3);
    assert!(v1.is_some());
    assert_eq!(v1.unwrap(), 5);
    let v2 = bit_reader.get_aligned::<i32>(1);
    assert!(v2.is_some());
    assert_eq!(v2.unwrap(), 203);
    let v3 = bit_reader.get_value::<i32>(1);
    assert!(v3.is_none());

    bit_reader.reset(&buffer);
    let v4 = bit_reader.get_aligned::<i32>(3);
    assert!(v4.is_none());
  }

  #[test]
  fn test_bit_reader_get_vlq_int() {
    // 10001001 00000001 11110010 10110101 00000110
    let buffer: Vec<u8> = vec!(0x89, 0x01, 0xF2, 0xB5, 0x06);
    let mut bit_reader = BitReader::new(&buffer);
    let v1 = bit_reader.get_vlq_int();
    assert!(v1.is_some());
    assert_eq!(v1.unwrap(), 137);
    let v2 = bit_reader.get_vlq_int();
    assert!(v2.is_some());
    assert_eq!(v2.unwrap(), 105202);
  }

  #[test]
  fn test_bit_reader_get_zigzag_vlq_int() {
    let buffer: Vec<u8> = vec!(0, 1, 2, 3);
    let mut bit_reader = BitReader::new(&buffer);

    let v = bit_reader.get_zigzag_vlq_int();
    assert!(v.is_some());
    assert_eq!(v.unwrap(), 0);

    let v = bit_reader.get_zigzag_vlq_int();
    assert!(v.is_some());
    assert_eq!(v.unwrap(), -1);

    let v = bit_reader.get_zigzag_vlq_int();
    assert!(v.is_some());
    assert_eq!(v.unwrap(), 1);

    let v = bit_reader.get_zigzag_vlq_int();
    assert!(v.is_some());
    assert_eq!(v.unwrap(), -2);
  }

  #[test]
  fn test_set_array_bit() {
    let mut buffer = vec![0, 0, 0];
    set_array_bit(&mut buffer[..], 1);
    assert_eq!(buffer, vec![2, 0, 0]);
    set_array_bit(&mut buffer[..], 4);
    assert_eq!(buffer, vec![18, 0, 0]);
    unset_array_bit(&mut buffer[..], 1);
    assert_eq!(buffer, vec![16, 0, 0]);
    set_array_bit(&mut buffer[..], 10);
    assert_eq!(buffer, vec![16, 4, 0]);
    set_array_bit(&mut buffer[..], 10);
    assert_eq!(buffer, vec![16, 4, 0]);
    set_array_bit(&mut buffer[..], 11);
    assert_eq!(buffer, vec![16, 12, 0]);
    unset_array_bit(&mut buffer[..], 10);
    assert_eq!(buffer, vec![16, 8, 0]);
  }

}
<|endoftext|>


<commit_before>use ndarray::prelude::*;
use ndarray::{Ix2, DataMut};
use lapack::c::Layout;
use std::slice;

/// Return an array with the specified dimensions and layout.
///
/// This function is used internally to ensure that
pub fn matrix_with_layout<T: Default>(d: Ix2, layout: Layout) -> Array<T, Ix2> {
    Array::default(match layout {
        Layout::RowMajor => d.into(),
        Layout::ColumnMajor => d.f(),
    })
}

/// Return the slice, layout, and leading dimension of the matrix.
///
/// For LAPACKE methods, the memory layout does not need to be
/// contiguous. We only required that either rows or columns are
/// contiguous.
pub fn slice_and_layout_mut<D, S: DataMut<Elem = D>>(mat: &mut ArrayBase<S, Ix2>)
                                                     -> Option<(&mut [S::Elem], Layout, Ixs)> {
    let strides = {
        let s = mat.strides();
        (s[0], s[1])
    };

    if strides.0 < 0 || strides.1 < 0 {
        return None;
    }

    let dim = mat.dim();

    // One of the stides, must be 1
    if strides.1 == 1 {
        let m = strides.0;
        let s = unsafe {
            let nelem: usize = (dim.0 - 1) * m as usize + dim.1;
            slice::from_raw_parts_mut(mat.as_mut_ptr(), nelem)
        };
        Some((s, Layout::RowMajor, m))
    } else if strides.0 == 0 {
        let n = strides.1;
        let s = unsafe {
            let nelem: usize = (dim.1 - 1) * n as usize + dim.0;
            slice::from_raw_parts_mut(mat.as_mut_ptr(), nelem)
        };
        Some((s, Layout::ColumnMajor, n))
    } else {
        None
    }
}

/// Return the slice, layout, and leading dimension of the matrix. If
/// the matrix can be interpreted with multiple inputs, assume the
/// previous one.
///
/// For LAPACKE methods, the memory layout does not need to be
/// contiguous. We only required that either rows or columns are
/// contiguous.
///
/// Returns None if the layout can't be matched.
pub fn slice_and_layout_matching_mut<D, S: DataMut<Elem = D>>(mat: &mut ArrayBase<S, Ix2>,
                                                              layout: Layout)
                                                              -> Option<(&mut [S::Elem], Ixs)> {
    let dim = mat.dim();

    // For column vectors, we can choose whatever layout we want.
    if dim.1 == 1 {
        let m = mat.strides()[0];

        let s = unsafe {
            let nelem: usize = (dim.0 - 1) * m as usize + dim.1;
            slice::from_raw_parts_mut(mat.as_mut_ptr(), nelem)
        };
        return Some((s, m));
    }

    // Otherwise, we just use the normal method and check for a match.
    if let Some((slice, lo, ld)) = slice_and_layout_mut(mat) {
        if lo == layout {
            return Some((slice, ld));
        }
    }

    None
}
<commit_msg>fix: fixed slice_and_layout_mut bug<commit_after>use ndarray::prelude::*;
use ndarray::{Ix2, DataMut};
use lapack::c::Layout;
use std::slice;

/// Return an array with the specified dimensions and layout.
///
/// This function is used internally to ensure that
pub fn matrix_with_layout<T: Default>(d: Ix2, layout: Layout) -> Array<T, Ix2> {
    Array::default(match layout {
        Layout::RowMajor => d.into(),
        Layout::ColumnMajor => d.f(),
    })
}

/// Return the slice, layout, and leading dimension of the matrix.
///
/// For LAPACKE methods, the memory layout does not need to be
/// contiguous. We only required that either rows or columns are
/// contiguous.
pub fn slice_and_layout_mut<D, S: DataMut<Elem = D>>(mat: &mut ArrayBase<S, Ix2>)
                                                     -> Option<(&mut [S::Elem], Layout, Ixs)> {
    let strides = {
        let s = mat.strides();
        (s[0], s[1])
    };

    if strides.0 < 0 || strides.1 < 0 {
        return None;
    }

    let dim = mat.dim();

    // One of the stides, must be 1
    if strides.1 == 1 {
        let m = strides.0;
        let s = unsafe {
            let nelem: usize = (dim.0 - 1) * m as usize + dim.1;
            slice::from_raw_parts_mut(mat.as_mut_ptr(), nelem)
        };
        Some((s, Layout::RowMajor, m))
    } else if strides.0 == 1 {
        let n = strides.1;
        let s = unsafe {
            let nelem: usize = (dim.1 - 1) * n as usize + dim.0;
            slice::from_raw_parts_mut(mat.as_mut_ptr(), nelem)
        };
        Some((s, Layout::ColumnMajor, n))
    } else {
        None
    }
}

/// Return the slice, layout, and leading dimension of the matrix. If
/// the matrix can be interpreted with multiple inputs, assume the
/// previous one.
///
/// For LAPACKE methods, the memory layout does not need to be
/// contiguous. We only required that either rows or columns are
/// contiguous.
///
/// Returns None if the layout can't be matched.
pub fn slice_and_layout_matching_mut<D, S: DataMut<Elem = D>>(mat: &mut ArrayBase<S, Ix2>,
                                                              layout: Layout)
                                                              -> Option<(&mut [S::Elem], Ixs)> {
    let dim = mat.dim();

    // For column vectors, we can choose whatever layout we want.
    if dim.1 == 1 {
        let m = mat.strides()[0];

        let s = unsafe {
            let nelem: usize = (dim.0 - 1) * m as usize + dim.1;
            slice::from_raw_parts_mut(mat.as_mut_ptr(), nelem)
        };
        return Some((s, m));
    }

    // Otherwise, we just use the normal method and check for a match.
    if let Some((slice, lo, ld)) = slice_and_layout_mut(mat) {
        if lo == layout {
            return Some((slice, ld));
        }
    }

    None
}
<|endoftext|>


<commit_before>use nom::{self, IResult, Needed};

use std::io::{self, Read};
use std::ptr;
use std::cmp;

use super::{Sample, StreamProducer};

/// Represent the different kinds of errors.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ErrorKind {
  /// Error from I/O.
  IO(io::ErrorKind),
  /// A parser stopped midway and need more bytes to consume.
  Incomplete(usize),
  /// A parser has completes and there is still more bytes to consume.
  Continue,
  /// A parser has completes and there is no more bytes to consume.
  EndOfInput,
  /// A non-specified error.
  Unknown,
  // Parser Error
  /// Failed parsing the "fLaC" header token.
  HeaderParser,
  /// Failed parsing a metadata header.
  MetadataHeaderParser,
  /// Failed parsing the metadata block `StreamInfo`.
  StreamInfoParser,
  /// Failed parsing the metadata block `Padding`.
  PaddingParser,
  /// Failed parsing the metadata block `Application`.
  ApplicationParser,
  /// Failed parsing the metadata block `SeekTable`.
  SeekTableParser,
  /// Failed parsing the metadata block `VorbisComment`.
  VorbisCommentParser,
  /// Failed parsing the metadata block `CueSheet`.
  CueSheetParser,
  /// Failed parsing the metadata block `Picture`.
  PictureParser,
  /// Failed parsing the metadata block `Unknown`.
  UnknownParser,
  /// Failed parsing the blocking strategy inside the frame header.
  BlockingStrategyParser,
  /// Failed parsing the blocking sample inside the frame header.
  BlockingSampleParser,
  /// Failed parsing the channel bits inside the frame header.
  ChannelBitsParser,
  /// Failed parsing the UTF-8 header inside the frame header.
  UTF8HeaderParser,
  /// Failed parsing the UTF-8 body inside the frame header.
  UTF8BodyParser,
  /// Failed parsing the secondary block size inside the frame header.
  BlockSizeParser,
  /// Failed parsing the secondary sample rate inside the frame header.
  SampleRateParser,
  /// Failed parsing the CRC-8 inside the frame header.
  CRC8Parser,
  /// Failed parsing the frame footer, also known as the CRC-16.
  FrameFooterParser,
  /// Failed parsing the subframe header.
  SubframeHeaderParser,
  /// Failed parsing the leading zero for a unary value.
  LeadingZerosParser,
  /// Failed parsing a Constant subframe data.
  ConstantParser,
  /// Failed parsing a Verbatim subframe data.
  VerbatimParser,
  /// Failed parsing a Fixed subframe data.
  FixedParser,
  /// Failed parsing a LPC subframe data.
  LPCParser,
  // Invalid Error
  /// A block type, base on the number, that is outside the range (0-126).
  InvalidBlockType,
  /// An incorrect sync code with the frame header.
  InvalidSyncCode,
  /// A block sample that could cause sync-fooling.
  InvalidBlockSample,
  /// One or more bits are reserved values.
  InvalidChannelBits,
  /// An error occurred in building the UTF-8 value.
  InvalidUTF8,
  /// The stored CRC-8 doesn't match the one generated from the bytes within
  /// the frame header.
  InvalidCRC8,
  /// The stored CRC-16 doesn't match the one generated from the bytes
  /// within the entire frame.
  InvalidCRC16,
  /// A subframe header that could cause sync-fooling.
  InvalidSubframeHeader,
  // Not Found
  /// Some metadata block was not found with a specific filter.
  NotFound,
}

/// Structure that hold a slice of bytes.
pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  /// Construct a `ByteStream` based on the passed in byte slice.
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  /// Return the number of bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  /// Return true if the stream contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T, ErrorKind> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        match e {
          nom::Err::Code(k)               |
          nom::Err::Node(k, _)            |
          nom::Err::Position(k, _)        |
          nom::Err::NodePosition(k, _, _) => {
            if let nom::ErrorKind::Custom(kind) = k {
              Err(kind)
            } else {
              Err(ErrorKind::Unknown)
            }
          }
        }
      },
    }
  }
}

// Growable buffer of bytes.
//
// Mainly used to the `ReadStream` structure but can be used seperately for
// manually filling with some `Read` source.
pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  // Default constructor for `Buffer`
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  // Explicitly set the buffer capacity.
  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  // Return the number of read bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  // Return true if buffer contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  // The set length of the unlining buffer.
  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  // Return a reference to the slice of unread bytes.
  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  // Fill the buffer with bytes from a `Read` source.
  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  // Resize the current buffer
  //
  // This will only allocate data when the size requests is larger than the
  // current capacity of the buffer, otherwise it moves the currently filled
  // data to the beginning of the buffer.
  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length  = self.filled - self.offset;
      let mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  // Move the offset by the amount of consumed bytes.
  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

/// Structure that hold a reader for a source of bytes.
pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  /// Constructor for `ReadStream` based on a `Read` source.
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  // Fill the stream with bytes from a `Read` source.
  fn fill(&mut self) -> io::Result<usize> {
    let needed = cmp::max(1, self.needed);

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T, ErrorKind>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity() + 1024;

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      match e {
        nom::Err::Code(k)               |
        nom::Err::Node(k, _)            |
        nom::Err::Position(k, _)        |
        nom::Err::NodePosition(k, _, _) => {
          if let nom::ErrorKind::Custom(kind) = k {
            Err(kind)
          } else {
            Err(ErrorKind::Unknown)
          }
        }
      }
    },
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T, ErrorKind> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(|e| ErrorKind::IO(e.kind())));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        if let ErrorKind::Incomplete(needed) = kind {
          self.needed = needed;

          Err(ErrorKind::Continue)
        } else {
          Err(kind)
        }
      }
    }
  }
}

macro_rules! sample (
  ($normal: ident, $extended: ident, $bits_per_sample: expr) => (
    impl Sample for $extended {
      type Normal = $normal;

      #[inline]
      fn size() -> usize { $bits_per_sample }

      fn to_normal(sample: Self) -> Option<Self::Normal> {
        use std::$normal;

        let min = $normal::min_value() as $extended;
        let max = $normal::max_value() as $extended;

        if sample > min && sample < max {
          Some(sample as $normal)
        } else {
          None
        }
      }
    }
  )
);

#[cfg(test)]
mod tests {
  use super::*;
  use utility::StreamProducer;
  use nom::{self, IResult};

  #[inline]
  fn be_u32(input: &[u8]) -> IResult<&[u8], u32, ErrorKind> {
    to_custom_error!(input, nom::be_u32, Unknown)
  }

  #[test]
  fn test_buffer() {
    let mut buffer = Buffer::new();
    let bytes      = b"Hello World";
    let mut reader = &bytes[..];

    assert!(buffer.is_empty());
    assert_eq!(buffer.capacity(), 1024);

    let bytes_read = buffer.fill(&mut reader).unwrap_or(0);
    let bytes_len  = bytes.len();

    assert_eq!(bytes_read, bytes_len);
    assert_eq!(buffer.len(), bytes_len);
    assert_eq!(buffer.as_slice(), bytes);

    buffer.resize(512);
    assert_eq!(buffer.capacity(), 1024);
  }

  #[test]
  fn test_byte_stream() {
    let bytes      = b"Hello World";
    let mut stream = ByteStream::new(bytes);

    assert_eq!(stream.len(), bytes.len());

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444);
    assert_eq!(stream.len(), 7);
  }

  #[test]
  fn test_read_stream() {
    let bytes      = b"Hello World";
    let mut stream = ReadStream::new(&bytes[..]);

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444)
  }
}
<commit_msg>Add the three implementors of the Sample trait<commit_after>use nom::{self, IResult, Needed};

use std::io::{self, Read};
use std::ptr;
use std::cmp;

use super::{Sample, StreamProducer};

/// Represent the different kinds of errors.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ErrorKind {
  /// Error from I/O.
  IO(io::ErrorKind),
  /// A parser stopped midway and need more bytes to consume.
  Incomplete(usize),
  /// A parser has completes and there is still more bytes to consume.
  Continue,
  /// A parser has completes and there is no more bytes to consume.
  EndOfInput,
  /// A non-specified error.
  Unknown,
  // Parser Error
  /// Failed parsing the "fLaC" header token.
  HeaderParser,
  /// Failed parsing a metadata header.
  MetadataHeaderParser,
  /// Failed parsing the metadata block `StreamInfo`.
  StreamInfoParser,
  /// Failed parsing the metadata block `Padding`.
  PaddingParser,
  /// Failed parsing the metadata block `Application`.
  ApplicationParser,
  /// Failed parsing the metadata block `SeekTable`.
  SeekTableParser,
  /// Failed parsing the metadata block `VorbisComment`.
  VorbisCommentParser,
  /// Failed parsing the metadata block `CueSheet`.
  CueSheetParser,
  /// Failed parsing the metadata block `Picture`.
  PictureParser,
  /// Failed parsing the metadata block `Unknown`.
  UnknownParser,
  /// Failed parsing the blocking strategy inside the frame header.
  BlockingStrategyParser,
  /// Failed parsing the blocking sample inside the frame header.
  BlockingSampleParser,
  /// Failed parsing the channel bits inside the frame header.
  ChannelBitsParser,
  /// Failed parsing the UTF-8 header inside the frame header.
  UTF8HeaderParser,
  /// Failed parsing the UTF-8 body inside the frame header.
  UTF8BodyParser,
  /// Failed parsing the secondary block size inside the frame header.
  BlockSizeParser,
  /// Failed parsing the secondary sample rate inside the frame header.
  SampleRateParser,
  /// Failed parsing the CRC-8 inside the frame header.
  CRC8Parser,
  /// Failed parsing the frame footer, also known as the CRC-16.
  FrameFooterParser,
  /// Failed parsing the subframe header.
  SubframeHeaderParser,
  /// Failed parsing the leading zero for a unary value.
  LeadingZerosParser,
  /// Failed parsing a Constant subframe data.
  ConstantParser,
  /// Failed parsing a Verbatim subframe data.
  VerbatimParser,
  /// Failed parsing a Fixed subframe data.
  FixedParser,
  /// Failed parsing a LPC subframe data.
  LPCParser,
  // Invalid Error
  /// A block type, base on the number, that is outside the range (0-126).
  InvalidBlockType,
  /// An incorrect sync code with the frame header.
  InvalidSyncCode,
  /// A block sample that could cause sync-fooling.
  InvalidBlockSample,
  /// One or more bits are reserved values.
  InvalidChannelBits,
  /// An error occurred in building the UTF-8 value.
  InvalidUTF8,
  /// The stored CRC-8 doesn't match the one generated from the bytes within
  /// the frame header.
  InvalidCRC8,
  /// The stored CRC-16 doesn't match the one generated from the bytes
  /// within the entire frame.
  InvalidCRC16,
  /// A subframe header that could cause sync-fooling.
  InvalidSubframeHeader,
  // Not Found
  /// Some metadata block was not found with a specific filter.
  NotFound,
}

/// Structure that hold a slice of bytes.
pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  /// Construct a `ByteStream` based on the passed in byte slice.
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  /// Return the number of bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  /// Return true if the stream contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T, ErrorKind> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        match e {
          nom::Err::Code(k)               |
          nom::Err::Node(k, _)            |
          nom::Err::Position(k, _)        |
          nom::Err::NodePosition(k, _, _) => {
            if let nom::ErrorKind::Custom(kind) = k {
              Err(kind)
            } else {
              Err(ErrorKind::Unknown)
            }
          }
        }
      },
    }
  }
}

// Growable buffer of bytes.
//
// Mainly used to the `ReadStream` structure but can be used seperately for
// manually filling with some `Read` source.
pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  // Default constructor for `Buffer`
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  // Explicitly set the buffer capacity.
  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  // Return the number of read bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  // Return true if buffer contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  // The set length of the unlining buffer.
  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  // Return a reference to the slice of unread bytes.
  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  // Fill the buffer with bytes from a `Read` source.
  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  // Resize the current buffer
  //
  // This will only allocate data when the size requests is larger than the
  // current capacity of the buffer, otherwise it moves the currently filled
  // data to the beginning of the buffer.
  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length  = self.filled - self.offset;
      let mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  // Move the offset by the amount of consumed bytes.
  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

/// Structure that hold a reader for a source of bytes.
pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  /// Constructor for `ReadStream` based on a `Read` source.
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  // Fill the stream with bytes from a `Read` source.
  fn fill(&mut self) -> io::Result<usize> {
    let needed = cmp::max(1, self.needed);

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T, ErrorKind>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity() + 1024;

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      match e {
        nom::Err::Code(k)               |
        nom::Err::Node(k, _)            |
        nom::Err::Position(k, _)        |
        nom::Err::NodePosition(k, _, _) => {
          if let nom::ErrorKind::Custom(kind) = k {
            Err(kind)
          } else {
            Err(ErrorKind::Unknown)
          }
        }
      }
    },
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T, ErrorKind> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(|e| ErrorKind::IO(e.kind())));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        if let ErrorKind::Incomplete(needed) = kind {
          self.needed = needed;

          Err(ErrorKind::Continue)
        } else {
          Err(kind)
        }
      }
    }
  }
}

macro_rules! sample (
  ($normal: ident, $extended: ident, $bits_per_sample: expr) => (
    impl Sample for $extended {
      type Normal = $normal;

      #[inline]
      fn size() -> usize { $bits_per_sample }

      fn to_normal(sample: Self) -> Option<Self::Normal> {
        use std::$normal;

        let min = $normal::min_value() as $extended;
        let max = $normal::max_value() as $extended;

        if sample > min && sample < max {
          Some(sample as $normal)
        } else {
          None
        }
      }
    }
  )
);

sample!(i8, i16, 8);
sample!(i16, i32, 16);
sample!(i32, i64, 32);

#[cfg(test)]
mod tests {
  use super::*;
  use utility::StreamProducer;
  use nom::{self, IResult};

  #[inline]
  fn be_u32(input: &[u8]) -> IResult<&[u8], u32, ErrorKind> {
    to_custom_error!(input, nom::be_u32, Unknown)
  }

  #[test]
  fn test_buffer() {
    let mut buffer = Buffer::new();
    let bytes      = b"Hello World";
    let mut reader = &bytes[..];

    assert!(buffer.is_empty());
    assert_eq!(buffer.capacity(), 1024);

    let bytes_read = buffer.fill(&mut reader).unwrap_or(0);
    let bytes_len  = bytes.len();

    assert_eq!(bytes_read, bytes_len);
    assert_eq!(buffer.len(), bytes_len);
    assert_eq!(buffer.as_slice(), bytes);

    buffer.resize(512);
    assert_eq!(buffer.capacity(), 1024);
  }

  #[test]
  fn test_byte_stream() {
    let bytes      = b"Hello World";
    let mut stream = ByteStream::new(bytes);

    assert_eq!(stream.len(), bytes.len());

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444);
    assert_eq!(stream.len(), 7);
  }

  #[test]
  fn test_read_stream() {
    let bytes      = b"Hello World";
    let mut stream = ReadStream::new(&bytes[..]);

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444)
  }
}
<|endoftext|>


<commit_before>// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

use serde::{Deserialize, Serialize};
use thiserror::Error;

use super::Capability;

/// Contains all the errors that any method on the `Transport` trait could generate.  This
/// struct is serializable, such that it can be transmitted across a network for instance as
/// part of the session proxy functionality.
#[derive(Error, Debug, Serialize, Deserialize)]
pub enum TransportError {
    #[error("USB device did not match")]
    NoMatch,
    #[error("Found no USB device")]
    NoDevice,
    #[error("Found multiple USB devices, use --serial")]
    MultipleDevices,
    #[error("USB error: {0}")]
    UsbGenericError(String),
    #[error("Error opening USB device: {0}")]
    UsbOpenError(String),
    #[error("Transport does not support {0:?}")]
    InvalidInterface(TransportInterfaceType),
    #[error("Transport does not support {0:?} instance {1}")]
    InvalidInstance(TransportInterfaceType, String),
    #[error("Encountered non-unicode device path")]
    UnicodePathError,
    #[error("Error opening {0}: {1}")]
    OpenError(String, String),
    #[error("Error reading from {0}: {1}")]
    ReadError(String, String),
    #[error("FPGA programming failed: {0}")]
    FpgaProgramFailed(String),
    #[error("Invalid pin strapping name \"{0}\"")]
    InvalidStrappingName(String),
    #[error("Transport does not support the requested operation")]
    UnsupportedOperation,
    #[error("Error communicating with FTDI: {0}")]
    FtdiError(String),
    #[error("Error communicating with debugger: {0}")]
    CommunicationError(String),
    #[error("Proxy unable to resolve `{0}`: {1}")]
    ProxyLookupError(String, String),
    #[error("Proxy unable to connect to `{0}`: {1}")]
    ProxyConnectError(String, String),
    #[error("Proxy communication error: {0}")]
    ProxyCommunicationError(#[from] crate::transport::proxy::ProxyError),
    #[error("Requested capabilities {0:?}, but capabilities {1:?} are supplied")]
    MissingCapabilities(Capability, Capability),

    // Include sub-enums for the various sub-traits of Tranport.
    #[error("GPIO error: {0}")]
    GpioError(#[from] crate::io::gpio::GpioError),
    #[error("UART error: {0}")]
    UartError(#[from] crate::io::uart::UartError),
    #[error("SPI error: {0}")]
    SpiError(#[from] crate::io::spi::SpiError),
    #[error("SPI error: {0}")]
    I2cError(#[from] crate::io::i2c::I2cError),
    #[error("Emulator error: {0}")]
    EmuError(#[from] crate::io::emu::EmuError),

    // Other sub-enums used by proxy logic (that is, opentitanlib logic running in session daemon
    // process for efficiency).
    #[error("Bootstrapping: {0}")]
    BootstrapError(#[from] crate::bootstrap::BootstrapError),
    #[error("Bootstrapping: {0}")]
    LegacyBootstrapError(#[from] crate::bootstrap::LegacyBootstrapError),
    #[error("Bootstrapping: {0}")]
    RescueError(#[from] crate::bootstrap::RescueError),
}

/// Enum value used by `TransportError::InvalidInstance`.
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub enum TransportInterfaceType {
    Gpio,
    Uart,
    Spi,
    I2c,
    Emulator,
    ProxyOps,
}

/// Return type to be used in `Transport` methods.
pub type Result<T> = anyhow::Result<T, TransportError>;

/// Convenience macro to be used in implementations of `Transport`.
#[macro_export]
macro_rules! bail {
    ($err:expr $(,)?) => {
        return Err($err.into());
    };
}

/// Convenience macro to be used in implementations of `Transport`.
#[macro_export]
macro_rules! ensure {
    ($cond:expr, $err:expr $(,)?) => {
        if !$cond {
            return Err($err.into());
        }
    };
}

/// Function for conveniently wrapping (the flat string representation of) an anyhow::Error in a
/// TransportError.
///
/// Example usage:
/// serialport::available_ports().wrap(UartError::EnumerationError)?;
pub trait WrapInTransportError<T> {
    fn wrap<S: Into<TransportError>>(self, kind: impl FnOnce(String) -> S) -> Result<T>;
}

impl<T, E: ToString> WrapInTransportError<T> for anyhow::Result<T, E> {
    fn wrap<S: Into<TransportError>>(self, kind: impl FnOnce(String) -> S) -> Result<T> {
        self.map_err(|e| kind(e.to_string()).into())
    }
}
<commit_msg>[opentitantool] Fix warnings<commit_after>// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

use serde::{Deserialize, Serialize};
use thiserror::Error;

use super::Capability;

/// Contains all the errors that any method on the `Transport` trait could generate.  This
/// struct is serializable, such that it can be transmitted across a network for instance as
/// part of the session proxy functionality.
#[derive(Error, Debug, Serialize, Deserialize)]
pub enum TransportError {
    #[error("USB device did not match")]
    NoMatch,
    #[error("Found no USB device")]
    NoDevice,
    #[error("Found multiple USB devices, use --serial")]
    MultipleDevices,
    #[error("USB error: {0}")]
    UsbGenericError(String),
    #[error("Error opening USB device: {0}")]
    UsbOpenError(String),
    #[error("Transport does not support {0:?}")]
    InvalidInterface(TransportInterfaceType),
    #[error("Transport does not support {0:?} instance {1}")]
    InvalidInstance(TransportInterfaceType, String),
    #[error("Encountered non-unicode device path")]
    UnicodePathError,
    #[error("Error opening {0}: {1}")]
    OpenError(String, String),
    #[error("Error reading from {0}: {1}")]
    ReadError(String, String),
    #[error("FPGA programming failed: {0}")]
    FpgaProgramFailed(String),
    #[error("Invalid pin strapping name \"{0}\"")]
    InvalidStrappingName(String),
    #[error("Transport does not support the requested operation")]
    UnsupportedOperation,
    #[error("Error communicating with FTDI: {0}")]
    FtdiError(String),
    #[error("Error communicating with debugger: {0}")]
    CommunicationError(String),
    #[error("Proxy unable to resolve `{0}`: {1}")]
    ProxyLookupError(String, String),
    #[error("Proxy unable to connect to `{0}`: {1}")]
    ProxyConnectError(String, String),
    #[error("Proxy communication error: {0}")]
    ProxyCommunicationError(#[from] crate::transport::proxy::ProxyError),
    #[error("Requested capabilities {0:?}, but capabilities {1:?} are supplied")]
    MissingCapabilities(Capability, Capability),

    // Include sub-enums for the various sub-traits of Tranport.
    #[error("GPIO error: {0}")]
    GpioError(#[from] crate::io::gpio::GpioError),
    #[error("UART error: {0}")]
    UartError(#[from] crate::io::uart::UartError),
    #[error("SPI error: {0}")]
    SpiError(#[from] crate::io::spi::SpiError),
    #[error("SPI error: {0}")]
    I2cError(#[from] crate::io::i2c::I2cError),
    #[error("Emulator error: {0}")]
    EmuError(#[from] crate::io::emu::EmuError),

    // Other sub-enums used by proxy logic (that is, opentitanlib logic running in session daemon
    // process for efficiency).
    #[error("Bootstrapping: {0}")]
    BootstrapError(#[from] crate::bootstrap::BootstrapError),
    #[error("Bootstrapping: {0}")]
    LegacyBootstrapError(#[from] crate::bootstrap::LegacyBootstrapError),
    #[error("Bootstrapping: {0}")]
    RescueError(#[from] crate::bootstrap::RescueError),
}

/// Enum value used by `TransportError::InvalidInstance`.
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub enum TransportInterfaceType {
    Gpio,
    Uart,
    Spi,
    I2c,
    Emulator,
    ProxyOps,
}

/// Return type to be used in `Transport` methods.
pub type Result<T> = anyhow::Result<T, TransportError>;

/// Convenience macro to be used in implementations of `Transport`.
#[macro_export]
macro_rules! bail {
    ($err:expr $(,)?) => {
        return Err($err.into())
    };
}

/// Convenience macro to be used in implementations of `Transport`.
#[macro_export]
macro_rules! ensure {
    ($cond:expr, $err:expr $(,)?) => {
        if !$cond {
            return Err($err.into());
        }
    };
}

/// Function for conveniently wrapping (the flat string representation of) an anyhow::Error in a
/// TransportError.
///
/// Example usage:
/// serialport::available_ports().wrap(UartError::EnumerationError)?;
pub trait WrapInTransportError<T> {
    fn wrap<S: Into<TransportError>>(self, kind: impl FnOnce(String) -> S) -> Result<T>;
}

impl<T, E: ToString> WrapInTransportError<T> for anyhow::Result<T, E> {
    fn wrap<S: Into<TransportError>>(self, kind: impl FnOnce(String) -> S) -> Result<T> {
        self.map_err(|e| kind(e.to_string()).into())
    }
}
<|endoftext|>