<commit_before>use std::error::FromError;
use std::mem;
use std::io;
use std::slice;

use color;
use color::ColorType;
use buffer::{ImageBuffer, Pixel};
use traits::Primitive;

/// An enumeration of Image Errors
#[deriving(Show, PartialEq, Eq)]
pub enum ImageError {
    /// The Image is not formatted properly
    FormatError(String),

    /// The Image's dimensions are either too small or too large
    DimensionError,

    /// The Decoder does not support this image format
    UnsupportedError(String),

    /// The Decoder does not support this color type
    UnsupportedColor(ColorType),

    /// Not enough data was provided to the Decoder
    /// to decode the image
    NotEnoughData,

    /// An I/O Error occurred while decoding the image
    IoError(io::IoError),

    /// The end of the image has been reached
    ImageEnd
}

impl FromError<io::IoError> for ImageError {
    fn from_error(err: io::IoError) -> ImageError {
        ImageError::IoError(err)
    }
}

/// Result of an image decoding/encoding process
pub type ImageResult<T> = Result<T, ImageError>;

/// An enumeration of supported image formats.
/// Not all formats support both encoding and decoding.
#[deriving(PartialEq, Eq, Show)]
pub enum ImageFormat {
    /// An Image in PNG Format
    PNG,

    /// An Image in JPEG Format
    JPEG,

    /// An Image in GIF Format
    GIF,

    /// An Image in WEBP Format
    WEBP,

    /// An Image in PPM Format
    PPM,

    /// An Image in TIFF Format
    TIFF,

    /// An Image in TGA Format
    TGA
}

/// The trait that all decoders implement
pub trait ImageDecoder {
    /// Returns a tuple containing the width and height of the image
    fn dimensions(&mut self) -> ImageResult<(u32, u32)>;

    /// Returns the color type of the image e.g RGB(8) (8bit RGB)
    fn colortype(&mut self) -> ImageResult<ColorType>;

    /// Returns the length in bytes of one decoded row of the image
    fn row_len(&mut self) -> ImageResult<uint>;

    /// Reads one row from the image into buf and returns the row index
    fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32>;

    /// Decodes the entire image and return it as a Vector
    fn read_image(&mut self) -> ImageResult<Vec<u8>>;

    /// Decodes a specific region of the image, represented by the rectangle
    /// starting from ```x``` and ```y``` and having ```length``` and ```width```
    fn load_rect(&mut self, x: u32, y: u32, length: u32, width: u32) -> ImageResult<Vec<u8>> {
        let (w, h) = try!(self.dimensions());

        if length > h || width > w || x > w || y > h {
            return Err(ImageError::DimensionError)
        }

        let c = try!(self.colortype());

        let bpp = color::bits_per_pixel(c) / 8;

        let rowlen  = try!(self.row_len());

        let mut buf = Vec::from_elem(length as uint * width as uint * bpp, 0u8);
        let mut tmp = Vec::from_elem(rowlen, 0u8);

        loop {
            let row = try!(self.read_scanline(tmp.as_mut_slice()));

            if row - 1 == y {
                break
            }
        }

        for i in range(0, length as uint) {
            {
                let from = tmp.slice_from(x as uint * bpp)
                              .slice_to(width as uint * bpp);

                let to   = buf.slice_from_mut(i * width as uint * bpp)
                              .slice_to_mut(width as uint * bpp);

                slice::bytes::copy_memory(to, from);
            }

            let _ = try!(self.read_scanline(tmp.as_mut_slice()));
        }

        Ok(buf)
    }
}

/// Immutable pixel iterator
pub struct Pixels<'a, I:'a> {
    image:  &'a I,
    x:      u32,
    y:      u32,
    width:  u32,
    height: u32
}

impl<'a, T: Primitive, P: Pixel<T>, I: GenericImage<P>> Iterator<(u32, u32, P)> for Pixels<'a, I> {
    fn next(&mut self) -> Option<(u32, u32, P)> {
        if self.x >= self.width {
            self.x =  0;
            self.y += 1;
        }

        if self.y >= self.height {
            None
        } else {
            let pixel = self.image.get_pixel(self.x, self.y);
            let p = (self.x, self.y, pixel);

            self.x += 1;

            Some(p)
        }
    }
}

/// Mutable pixel iterator
pub struct MutPixels<'a, I:'a> {
    image:  &'a mut I,
    x:      u32,
    y:      u32,
    width:  u32,
    height: u32
}

impl<'a, T: Primitive, P: Pixel<T>, I: GenericImage<P>> Iterator<(u32, u32, &'a mut P)> for MutPixels<'a, I> {
    fn next(&mut self) -> Option<(u32, u32, &'a mut P)> {
        if self.x >= self.width {
            self.x =  0;
            self.y += 1;
        }

        if self.y >= self.height {
            None
        } else {
            let tmp = self.image.get_pixel_mut(self.x, self.y);

            //error: lifetime of `self` is too short to guarantee its contents
            //       can be safely reborrowed...
            let ptr = unsafe {
                mem::transmute(tmp)
            };

            let p = (self.x, self.y, ptr);

            self.x += 1;

            Some(p)
        }
    }
}

/// A trait for manipulating images.
pub trait GenericImage<P> {
    /// The width and height of this image.
    fn dimensions(&self) -> (u32, u32);

    /// The bounding rectangle of this image.
    fn bounds(&self) -> (u32, u32, u32, u32);

    /// Returns the pixel located at (x, y)
    ///
    /// # Panics
    ///
    /// Panics if `(x, y)` is out of bounds.
    /// TODO: change this signature to &P
    fn get_pixel(&self, x: u32, y: u32) -> P;

    /// Puts a pixel at location (x, y)
    ///
    /// # Panics
    ///
    /// Panics if `(x, y)` is out of bounds.
    fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut P;

    /// Put a pixel at location (x, y)
    ///
    /// # Panics
    ///
    /// Panics if `(x, y)` is out of bounds.
    fn put_pixel(&mut self, x: u32, y: u32, pixel: P);

    ///Put a pixel at location (x, y), taking into account alpha channels
    #[deprecated = "This method will be removed. Blend the pixel directly instead."]
    fn blend_pixel(&mut self, x: u32, y: u32, pixel: P);

    /// Returns an Iterator over the pixels of this image.
    /// The iterator yields the coordinates of each pixel
    /// along with their value
    fn pixels(&self) -> Pixels<Self> {
        let (width, height) = self.dimensions();

        Pixels {
            image:  self,
            x:      0,
            y:      0,
            width:  width,
            height: height,
        }
    }

    /// Returns an Iterator over mutable pixels of this image.
    /// The iterator yields the coordinates of each pixel
    /// along with a mutable reference to them.
    fn pixels_mut(&mut self) -> MutPixels<Self> {
        let (width, height) = self.dimensions();

        MutPixels {
            image:  self,
            x:      0,
            y:      0,
            width:  width,
            height: height,
        }
    }
}

/// A View into another image
pub struct SubImage <'a, I:'a> {
    image:   &'a mut I,
    xoffset: u32,
    yoffset: u32,
    xstride: u32,
    ystride: u32,
}

impl<'a, T: Primitive + 'static, P: Pixel<T>, I: GenericImage<P>> SubImage<'a, I> {
    ///Construct a new subimage
    pub fn new(image: &mut I, x: u32, y: u32, width: u32, height: u32) -> SubImage<I> {
        SubImage {
            image:   image,
            xoffset: x,
            yoffset: y,
            xstride: width,
            ystride: height,
        }
    }

    /// Returns a mutable reference to the wrapped image.
    pub fn inner_mut(&mut self) -> &mut I {
        &mut (*self.image)
    }

    ///Change the coordinates of this subimage.
    pub fn change_bounds(&mut self, x: u32, y: u32, width: u32, height: u32) {
        self.xoffset = x;
        self.yoffset = y;
        self.xstride = width;
        self.ystride = height;
    }

    ///Convert this subimage to an ImageBuffer
    pub fn to_image(&self) -> ImageBuffer<Vec<T>, T, P> {
        let mut out = ImageBuffer::new(self.xstride, self.ystride);

        for y in range(0, self.ystride) {
            for x in range(0, self.xstride) {
                let p = self.get_pixel(x, y);
                out.put_pixel(x, y, p);
            }
        }

        out
    }
}

#[allow(deprecated)]
impl<'a, T: Primitive, P: Pixel<T>, I: GenericImage<P>> GenericImage<P> for SubImage<'a, I> {
    fn dimensions(&self) -> (u32, u32) {
        (self.xstride, self.ystride)
    }

    fn bounds(&self) -> (u32, u32, u32, u32) {
        (self.xoffset, self.yoffset, self.xstride, self.ystride)
    }

    fn get_pixel(&self, x: u32, y: u32) -> P {
        self.image.get_pixel(x + self.xoffset, y + self.yoffset)
    }

    fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
        self.image.put_pixel(x + self.xoffset, y + self.yoffset, pixel)
    }

    #[deprecated = "This method will be removed. Blend the pixel directly instead."]
    fn blend_pixel(&mut self, x: u32, y: u32, pixel: P) {
        self.image.blend_pixel(x + self.xoffset, y + self.yoffset, pixel)
    }

    fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut P {
        self.image.get_pixel_mut(x + self.xoffset, y + self.yoffset)
    }
}

#[cfg(test)]
mod tests {

    use super::GenericImage;
    use buffer::ImageBuffer;
    use color::{Rgba};

    #[test]
    ///Test that alpha blending works as expected
    #[allow(deprecated)]
    fn test_image_alpha_blending() {
        let mut target = ImageBuffer::new(1, 1);
        target.put_pixel(0, 0, Rgba([255u8, 0, 0, 255]));
        assert!(*target.get_pixel(0, 0) == Rgba([255, 0, 0, 255]));
        target.blend_pixel(0, 0, Rgba([0, 255, 0, 255]));
        assert!(*target.get_pixel(0, 0) == Rgba([0, 255, 0, 255]));

        //Blending an alpha channel onto a solid background
        target.blend_pixel(0, 0, Rgba([255, 0, 0, 127]));
        assert!(*target.get_pixel(0, 0) == Rgba([127, 127, 0, 255]));

        //Blending two alpha channels
        target.put_pixel(0, 0, Rgba([0, 255, 0, 127]));
        target.blend_pixel(0, 0, Rgba([255, 0, 0, 127]));
        assert!(*target.get_pixel(0, 0) == Rgba([169, 85, 0, 190]));
    }
}
<commit_msg>Deprecation of pixels_mut()…<commit_after>use std::error::FromError;
use std::mem;
use std::io;
use std::slice;

use color;
use color::ColorType;
use buffer::{ImageBuffer, Pixel};
use traits::Primitive;

/// An enumeration of Image Errors
#[deriving(Show, PartialEq, Eq)]
pub enum ImageError {
    /// The Image is not formatted properly
    FormatError(String),

    /// The Image's dimensions are either too small or too large
    DimensionError,

    /// The Decoder does not support this image format
    UnsupportedError(String),

    /// The Decoder does not support this color type
    UnsupportedColor(ColorType),

    /// Not enough data was provided to the Decoder
    /// to decode the image
    NotEnoughData,

    /// An I/O Error occurred while decoding the image
    IoError(io::IoError),

    /// The end of the image has been reached
    ImageEnd
}

impl FromError<io::IoError> for ImageError {
    fn from_error(err: io::IoError) -> ImageError {
        ImageError::IoError(err)
    }
}

/// Result of an image decoding/encoding process
pub type ImageResult<T> = Result<T, ImageError>;

/// An enumeration of supported image formats.
/// Not all formats support both encoding and decoding.
#[deriving(PartialEq, Eq, Show)]
pub enum ImageFormat {
    /// An Image in PNG Format
    PNG,

    /// An Image in JPEG Format
    JPEG,

    /// An Image in GIF Format
    GIF,

    /// An Image in WEBP Format
    WEBP,

    /// An Image in PPM Format
    PPM,

    /// An Image in TIFF Format
    TIFF,

    /// An Image in TGA Format
    TGA
}

/// The trait that all decoders implement
pub trait ImageDecoder {
    /// Returns a tuple containing the width and height of the image
    fn dimensions(&mut self) -> ImageResult<(u32, u32)>;

    /// Returns the color type of the image e.g RGB(8) (8bit RGB)
    fn colortype(&mut self) -> ImageResult<ColorType>;

    /// Returns the length in bytes of one decoded row of the image
    fn row_len(&mut self) -> ImageResult<uint>;

    /// Reads one row from the image into buf and returns the row index
    fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32>;

    /// Decodes the entire image and return it as a Vector
    fn read_image(&mut self) -> ImageResult<Vec<u8>>;

    /// Decodes a specific region of the image, represented by the rectangle
    /// starting from ```x``` and ```y``` and having ```length``` and ```width```
    fn load_rect(&mut self, x: u32, y: u32, length: u32, width: u32) -> ImageResult<Vec<u8>> {
        let (w, h) = try!(self.dimensions());

        if length > h || width > w || x > w || y > h {
            return Err(ImageError::DimensionError)
        }

        let c = try!(self.colortype());

        let bpp = color::bits_per_pixel(c) / 8;

        let rowlen  = try!(self.row_len());

        let mut buf = Vec::from_elem(length as uint * width as uint * bpp, 0u8);
        let mut tmp = Vec::from_elem(rowlen, 0u8);

        loop {
            let row = try!(self.read_scanline(tmp.as_mut_slice()));

            if row - 1 == y {
                break
            }
        }

        for i in range(0, length as uint) {
            {
                let from = tmp.slice_from(x as uint * bpp)
                              .slice_to(width as uint * bpp);

                let to   = buf.slice_from_mut(i * width as uint * bpp)
                              .slice_to_mut(width as uint * bpp);

                slice::bytes::copy_memory(to, from);
            }

            let _ = try!(self.read_scanline(tmp.as_mut_slice()));
        }

        Ok(buf)
    }
}

/// Immutable pixel iterator
pub struct Pixels<'a, I:'a> {
    image:  &'a I,
    x:      u32,
    y:      u32,
    width:  u32,
    height: u32
}

impl<'a, T: Primitive, P: Pixel<T>, I: GenericImage<P>> Iterator<(u32, u32, P)> for Pixels<'a, I> {
    fn next(&mut self) -> Option<(u32, u32, P)> {
        if self.x >= self.width {
            self.x =  0;
            self.y += 1;
        }

        if self.y >= self.height {
            None
        } else {
            let pixel = self.image.get_pixel(self.x, self.y);
            let p = (self.x, self.y, pixel);

            self.x += 1;

            Some(p)
        }
    }
}

/// Mutable pixel iterator
#[deprecated = "It is currently not possible to create a safe iterator for this in Rust. You have to use an iterator over the image buffer instead."]
pub struct MutPixels<'a, I:'a> {
    image:  &'a mut I,
    x:      u32,
    y:      u32,
    width:  u32,
    height: u32
}

impl<'a, T: Primitive, P: Pixel<T>, I: GenericImage<P>> Iterator<(u32, u32, &'a mut P)> for MutPixels<'a, I> {
    fn next(&mut self) -> Option<(u32, u32, &'a mut P)> {
        if self.x >= self.width {
            self.x =  0;
            self.y += 1;
        }

        if self.y >= self.height {
            None
        } else {
            let tmp = self.image.get_pixel_mut(self.x, self.y);

            // NOTE: This is potentially dangerous. It would require the signature fn next(&'a mut self) to be safe.
            //error: lifetime of `self` is too short to guarantee its contents
            //       can be safely reborrowed...
            let ptr = unsafe {
                mem::transmute(tmp)
            };

            let p = (self.x, self.y, ptr);

            self.x += 1;

            Some(p)
        }
    }
}

/// A trait for manipulating images.
pub trait GenericImage<P> {
    /// The width and height of this image.
    fn dimensions(&self) -> (u32, u32);

    /// The bounding rectangle of this image.
    fn bounds(&self) -> (u32, u32, u32, u32);

    /// Returns the pixel located at (x, y)
    ///
    /// # Panics
    ///
    /// Panics if `(x, y)` is out of bounds.
    /// TODO: change this signature to &P
    fn get_pixel(&self, x: u32, y: u32) -> P;

    /// Puts a pixel at location (x, y)
    ///
    /// # Panics
    ///
    /// Panics if `(x, y)` is out of bounds.
    fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut P;

    /// Put a pixel at location (x, y)
    ///
    /// # Panics
    ///
    /// Panics if `(x, y)` is out of bounds.
    fn put_pixel(&mut self, x: u32, y: u32, pixel: P);

    ///Put a pixel at location (x, y), taking into account alpha channels
    #[deprecated = "This method will be removed. Blend the pixel directly instead."]
    fn blend_pixel(&mut self, x: u32, y: u32, pixel: P);

    /// Returns an Iterator over the pixels of this image.
    /// The iterator yields the coordinates of each pixel
    /// along with their value
    fn pixels(&self) -> Pixels<Self> {
        let (width, height) = self.dimensions();

        Pixels {
            image:  self,
            x:      0,
            y:      0,
            width:  width,
            height: height,
        }
    }

    /// Returns an Iterator over mutable pixels of this image.
    /// The iterator yields the coordinates of each pixel
    /// along with a mutable reference to them.
    #[allow(deprecated)]
    #[deprecated = "This cannot be implemented safely Rust. Please use the image buffer directly."]
    fn pixels_mut(&mut self) -> MutPixels<Self> {
        let (width, height) = self.dimensions();

        MutPixels {
            image:  self,
            x:      0,
            y:      0,
            width:  width,
            height: height,
        }
    }
}

/// A View into another image
pub struct SubImage <'a, I:'a> {
    image:   &'a mut I,
    xoffset: u32,
    yoffset: u32,
    xstride: u32,
    ystride: u32,
}

impl<'a, T: Primitive + 'static, P: Pixel<T>, I: GenericImage<P>> SubImage<'a, I> {
    ///Construct a new subimage
    pub fn new(image: &mut I, x: u32, y: u32, width: u32, height: u32) -> SubImage<I> {
        SubImage {
            image:   image,
            xoffset: x,
            yoffset: y,
            xstride: width,
            ystride: height,
        }
    }

    /// Returns a mutable reference to the wrapped image.
    pub fn inner_mut(&mut self) -> &mut I {
        &mut (*self.image)
    }

    ///Change the coordinates of this subimage.
    pub fn change_bounds(&mut self, x: u32, y: u32, width: u32, height: u32) {
        self.xoffset = x;
        self.yoffset = y;
        self.xstride = width;
        self.ystride = height;
    }

    ///Convert this subimage to an ImageBuffer
    pub fn to_image(&self) -> ImageBuffer<Vec<T>, T, P> {
        let mut out = ImageBuffer::new(self.xstride, self.ystride);

        for y in range(0, self.ystride) {
            for x in range(0, self.xstride) {
                let p = self.get_pixel(x, y);
                out.put_pixel(x, y, p);
            }
        }

        out
    }
}

#[allow(deprecated)]
impl<'a, T: Primitive, P: Pixel<T>, I: GenericImage<P>> GenericImage<P> for SubImage<'a, I> {
    fn dimensions(&self) -> (u32, u32) {
        (self.xstride, self.ystride)
    }

    fn bounds(&self) -> (u32, u32, u32, u32) {
        (self.xoffset, self.yoffset, self.xstride, self.ystride)
    }

    fn get_pixel(&self, x: u32, y: u32) -> P {
        self.image.get_pixel(x + self.xoffset, y + self.yoffset)
    }

    fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
        self.image.put_pixel(x + self.xoffset, y + self.yoffset, pixel)
    }

    #[deprecated = "This method will be removed. Blend the pixel directly instead."]
    fn blend_pixel(&mut self, x: u32, y: u32, pixel: P) {
        self.image.blend_pixel(x + self.xoffset, y + self.yoffset, pixel)
    }

    fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut P {
        self.image.get_pixel_mut(x + self.xoffset, y + self.yoffset)
    }
}

#[cfg(test)]
mod tests {

    use super::GenericImage;
    use buffer::ImageBuffer;
    use color::{Rgba};

    #[test]
    ///Test that alpha blending works as expected
    #[allow(deprecated)]
    fn test_image_alpha_blending() {
        let mut target = ImageBuffer::new(1, 1);
        target.put_pixel(0, 0, Rgba([255u8, 0, 0, 255]));
        assert!(*target.get_pixel(0, 0) == Rgba([255, 0, 0, 255]));
        target.blend_pixel(0, 0, Rgba([0, 255, 0, 255]));
        assert!(*target.get_pixel(0, 0) == Rgba([0, 255, 0, 255]));

        //Blending an alpha channel onto a solid background
        target.blend_pixel(0, 0, Rgba([255, 0, 0, 127]));
        assert!(*target.get_pixel(0, 0) == Rgba([127, 127, 0, 255]));

        //Blending two alpha channels
        target.put_pixel(0, 0, Rgba([0, 255, 0, 127]));
        target.blend_pixel(0, 0, Rgba([255, 0, 0, 127]));
        assert!(*target.get_pixel(0, 0) == Rgba([169, 85, 0, 190]));
    }
}
<|endoftext|>


<commit_before><commit_msg>I think part 5 is working now<commit_after><|endoftext|>


<commit_before>#![allow(non_snake_case)]

use std::fmt;
use std::mem;
use std::slice;
use num;
use approx;
use angle::{Deg, Angle, FromAngle, IntoAngle, Turns};
use angle;
use channel::{PosFreeChannel, FreeChannelScalar, AngularChannel, AngularChannelScalar,
              ChannelFormatCast, ChannelCast, ColorChannel};
use color::{Color, PolarColor, FromTuple, Lerp, Bounded, Flatten};
use convert::{GetChroma, GetHue};

pub struct LchabTag;

#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct Lchab<T, A = Deg<T>> {
    pub L: PosFreeChannel<T>,
    pub chroma: PosFreeChannel<T>,
    pub hue: AngularChannel<A>,
}

impl<T, A> Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    pub fn from_channels(L: T, chroma: T, hue: A) -> Self {
        Lchab {
            L: PosFreeChannel::new(L),
            chroma: PosFreeChannel::new(chroma),
            hue: AngularChannel::new(hue),
        }
    }

    impl_color_color_cast_angular!(Lchab {L, chroma, hue},
        chan_traits={FreeChannelScalar});

    pub fn L(&self) -> T {
        self.L.0.clone()
    }
    pub fn chroma(&self) -> T {
        self.chroma.0.clone()
    }
    pub fn hue(&self) -> A {
        self.hue.0.clone()
    }
    pub fn L_mut(&mut self) -> &mut T {
        &mut self.L.0
    }
    pub fn chroma_mut(&mut self) -> &mut T {
        &mut self.chroma.0
    }
    pub fn hue_mut(&mut self) -> &mut A {
        &mut self.hue.0
    }
    pub fn set_L(&mut self, val: T) {
        self.L.0 = val;
    }
    pub fn set_chroma(&mut self, val: T) {
        self.chroma.0 = val;
    }
    pub fn set_hue(&mut self, val: A) {
        self.hue.0 = val;
    }
}

impl<T, A> Color for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    type Tag = LchabTag;
    type ChannelsTuple = (T, T, A);

    fn num_channels() -> u32 {
        3
    }
    fn to_tuple(self) -> Self::ChannelsTuple {
        (self.L.0, self.chroma.0, self.hue.0)
    }
}

impl<T, A> PolarColor for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    type Angular = A;
    type Cartesian = T;
}

impl<T, A> FromTuple for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    fn from_tuple(values: Self::ChannelsTuple) -> Self {
        Lchab::from_channels(values.0, values.1, values.2)
    }
}

impl<T, A> Lerp for Lchab<T, A>
    where T: FreeChannelScalar + Lerp,
          A: AngularChannelScalar + Lerp
{
    type Position = A::Position;

    impl_color_lerp_angular!(Lchab<T> {hue, L, chroma});
}

impl<T, A> Bounded for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    impl_color_bounded!(Lchab {L, chroma, hue});
}

impl<T, A> Flatten for Lchab<T, A>
    where T: FreeChannelScalar + num::Float,
          A: AngularChannelScalar + Angle<Scalar = T> + FromAngle<Turns<T>>
{
    type ScalarFormat = T;

    impl_color_as_slice!(T);
    impl_color_from_slice_angular!(Lchab<T, A> {hue:AngularChannel - 0,
        chroma:PosFreeChannel - 1, L:PosFreeChannel - 2});
}

impl<T, A> approx::ApproxEq for Lchab<T, A>
    where T: FreeChannelScalar + approx::ApproxEq<Epsilon = A::Epsilon>,
          A: AngularChannelScalar + approx::ApproxEq,
          A::Epsilon: Clone + num::Float
{
    impl_approx_eq!({L, chroma, hue});
}

impl<T, A> Default for Lchab<T, A>
    where T: FreeChannelScalar + num::Zero,
          A: AngularChannelScalar + num::Zero
{
    impl_color_default!(Lchab {hue: AngularChannel,
        L: PosFreeChannel, chroma: PosFreeChannel});
}

impl<T, A> fmt::Display for Lchab<T, A>
    where T: FreeChannelScalar + fmt::Display,
          A: AngularChannelScalar + fmt::Display
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Lch(ab)({}, {}, {})", self.L, self.chroma, self.hue)
    }
}

impl<T, A> GetChroma for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    type ChromaType = T;
    fn get_chroma(&self) -> T {
        return self.chroma();
    }
}

impl<T, A> GetHue for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    impl_color_get_hue_angular!(Lchab);
}
<commit_msg>Implemented Lab->Lch(ab) and back.<commit_after>#![allow(non_snake_case)]

use std::fmt;
use std::mem;
use std::slice;
use num;
use approx;
use angle::{Deg, Angle, FromAngle, IntoAngle, Turns, Rad};
use angle;
use channel::{PosFreeChannel, FreeChannelScalar, AngularChannel, AngularChannelScalar,
              ChannelFormatCast, ChannelCast, ColorChannel};
use color::{Color, PolarColor, FromTuple, Lerp, Bounded, Flatten};
use convert::{GetChroma, GetHue, FromColor};
use lab::Lab;

pub struct LchabTag;

#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct Lchab<T, A = Deg<T>> {
    pub L: PosFreeChannel<T>,
    pub chroma: PosFreeChannel<T>,
    pub hue: AngularChannel<A>,
}

impl<T, A> Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    pub fn from_channels(L: T, chroma: T, hue: A) -> Self {
        Lchab {
            L: PosFreeChannel::new(L),
            chroma: PosFreeChannel::new(chroma),
            hue: AngularChannel::new(hue),
        }
    }

    impl_color_color_cast_angular!(Lchab {L, chroma, hue},
        chan_traits={FreeChannelScalar});

    pub fn L(&self) -> T {
        self.L.0.clone()
    }
    pub fn chroma(&self) -> T {
        self.chroma.0.clone()
    }
    pub fn hue(&self) -> A {
        self.hue.0.clone()
    }
    pub fn L_mut(&mut self) -> &mut T {
        &mut self.L.0
    }
    pub fn chroma_mut(&mut self) -> &mut T {
        &mut self.chroma.0
    }
    pub fn hue_mut(&mut self) -> &mut A {
        &mut self.hue.0
    }
    pub fn set_L(&mut self, val: T) {
        self.L.0 = val;
    }
    pub fn set_chroma(&mut self, val: T) {
        self.chroma.0 = val;
    }
    pub fn set_hue(&mut self, val: A) {
        self.hue.0 = val;
    }
}

impl<T, A> Color for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    type Tag = LchabTag;
    type ChannelsTuple = (T, T, A);

    fn num_channels() -> u32 {
        3
    }
    fn to_tuple(self) -> Self::ChannelsTuple {
        (self.L.0, self.chroma.0, self.hue.0)
    }
}

impl<T, A> PolarColor for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    type Angular = A;
    type Cartesian = T;
}

impl<T, A> FromTuple for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    fn from_tuple(values: Self::ChannelsTuple) -> Self {
        Lchab::from_channels(values.0, values.1, values.2)
    }
}

impl<T, A> Lerp for Lchab<T, A>
    where T: FreeChannelScalar + Lerp,
          A: AngularChannelScalar + Lerp
{
    type Position = A::Position;

    impl_color_lerp_angular!(Lchab<T> {hue, L, chroma});
}

impl<T, A> Bounded for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    impl_color_bounded!(Lchab {L, chroma, hue});
}

impl<T, A> Flatten for Lchab<T, A>
    where T: FreeChannelScalar + num::Float,
          A: AngularChannelScalar + Angle<Scalar = T> + FromAngle<Turns<T>>
{
    type ScalarFormat = T;

    impl_color_as_slice!(T);
    impl_color_from_slice_angular!(Lchab<T, A> {hue:AngularChannel - 0,
        chroma:PosFreeChannel - 1, L:PosFreeChannel - 2});
}

impl<T, A> approx::ApproxEq for Lchab<T, A>
    where T: FreeChannelScalar + approx::ApproxEq<Epsilon = A::Epsilon>,
          A: AngularChannelScalar + approx::ApproxEq,
          A::Epsilon: Clone + num::Float
{
    impl_approx_eq!({L, chroma, hue});
}

impl<T, A> Default for Lchab<T, A>
    where T: FreeChannelScalar + num::Zero,
          A: AngularChannelScalar + num::Zero
{
    impl_color_default!(Lchab {hue: AngularChannel,
        L: PosFreeChannel, chroma: PosFreeChannel});
}

impl<T, A> fmt::Display for Lchab<T, A>
    where T: FreeChannelScalar + fmt::Display,
          A: AngularChannelScalar + fmt::Display
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Lch(ab)({}, {}, {})", self.L, self.chroma, self.hue)
    }
}

impl<T, A> GetChroma for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    type ChromaType = T;
    fn get_chroma(&self) -> T {
        return self.chroma();
    }
}

impl<T, A> GetHue for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar
{
    impl_color_get_hue_angular!(Lchab);
}

impl<T, A> FromColor<Lab<T>> for Lchab<T, A>
    where T: FreeChannelScalar,
          A: AngularChannelScalar + FromAngle<Rad<T>> + Angle
{
    fn from_color(from: &Lab<T>) -> Self {
        let L = from.L();
        let chroma = (from.a() * from.a() + from.b() * from.b()).sqrt();
        let hue = A::from_angle(Rad::atan2(from.b(), from.a()));

        Lchab::from_channels(L, chroma, <A as Angle>::normalize(hue))
    }
}

impl<T, A> FromColor<Lchab<T, A>> for Lab<T>
    where T: FreeChannelScalar,
          A: AngularChannelScalar + Angle<Scalar = T>
{
    fn from_color(from: &Lchab<T, A>) -> Self {
        let L = from.L();
        let a = from.chroma() * from.hue().cos();
        let b = from.chroma() * from.hue().sin();

        Lab::from_channels(L, a, b)
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use lab::Lab;
    use angle::*;
    use convert::FromColor;

    #[test]
    fn test_from_lab() {
        let c1 = Lab::from_channels(50.0, 30.0, 30.0);
        let t1 = Lchab::from_color(&c1);
        assert_relative_eq!(t1, Lchab::from_channels(50.0, 42.4264, Deg(45.0000)), epsilon=1e-4);
        assert_relative_eq!(Lab::from_color(&t1), c1, epsilon=1e-4);

        let c2 = Lab::from_channels(0.0, 0.0, 0.0);
        let t2 = Lchab::from_color(&c2);
        assert_relative_eq!(t2, Lchab::from_channels(0.0, 0.0, Rad(0.0)), epsilon=1e-4);
        assert_relative_eq!(Lab::from_color(&t2), c2, epsilon=1e-4);

        let c3 = Lab::from_channels(0.0, 55.0, 95.0);
        let t3 = Lchab::from_color(&c3);
        assert_relative_eq!(t3, Lchab::from_channels(0.0, 109.7725, Deg(59.9314)), epsilon=1e-4);
        assert_relative_eq!(Lab::from_color(&t3), c3, epsilon=1e-4);

        let c4 = Lab::from_channels(67.2, -80.0, 80.0);
        let t4 = Lchab::from_color(&c4);
        assert_relative_eq!(t4, Lchab::from_channels(67.2, 113.1371, Deg(135.0)), epsilon=1e-4);
        assert_relative_eq!(Lab::from_color(&t4), c4, epsilon=1e-4);

        let c5 = Lab::from_channels(45.0, 100.0, 0.0);
        let t5 = Lchab::from_color(&c5);
        assert_relative_eq!(t5, Lchab::from_channels(45.0, 100.0, Deg(0.0)), epsilon=1e-4);
        assert_relative_eq!(Lab::from_color(&t5), c5, epsilon=1e-4);

        let c6 = Lab::from_channels(82.0, 72.5, -67.3);
        let t6 = Lchab::from_color(&c6);
        assert_relative_eq!(t6, Lchab::from_channels(82.0, 98.9219, Deg(317.1302)), epsilon=1e-4);
        assert_relative_eq!(Lab::from_color(&t6), c6, epsilon=1e-4);
    }

    #[test]
    fn test_to_lab() {
        let c1 = Lchab::from_channels(75.0, 80.0, Deg(330.0));
        let t1 = Lab::from_color(&c1);
        assert_relative_eq!(t1, Lab::from_channels(75.0, 69.2820, -40.00), epsilon=1e-4);
        assert_relative_eq!(Lchab::from_color(&t1), c1, epsilon=1e-4);

        let c2 = Lchab::from_channels(55.5, 60.0, Deg(0.0));
        let t2 = Lab::from_color(&c2);
        assert_relative_eq!(t2, Lab::from_channels(55.5, 60.0, 0.0), epsilon=1e-4);
        assert_relative_eq!(Lchab::from_color(&t2), c2, epsilon=1e-4);

        let c3 = Lchab::from_channels(88.8, 52.0, Deg(1.5));
        let t3 = Lab::from_color(&c3);
        assert_relative_eq!(t3, Lab::from_channels(88.8, 51.9822, 1.3612), epsilon=1e-4);
        assert_relative_eq!(Lchab::from_color(&t3), c3, epsilon=1e-4);

        let c4 = Lchab::from_channels(62.0, 79.0, Deg(225.0));
        let t4 = Lab::from_color(&c4);
        assert_relative_eq!(t4, Lab::from_channels(62.0, -55.8614, -55.8614), epsilon=1e-4);
        assert_relative_eq!(Lchab::from_color(&t4), c4, epsilon=1e-4);
    }
}
<|endoftext|>


<commit_before>use std::collections::LinkedList;

use token::Token;

use std::cell::Cell;
use std::rc::Rc;
use regex::Regex;
use context::Context;
use token::Posn;

pub trait ESCharExt {
    fn is_es_newline(self) -> bool;
    fn is_es_whitespace(self) -> bool;
}

impl ESCharExt for char {
    fn is_es_newline(self) -> bool {
        match self {
            '\u{000a}' | '\u{000d}' | '\u{2028}' | '\u{2029}' => true,
            _ => false
        }
    }

    fn is_es_whitespace(self) -> bool {
        match self {
              '\u{0009}' | '\u{000b}' | '\u{000c}' | '\u{0020}' | '\u{00a0}'
            | '\u{1680}' | '\u{2000}' | '\u{2001}' | '\u{2002}' | '\u{2003}' | '\u{2004}'
            | '\u{2005}' | '\u{2006}' | '\u{2009}' | '\u{200a}' | '\u{202f}' | '\u{205f}'
            | '\u{3000}' | '\u{feff}' => true,
            _ => false
        }
    }
}

struct LineOrientedReader<I> {
    chars: I,
    curr_char: Option<char>,
    next_char: Option<char>,
    curr_posn: Posn
}

impl<I> LineOrientedReader<I> where I: Iterator<Item=char> {
    pub fn new(mut chars: I) -> LineOrientedReader<I> {
        let curr_char = chars.next();
        let next_char = if curr_char.is_some() { chars.next() } else { None };
        LineOrientedReader {
            chars: chars,
            curr_char: curr_char,
            next_char: next_char,
            curr_posn: Posn {
                offset: 0,
                line: 0,
                column: 0
            }
        }
    }

    pub fn curr_char(&mut self) -> Option<char> { self.curr_char }
    pub fn curr_posn(&mut self) -> Posn { self.curr_posn }

    pub fn bump(&mut self) {
        let curr_char = self.next_char;
        let next_char = if curr_char.is_some() { self.chars.next() } else { None };

        self.curr_char = curr_char;
        self.next_char = next_char;

        if (curr_char == Some('\r') && next_char != Some('\n')) ||
           curr_char == Some('\n') ||
           curr_char == Some('\u{2028}') ||
           curr_char == Some('\u{2029}') {
            self.curr_posn.line += 1;
            self.curr_posn.column = 0;
        } else {
            self.curr_posn.column += 1;
        }

        self.curr_posn.offset += 1;
    }
}

struct TokenBuffer {
    tokens: LinkedList<Token>
}

impl TokenBuffer {
    fn new() -> TokenBuffer {
        TokenBuffer {
            tokens: LinkedList::new()
        }
    }

    fn ensure_nonempty(&mut self, get: &fn() -> Token) {
        if self.tokens.len() == 0 {
            self.tokens.push_back(get());
        }
    }

    fn read_token(&mut self) -> Token {
        assert!(self.tokens.len() > 0);
        self.tokens.pop_front().unwrap()
    }
}

pub struct Lexer<I> {
    reader: LineOrientedReader<I>,
    cx: Rc<Cell<Context>>,
    lookahead: TokenBuffer
}

impl<I> Lexer<I> where I: Iterator<Item=char> {
    // constructor

    pub fn new(chars: I, cx: Rc<Cell<Context>>) -> Lexer<I> {
        Lexer {
            reader: LineOrientedReader::new(chars),
            cx: cx,
            lookahead: TokenBuffer::new()
        }
    }

    // public methods

    pub fn read_token(&mut self) -> Token {
        self.lookahead.ensure_nonempty(|| {
            self.read_next_token()
        });
        unimplemented!()
    }

    // private methods

    fn read_next_token(&mut self) -> Token {
        unimplemented!()
    }

    fn is_whitespace(&mut self) -> bool {
        match self.reader.curr_char() {
            Some(ch) => ch.is_es_whitespace(),
            None => false
        }
    }

    fn eat(&mut self) -> Option<char> {
        let ch = self.reader.curr_char();
        self.reader.bump();
        ch
    }

    fn skip_whitespace(&mut self) {
        while self.is_whitespace() {
            self.reader.bump();
        }
    }
}

impl<I> Iterator for Lexer<I> where I: Iterator<Item=char> {
    type Item = Token;

    fn next(&mut self) -> Option<Token> {
        self.skip_whitespace();
        self.eat()
            .map(|ch| {
                match ch {
                    '1' => Token::DecimalInt(String::from_str("1")),
                    '+' => Token::Plus,
                    _ => Token::Error(ch)
                }
            })
    }
}
<commit_msg>guess: &mut fn() -> Token? nope. can't understand the message src/lexer.rs:125:40: 127:10 error: mismatched types:  expected `&mut fn() -> token::Token`,     found `[closure src/lexer.rs:125:40: 127:10]` (expected &-ptr,     found closure) [E0308] src/lexer.rs:125         self.lookahead.ensure_nonempty(|| { src/lexer.rs:126             self.read_next_token() src/lexer.rs:127         });<commit_after>use std::collections::LinkedList;

use token::Token;

use std::cell::Cell;
use std::rc::Rc;
use regex::Regex;
use context::Context;
use token::Posn;

pub trait ESCharExt {
    fn is_es_newline(self) -> bool;
    fn is_es_whitespace(self) -> bool;
}

impl ESCharExt for char {
    fn is_es_newline(self) -> bool {
        match self {
            '\u{000a}' | '\u{000d}' | '\u{2028}' | '\u{2029}' => true,
            _ => false
        }
    }

    fn is_es_whitespace(self) -> bool {
        match self {
              '\u{0009}' | '\u{000b}' | '\u{000c}' | '\u{0020}' | '\u{00a0}'
            | '\u{1680}' | '\u{2000}' | '\u{2001}' | '\u{2002}' | '\u{2003}' | '\u{2004}'
            | '\u{2005}' | '\u{2006}' | '\u{2009}' | '\u{200a}' | '\u{202f}' | '\u{205f}'
            | '\u{3000}' | '\u{feff}' => true,
            _ => false
        }
    }
}

struct LineOrientedReader<I> {
    chars: I,
    curr_char: Option<char>,
    next_char: Option<char>,
    curr_posn: Posn
}

impl<I> LineOrientedReader<I> where I: Iterator<Item=char> {
    pub fn new(mut chars: I) -> LineOrientedReader<I> {
        let curr_char = chars.next();
        let next_char = if curr_char.is_some() { chars.next() } else { None };
        LineOrientedReader {
            chars: chars,
            curr_char: curr_char,
            next_char: next_char,
            curr_posn: Posn {
                offset: 0,
                line: 0,
                column: 0
            }
        }
    }

    pub fn curr_char(&mut self) -> Option<char> { self.curr_char }
    pub fn curr_posn(&mut self) -> Posn { self.curr_posn }

    pub fn bump(&mut self) {
        let curr_char = self.next_char;
        let next_char = if curr_char.is_some() { self.chars.next() } else { None };

        self.curr_char = curr_char;
        self.next_char = next_char;

        if (curr_char == Some('\r') && next_char != Some('\n')) ||
           curr_char == Some('\n') ||
           curr_char == Some('\u{2028}') ||
           curr_char == Some('\u{2029}') {
            self.curr_posn.line += 1;
            self.curr_posn.column = 0;
        } else {
            self.curr_posn.column += 1;
        }

        self.curr_posn.offset += 1;
    }
}

struct TokenBuffer {
    tokens: LinkedList<Token>
}

impl TokenBuffer {
    fn new() -> TokenBuffer {
        TokenBuffer {
            tokens: LinkedList::new()
        }
    }

    fn ensure_nonempty(&mut self, get: &mut fn() -> Token) {
        if self.tokens.len() == 0 {
            self.tokens.push_back(get());
        }
    }

    fn read_token(&mut self) -> Token {
        assert!(self.tokens.len() > 0);
        self.tokens.pop_front().unwrap()
    }
}

pub struct Lexer<I> {
    reader: LineOrientedReader<I>,
    cx: Rc<Cell<Context>>,
    lookahead: TokenBuffer
}

impl<I> Lexer<I> where I: Iterator<Item=char> {
    // constructor

    pub fn new(chars: I, cx: Rc<Cell<Context>>) -> Lexer<I> {
        Lexer {
            reader: LineOrientedReader::new(chars),
            cx: cx,
            lookahead: TokenBuffer::new()
        }
    }

    // public methods

    pub fn read_token(&mut self) -> Token {
        self.lookahead.ensure_nonempty(|| {
            self.read_next_token()
        });
        unimplemented!()
    }

    // private methods

    fn read_next_token(&mut self) -> Token {
        unimplemented!()
    }

    fn is_whitespace(&mut self) -> bool {
        match self.reader.curr_char() {
            Some(ch) => ch.is_es_whitespace(),
            None => false
        }
    }

    fn eat(&mut self) -> Option<char> {
        let ch = self.reader.curr_char();
        self.reader.bump();
        ch
    }

    fn skip_whitespace(&mut self) {
        while self.is_whitespace() {
            self.reader.bump();
        }
    }
}

impl<I> Iterator for Lexer<I> where I: Iterator<Item=char> {
    type Item = Token;

    fn next(&mut self) -> Option<Token> {
        self.skip_whitespace();
        self.eat()
            .map(|ch| {
                match ch {
                    '1' => Token::DecimalInt(String::from_str("1")),
                    '+' => Token::Plus,
                    _ => Token::Error(ch)
                }
            })
    }
}
<|endoftext|>


<commit_before>use std::io::{BufRead, BufReader};
use std::io;
use std::io::prelude::*;
use std::iter;
use std::str;
use std::collections::VecDeque;

pub enum TokenKind {
    Identifier,
    IntNumber,
    FloatNumber,
    String,
    Char,
    Symbol,
    Newline,
    End,
}

pub struct Token {
    pub kind: TokenKind,
    pub val: String,
    pub line: i32,
}

impl Token {
    pub fn new(kind: TokenKind, val: &str, line: i32) -> Token {
        Token {
            kind: kind,
            val: val.to_string(),
            line: line,
        }
    }
}

pub struct Lexer<'a> {
    cur_line: i32,
    filename: String,
    peek: iter::Peekable<str::Chars<'a>>,
    buf: VecDeque<char>,
}

impl<'a> Lexer<'a> {
    pub fn new(filename: String, input: &'a str) -> Lexer<'a> {
        Lexer {
            cur_line: 0,
            filename: filename.to_string(),
            peek: input.chars().peekable(),
            buf: VecDeque::new(),
        }
    }
    pub fn get_filename(self) -> String {
        self.filename
    }

    fn peek_get(&mut self) -> Option<&char> {
        if self.buf.len() > 0 {
            self.buf.front()
        } else {
            self.peek.peek()
        }
    }
    fn peek_next(&mut self) -> char {
        if self.buf.len() > 0 {
            self.buf.pop_front().unwrap()
        } else {
            self.peek.next().unwrap()
        }
    }
    fn peek_unget(&mut self, ch: char) {
        self.buf.push_back(ch);
    }
    fn peek_next_char_is(&mut self, ch: char) -> bool {
        let nextc = self.peek_next();
        nextc == ch
    }

    pub fn read_identifier(&mut self) -> Token {
        let mut ident = String::new();
        loop {
            match self.peek_get() {
                Some(&c) => {
                    match c {
                        'a'...'z' | 'A'...'Z' | '_' | '0'...'9' => ident.push(c),
                        _ => break,
                    }
                }
                _ => break,
            };
            self.peek_next();
        }
        Token::new(TokenKind::Identifier, ident.as_str(), self.cur_line)
    }
    pub fn read_newline(&mut self) -> Token {
        self.peek_next();
        Token::new(TokenKind::Newline, "", self.cur_line)
    }
    pub fn read_symbol(&mut self) -> Token {
        let c = self.peek_next();
        let mut sym = String::new();
        sym.push(c);
        Token::new(TokenKind::Symbol, sym.as_str(), self.cur_line)
    }

    pub fn read_token(&mut self) -> Option<Token> {
        match self.peek_get() {
            Some(&c) => {
                match c {
                    'a'...'z' | 'A'...'Z' | '_' => Some(self.read_identifier()),
                    ' ' | '\t' => {
                        self.peek_next();
                        self.read_token()
                    }
                    '\n' => Some(self.read_newline()),
                    _ => Some(self.read_symbol()),
                }
            }
            None => None as Option<Token>,
        }
    }
}
<commit_msg>lexer update<commit_after>use std::io::{BufRead, BufReader};
use std::io;
use std::io::prelude::*;
use std::iter;
use std::str;
use std::collections::VecDeque;

pub enum TokenKind {
    Identifier,
    IntNumber,
    FloatNumber,
    String,
    Char,
    Symbol,
    Newline,
    End,
}

pub struct Token {
    pub kind: TokenKind,
    pub val: String,
    pub line: i32,
}

impl Token {
    pub fn new(kind: TokenKind, val: &str, line: i32) -> Token {
        Token {
            kind: kind,
            val: val.to_string(),
            line: line,
        }
    }
}

pub struct Lexer<'a> {
    cur_line: i32,
    filename: String,
    peek: iter::Peekable<str::Chars<'a>>,
    buf: VecDeque<char>,
}

impl<'a> Lexer<'a> {
    pub fn new(filename: String, input: &'a str) -> Lexer<'a> {
        Lexer {
            cur_line: 0,
            filename: filename.to_string(),
            peek: input.chars().peekable(),
            buf: VecDeque::new(),
        }
    }
    pub fn get_filename(self) -> String {
        self.filename
    }

    fn peek_get(&mut self) -> Option<&char> {
        if self.buf.len() > 0 {
            self.buf.front()
        } else {
            self.peek.peek()
        }
    }
    fn peek_next(&mut self) -> char {
        if self.buf.len() > 0 {
            self.buf.pop_front().unwrap()
        } else {
            self.peek.next().unwrap()
        }
    }
    fn peek_unget(&mut self, ch: char) {
        self.buf.push_back(ch);
    }
    fn peek_next_char_is(&mut self, ch: char) -> bool {
        let nextc = self.peek_next();
        self.peek_unget(nextc);
        nextc == ch
    }
    fn peek_char_is(&mut self, ch: char) -> bool {
        let peekc = self.peek_get().unwrap();
        *peekc == ch
    }

    pub fn read_identifier(&mut self) -> Token {
        let mut ident = String::new();
        loop {
            match self.peek_get() {
                Some(&c) => {
                    match c {
                        'a'...'z' | 'A'...'Z' | '_' | '0'...'9' => ident.push(c),
                        _ => break,
                    }
                }
                _ => break,
            };
            self.peek_next();
        }
        Token::new(TokenKind::Identifier, ident.as_str(), self.cur_line)
    }
    fn read_number_literal(&mut self) -> Token {
        let mut num = String::new();
        let mut is_float = false;
        loop {
            match self.peek_get() {
                Some(&c) => {
                    match c {
                        '.' | '0'...'9' => {
                            num.push(c);
                            if (c == '.') {
                                is_float = true;
                            }
                        }
                        _ => break,
                    }
                }
                _ => break,
            };
            self.peek_next();
        }
        if is_float {
            Token::new(TokenKind::FloatNumber, num.as_str(), self.cur_line)
        } else {
            Token::new(TokenKind::IntNumber, num.as_str(), self.cur_line)
        }
    }
    pub fn read_newline(&mut self) -> Token {
        self.peek_next();
        Token::new(TokenKind::Newline, "", self.cur_line)
    }
    pub fn read_symbol(&mut self) -> Token {
        let c = self.peek_next();
        let mut sym = String::new();
        sym.push(c);
        match c {
            '+' | '-' | '*' | '/' | '%' | '=' | '^' | '!' => {
                if (self.peek_char_is('=')) {
                    sym.push(self.peek_next());
                }
            }
            '<' | '>' | '&' | '|' => {
                if (self.peek_char_is(c)) {
                    sym.push(self.peek_next());
                }
                if (self.peek_char_is('=')) {
                    sym.push(self.peek_next());
                }
            }
            '.' => {
                if (self.peek_char_is('.') && self.peek_next_char_is('.')) {
                    sym.push(self.peek_next());
                    sym.push(self.peek_next());
                }
            }
            _ => {}
        };
        Token::new(TokenKind::Symbol, sym.as_str(), self.cur_line)
    }
    fn read_string_literal(&mut self) -> Token {
        self.peek_next();
        let mut s = String::new();
        while !self.peek_char_is('\"') {
            s.push(self.peek_next());
        }
        self.peek_next();
        Token::new(TokenKind::String, s.as_str(), self.cur_line)
    }
    fn read_char_literal(&mut self) -> Token {
        self.peek_next();
        let mut s = String::new();
        while !self.peek_char_is('\'') {
            s.push(self.peek_next());
        }
        self.peek_next();
        Token::new(TokenKind::Char, s.as_str(), self.cur_line)
    }

    pub fn do_read_token(&mut self) -> Option<Token> {
        match self.peek_get() {
            Some(&c) => {
                match c {
                    'a'...'z' | 'A'...'Z' | '_' => Some(self.read_identifier()),
                    ' ' | '\t' => {
                        self.peek_next();
                        self.read_token()
                    }
                    '0'...'9' => Some(self.read_number_literal()),
                    '\"' => Some(self.read_string_literal()),
                    '\'' => Some(self.read_char_literal()),
                    '\n' => Some(self.read_newline()),
                    _ => Some(self.read_symbol()),
                }
            }
            None => None as Option<Token>,
        }
    }
    pub fn read_token(&mut self) -> Option<Token> {
        let t = self.do_read_token();
        match t {
            Some(tok) => {
                match tok.kind {
                    TokenKind::Newline => self.read_token(),
                    _ => Some(tok),
                }
            }
            _ => t,
        }
    }
}
<|endoftext|>


<commit_before>use serial::Serial;
use timer::Timer;
use keypad::Keypad;
use gpu::GPU;
use sound::Sound;

static WRAM_SIZE: uint = 0x8000;
static ZRAM_SIZE: uint = 0x7F;

#[deriving(Eq)]
enum DMAType {
	NoDMA,
	GDMA,
	HDMA,
}

pub struct MMU {
	priv wram: ~[u8, ..WRAM_SIZE],
	priv zram: ~[u8, ..ZRAM_SIZE],
	priv hdma: [u8, ..4],
	inte: u8,
	intf: u8,
	serial: Serial,
	timer: Timer,
	keypad: Keypad,
	gpu: GPU,
	sound: Sound,
	priv hdma_status: DMAType,
	priv hdma_src: u16,
	priv hdma_dst: u16,
	priv hdma_len: u8,
	priv wrambank: u8,
	priv mbc: ~::mbc::MBC,
	priv gbmode: ::gbmode::GbMode,
}

impl MMU {
	pub fn new(romname: &str) -> MMU {
		let mut res = MMU {
			wram: ~([0, ..WRAM_SIZE]),
			zram: ~([0, ..ZRAM_SIZE]),
			hdma: [0, ..4],
			wrambank: 1,
			inte: 0,
			intf: 0,
			serial: Serial::new(),
			timer: Timer::new(),
			keypad: Keypad::new(),
			gpu: GPU::new(),
			sound: Sound::new(),
			mbc: ::mbc::get_mbc(&Path::new(romname)),
			gbmode: ::gbmode::Classic,
			hdma_src: 0,
			hdma_dst: 0,
			hdma_status: NoDMA,
			hdma_len: 0xFF,
		};
		if res.rb(0x0143) == 0xC0 {
			fail!("This game does not work in Classic mode");
		}
		res.set_initial();
		return res
	}

	pub fn new_cgb(romname: &str) -> MMU {
		let mut res = MMU {
			wram: ~([0,.. WRAM_SIZE]),
			zram: ~([0,.. ZRAM_SIZE]),
			wrambank: 1,
			hdma: [0,.. 4],
			inte: 0,
			intf: 0,
			serial: Serial::new(),
			timer: Timer::new(),
			keypad: Keypad::new(),
			gpu: GPU::new_cgb(),
			sound: Sound::new(),
			mbc: ::mbc::get_mbc(&Path::new(romname)),
			gbmode: ::gbmode::Color,
			hdma_src: 0,
			hdma_dst: 0,
			hdma_status: NoDMA,
			hdma_len: 0xFF,
		};
		res.determine_mode();
		res.set_initial();
		return res;
	}

	fn set_initial(&mut self) {
		self.wb(0xFF05, 0);
		self.wb(0xFF06, 0);
		self.wb(0xFF07, 0);
		self.wb(0xFF40, 0x91);
		self.wb(0xFF42, 0);
		self.wb(0xFF43, 0);
		self.wb(0xFF45, 0);
		self.wb(0xFF47, 0xFC);
		self.wb(0xFF48, 0xFF);
		self.wb(0xFF49, 0xFF);
		self.wb(0xFF4A, 0);
		self.wb(0xFF4B, 0);
	}

	fn determine_mode(&mut self) {
		let mode = match self.rb(0x0143) & 0x80 {
			0x80 => ::gbmode::Color,
			_ => ::gbmode::ColorAsClassic,
		};
		self.gbmode = mode;
		self.gpu.gbmode = mode;
	}

	pub fn get_mode(&self) -> ::gbmode::GbMode {
		self.gbmode
	}

	pub fn cycle(&mut self, cputicks: uint) -> uint {
		let ticks = cputicks + self.perform_vramdma();

		self.timer.cycle(ticks);
		self.intf |= self.timer.interrupt;
		self.timer.interrupt = 0;

		self.intf |= self.keypad.interrupt;
		self.keypad.interrupt = 0;

		self.gpu.cycle(ticks);
		self.intf |= self.gpu.interrupt;
		self.gpu.interrupt = 0;

		return ticks;
	}

	pub fn rb(&self, address: u16) -> u8 {
		match address {
			0x0000 .. 0x7FFF => self.mbc.readrom(address),
			0x8000 .. 0x9FFF => self.gpu.rb(address),
			0xA000 .. 0xBFFF => self.mbc.readram(address),
			0xC000 .. 0xCFFF | 0xE000 .. 0xEFFF => self.wram[address & 0x0FFF],
			0xD000 .. 0xDFFF | 0xF000 .. 0xFDFF => self.wram[(self.wrambank as u16 * 0x1000) | address & 0x0FFF],
			0xFE00 .. 0xFE9F => self.gpu.rb(address),
			0xFF00 => self.keypad.rb(),
			0xFF01 .. 0xFF02 => self.serial.rb(address),
			0xFF04 .. 0xFF07 => self.timer.rb(address),
			0xFF0F => self.intf,
			0xFF10 .. 0xFF26 => self.sound.rb(address),
			0xFF4D => 0,
			0xFF40 .. 0xFF4F => self.gpu.rb(address),
			0xFF51 .. 0xFF55 => self.hdma_read(address),
			0xFF68 .. 0xFF6B => self.gpu.rb(address),
			0xFF70 => self.wrambank,
			0xFF80 .. 0xFFFE => self.zram[address & 0x007F],
			0xFFFF => self.inte,
			_ => { warn!("rb not implemented for {:X}", address); 0 },
		}
	}

	pub fn rw(&self, address: u16) -> u16 {
		(self.rb(address) as u16) | (self.rb(address + 1) as u16 << 8)
	}

	pub fn wb(&mut self, address: u16, value: u8) {
		match address {
			0x0000 .. 0x7FFF => self.mbc.writerom(address, value),
			0x8000 .. 0x9FFF => self.gpu.wb(address, value),
			0xA000 .. 0xBFFF => self.mbc.writeram(address, value),
			0xC000 .. 0xCFFF | 0xE000 .. 0xEFFF => self.wram[address & 0x0FFF] = value,
			0xD000 .. 0xDFFF | 0xF000 .. 0xFDFF => self.wram[(self.wrambank as u16 * 0x1000) | address & 0x0FFF] = value,
			0xFE00 .. 0xFE9F => self.gpu.wb(address, value),
			0xFF00 => self.keypad.wb(value),
			0xFF01 .. 0xFF02 => self.serial.wb(address, value),
			0xFF04 .. 0xFF07 => self.timer.wb(address, value),
			0xFF10 .. 0xFF26 => self.sound.wb(address, value),
			0xFF46 => self.oamdma(value),
			0xFF4D => { if value & 0x1 == 0x1 { warn!("Speed switch requested but not supported"); } }, // CGB speed switch
			0xFF40 .. 0xFF4F => self.gpu.wb(address, value),
			0xFF51 .. 0xFF55 => self.hdma_write(address, value),
			0xFF68 .. 0xFF6B => self.gpu.wb(address, value),
			0xFF0F => self.intf = value,
			0xFF70 => { self.wrambank = match value & 0x7 { 0 => 1, n => n }; },
			0xFF80 .. 0xFFFE => self.zram[address & 0x007F] = value,
			0xFFFF => self.inte = value,
			_ => warn!("wb not implemented for {:X}", address),
		};
	}

	pub fn ww(&mut self, address: u16, value: u16) {
		self.wb(address, (value & 0xFF) as u8);
		self.wb(address + 1, (value >> 8) as u8);
	}

	fn oamdma(&mut self, value: u8) {
		let base = (value as u16) << 8;
		for i in range(0u16, 0xA0) {
			let b = self.rb(base + i);
			self.wb(0xFE00 + i, b);
		}
	}

	fn hdma_read(&self, a: u16) -> u8 {
		match a {
			0xFF51 .. 0xFF54 => { self.hdma[a - 0xFF51] },
			0xFF55 => self.hdma_len | if self.hdma_status == NoDMA { 0x80 } else { 0 },
			_ => fail!(),
		}
	}

	fn hdma_write(&mut self, a: u16, v: u8) {
		match a {
			0xFF51 => self.hdma[0] = v,
			0xFF52 => self.hdma[1] = v & 0xF0,
			0xFF53 => self.hdma[2] = v & 0x1F,
			0xFF54 => self.hdma[3] = v & 0xF0,
			0xFF55 => {
				if self.hdma_status == HDMA {
					if v & 0x80 == 0 { self.hdma_status = NoDMA; };
					return;
				}
				let src = (self.hdma[0] as u16 << 8) | (self.hdma[1] as u16);
				let dst = (self.hdma[2] as u16 << 8) | (self.hdma[3] as u16) | 0x8000;
				if !(src <= 0x7FF0 || (src >= 0xA000 && src <= 0xDFF0)) { fail!("HDMA transfer with illegal start address {:04X}", src); }

				self.hdma_src = src;
				self.hdma_dst = dst;
				self.hdma_len = v & 0x7F;

				self.hdma_status =
					if v & 0x80 == 0x80 { HDMA }
					else { GDMA };
			},
			_ => fail!(),
		};
	}

	fn perform_vramdma(&mut self) -> uint {
		match self.hdma_status
		{
			NoDMA => 0,
			GDMA => self.perform_gdma(),
			HDMA => self.perform_hdma(),
		}
	}

	fn perform_hdma(&mut self) -> uint {
		if self.gpu.may_hdma() == false
			|| self.hdma_len == 0xFF
		{
			return 0;
		}

		self.perform_vramdma_row();

		return 0x10;
	}

	fn perform_gdma(&mut self) -> uint {
		let len = self.hdma_len as uint + 1;
		for _i in range(0, len)
		{
			self.perform_vramdma_row();
		}

		self.hdma_status = NoDMA;
		return len * 0x10;
	}

	fn perform_vramdma_row(&mut self) {
		for j in range(0u16, 0x10)
		{
			let b: u8 = self.rb(self.hdma_src + j);
			self.gpu.wb(self.hdma_dst + j, b);
		}
		self.hdma_src += 0x10;
		self.hdma_dst += 0x10;
		self.hdma_len -= 1;
	}
}
<commit_msg>Fixed coding style<commit_after>use serial::Serial;
use timer::Timer;
use keypad::Keypad;
use gpu::GPU;
use sound::Sound;

static WRAM_SIZE: uint = 0x8000;
static ZRAM_SIZE: uint = 0x7F;

#[deriving(Eq)]
enum DMAType {
	NoDMA,
	GDMA,
	HDMA,
}

pub struct MMU {
	priv wram: ~[u8, ..WRAM_SIZE],
	priv zram: ~[u8, ..ZRAM_SIZE],
	priv hdma: [u8, ..4],
	inte: u8,
	intf: u8,
	serial: Serial,
	timer: Timer,
	keypad: Keypad,
	gpu: GPU,
	sound: Sound,
	priv hdma_status: DMAType,
	priv hdma_src: u16,
	priv hdma_dst: u16,
	priv hdma_len: u8,
	priv wrambank: u8,
	priv mbc: ~::mbc::MBC,
	priv gbmode: ::gbmode::GbMode,
}

impl MMU {
	pub fn new(romname: &str) -> MMU {
		let mut res = MMU {
			wram: ~([0, ..WRAM_SIZE]),
			zram: ~([0, ..ZRAM_SIZE]),
			hdma: [0, ..4],
			wrambank: 1,
			inte: 0,
			intf: 0,
			serial: Serial::new(),
			timer: Timer::new(),
			keypad: Keypad::new(),
			gpu: GPU::new(),
			sound: Sound::new(),
			mbc: ::mbc::get_mbc(&Path::new(romname)),
			gbmode: ::gbmode::Classic,
			hdma_src: 0,
			hdma_dst: 0,
			hdma_status: NoDMA,
			hdma_len: 0xFF,
		};
		if res.rb(0x0143) == 0xC0 {
			fail!("This game does not work in Classic mode");
		}
		res.set_initial();
		return res
	}

	pub fn new_cgb(romname: &str) -> MMU {
		let mut res = MMU {
			wram: ~([0,.. WRAM_SIZE]),
			zram: ~([0,.. ZRAM_SIZE]),
			wrambank: 1,
			hdma: [0,.. 4],
			inte: 0,
			intf: 0,
			serial: Serial::new(),
			timer: Timer::new(),
			keypad: Keypad::new(),
			gpu: GPU::new_cgb(),
			sound: Sound::new(),
			mbc: ::mbc::get_mbc(&Path::new(romname)),
			gbmode: ::gbmode::Color,
			hdma_src: 0,
			hdma_dst: 0,
			hdma_status: NoDMA,
			hdma_len: 0xFF,
		};
		res.determine_mode();
		res.set_initial();
		return res;
	}

	fn set_initial(&mut self) {
		self.wb(0xFF05, 0);
		self.wb(0xFF06, 0);
		self.wb(0xFF07, 0);
		self.wb(0xFF40, 0x91);
		self.wb(0xFF42, 0);
		self.wb(0xFF43, 0);
		self.wb(0xFF45, 0);
		self.wb(0xFF47, 0xFC);
		self.wb(0xFF48, 0xFF);
		self.wb(0xFF49, 0xFF);
		self.wb(0xFF4A, 0);
		self.wb(0xFF4B, 0);
	}

	fn determine_mode(&mut self) {
		let mode = match self.rb(0x0143) & 0x80 {
			0x80 => ::gbmode::Color,
			_ => ::gbmode::ColorAsClassic,
		};
		self.gbmode = mode;
		self.gpu.gbmode = mode;
	}

	pub fn get_mode(&self) -> ::gbmode::GbMode {
		self.gbmode
	}

	pub fn cycle(&mut self, cputicks: uint) -> uint {
		let ticks = cputicks + self.perform_vramdma();

		self.timer.cycle(ticks);
		self.intf |= self.timer.interrupt;
		self.timer.interrupt = 0;

		self.intf |= self.keypad.interrupt;
		self.keypad.interrupt = 0;

		self.gpu.cycle(ticks);
		self.intf |= self.gpu.interrupt;
		self.gpu.interrupt = 0;

		return ticks;
	}

	pub fn rb(&self, address: u16) -> u8 {
		match address {
			0x0000 .. 0x7FFF => self.mbc.readrom(address),
			0x8000 .. 0x9FFF => self.gpu.rb(address),
			0xA000 .. 0xBFFF => self.mbc.readram(address),
			0xC000 .. 0xCFFF | 0xE000 .. 0xEFFF => self.wram[address & 0x0FFF],
			0xD000 .. 0xDFFF | 0xF000 .. 0xFDFF => self.wram[(self.wrambank as u16 * 0x1000) | address & 0x0FFF],
			0xFE00 .. 0xFE9F => self.gpu.rb(address),
			0xFF00 => self.keypad.rb(),
			0xFF01 .. 0xFF02 => self.serial.rb(address),
			0xFF04 .. 0xFF07 => self.timer.rb(address),
			0xFF0F => self.intf,
			0xFF10 .. 0xFF26 => self.sound.rb(address),
			0xFF4D => 0,
			0xFF40 .. 0xFF4F => self.gpu.rb(address),
			0xFF51 .. 0xFF55 => self.hdma_read(address),
			0xFF68 .. 0xFF6B => self.gpu.rb(address),
			0xFF70 => self.wrambank,
			0xFF80 .. 0xFFFE => self.zram[address & 0x007F],
			0xFFFF => self.inte,
			_ => { warn!("rb not implemented for {:X}", address); 0 },
		}
	}

	pub fn rw(&self, address: u16) -> u16 {
		(self.rb(address) as u16) | (self.rb(address + 1) as u16 << 8)
	}

	pub fn wb(&mut self, address: u16, value: u8) {
		match address {
			0x0000 .. 0x7FFF => self.mbc.writerom(address, value),
			0x8000 .. 0x9FFF => self.gpu.wb(address, value),
			0xA000 .. 0xBFFF => self.mbc.writeram(address, value),
			0xC000 .. 0xCFFF | 0xE000 .. 0xEFFF => self.wram[address & 0x0FFF] = value,
			0xD000 .. 0xDFFF | 0xF000 .. 0xFDFF => self.wram[(self.wrambank as u16 * 0x1000) | address & 0x0FFF] = value,
			0xFE00 .. 0xFE9F => self.gpu.wb(address, value),
			0xFF00 => self.keypad.wb(value),
			0xFF01 .. 0xFF02 => self.serial.wb(address, value),
			0xFF04 .. 0xFF07 => self.timer.wb(address, value),
			0xFF10 .. 0xFF26 => self.sound.wb(address, value),
			0xFF46 => self.oamdma(value),
			0xFF4D => { if value & 0x1 == 0x1 { warn!("Speed switch requested but not supported"); } }, // CGB speed switch
			0xFF40 .. 0xFF4F => self.gpu.wb(address, value),
			0xFF51 .. 0xFF55 => self.hdma_write(address, value),
			0xFF68 .. 0xFF6B => self.gpu.wb(address, value),
			0xFF0F => self.intf = value,
			0xFF70 => { self.wrambank = match value & 0x7 { 0 => 1, n => n }; },
			0xFF80 .. 0xFFFE => self.zram[address & 0x007F] = value,
			0xFFFF => self.inte = value,
			_ => warn!("wb not implemented for {:X}", address),
		};
	}

	pub fn ww(&mut self, address: u16, value: u16) {
		self.wb(address, (value & 0xFF) as u8);
		self.wb(address + 1, (value >> 8) as u8);
	}

	fn oamdma(&mut self, value: u8) {
		let base = (value as u16) << 8;
		for i in range(0u16, 0xA0) {
			let b = self.rb(base + i);
			self.wb(0xFE00 + i, b);
		}
	}

	fn hdma_read(&self, a: u16) -> u8 {
		match a {
			0xFF51 .. 0xFF54 => { self.hdma[a - 0xFF51] },
			0xFF55 => self.hdma_len | if self.hdma_status == NoDMA { 0x80 } else { 0 },
			_ => fail!(),
		}
	}

	fn hdma_write(&mut self, a: u16, v: u8) {
		match a {
			0xFF51 => self.hdma[0] = v,
			0xFF52 => self.hdma[1] = v & 0xF0,
			0xFF53 => self.hdma[2] = v & 0x1F,
			0xFF54 => self.hdma[3] = v & 0xF0,
			0xFF55 => {
				if self.hdma_status == HDMA {
					if v & 0x80 == 0 { self.hdma_status = NoDMA; };
					return;
				}
				let src = (self.hdma[0] as u16 << 8) | (self.hdma[1] as u16);
				let dst = (self.hdma[2] as u16 << 8) | (self.hdma[3] as u16) | 0x8000;
				if !(src <= 0x7FF0 || (src >= 0xA000 && src <= 0xDFF0)) { fail!("HDMA transfer with illegal start address {:04X}", src); }

				self.hdma_src = src;
				self.hdma_dst = dst;
				self.hdma_len = v & 0x7F;

				self.hdma_status =
					if v & 0x80 == 0x80 { HDMA }
					else { GDMA };
			},
			_ => fail!(),
		};
	}

	fn perform_vramdma(&mut self) -> uint {
		match self.hdma_status {
			NoDMA => 0,
			GDMA => self.perform_gdma(),
			HDMA => self.perform_hdma(),
		}
	}

	fn perform_hdma(&mut self) -> uint {
		if self.gpu.may_hdma() == false || self.hdma_len == 0xFF {
			return 0;
		}

		self.perform_vramdma_row();

		return 0x10;
	}

	fn perform_gdma(&mut self) -> uint {
		let len = self.hdma_len as uint + 1;
		for _i in range(0, len) {
			self.perform_vramdma_row();
		}

		self.hdma_status = NoDMA;
		return len * 0x10;
	}

	fn perform_vramdma_row(&mut self) {
		for j in range(0u16, 0x10) {
			let b: u8 = self.rb(self.hdma_src + j);
			self.gpu.wb(self.hdma_dst + j, b);
		}
		self.hdma_src += 0x10;
		self.hdma_dst += 0x10;
		self.hdma_len -= 1;
	}
}
<|endoftext|>


<commit_before>use std::io;
use std::net::SocketAddr;
use std::str::FromStr;
use std::time::Duration;

use std::io::{Read, Write};  // Used for TcpStream.read,  TcpStream.write
use mio::{Poll, Token, Events, Event, Ready, PollOpt};
use mio::tcp::{TcpListener, TcpStream};

use slab;
use interface::{ServerFactory, Protocol, Reason};
use transport::Transport;

const CONNS_MAX: usize = 65_536;
const BUF_SIZE: usize = 4096;

type Slab<T> = slab::Slab<T, Token>;

#[derive(Clone)]
enum ConnectionType {
    Server,
    Client,
}

struct ServerConnection {
    server: Box<ServerFactory>,
    socket: TcpListener,
}

struct ClientConnection {
    protocol: Box<Protocol>,
    socket: TcpStream,
    interest: Ready,
    transport: Transport,
}

impl ClientConnection {
    fn new(protocol: Box<Protocol>, socket: TcpStream) -> ClientConnection {
        ClientConnection {
            protocol: protocol,
            socket: socket,
            interest: Ready::hup() | Ready::readable(),
            transport: Transport::new(),
        }
    }

    fn peer_addr(&self) -> io::Result<SocketAddr> {
        self.socket.peer_addr()
    }

    fn is_finished(&self) -> bool {
        self.interest == Ready::none()
    }

    fn handle_hup(&mut self) {
        self.interest = Ready::none();
    }

    fn handle_read(&mut self) -> io::Result<()> {
        let mut read_bytes: Vec<u8> = Vec::new();
        loop {
            let (buf, read_len) = {
                let mut buf = [0; BUF_SIZE];
                let read_len = try!(self.socket.read(&mut buf[..]));
                // let s_data = str::from_utf8(&buf).unwrap();
                // info!("<<< {}", s_data);
                (buf, read_len)
            };
            if read_len > 0 {
                read_bytes.extend(buf[0..read_len].iter());
                if read_len < BUF_SIZE {
                    info!("Nothing more to read");
                    break;
                } else {
                    info!("More data to read");
                }
            }
        }
        self.protocol.data_received(&read_bytes[..], &mut self.transport);

        Ok(())
    }

    fn handle_write(&mut self) {

        {
            // a block where transport muting

            debug!("handle write");
            let buf = &mut self.transport.buf();
            let to_write_len = buf.len();
            if to_write_len > 0 {
                // let s_data = str::from_utf8(&buf[..]).unwrap();
                // info!(">>> {}", s_data);

                let result = self.socket.write(&buf[..]);
                match result {
                    Ok(written_len) => {
                        debug!("Write {} bytes", written_len);
                        if to_write_len != written_len {
                            error!("{} bytes to write but {} written, hanging up",
                                   to_write_len,
                                   written_len);
                            self.interest = Ready::hup();
                        }
                    }
                    Err(err) => {
                        error!("Error {} while writing to the socket, disconnecting", err);
                        self.interest = Ready::hup();
                    }
                };
            }
        };

        self.transport.clear();

        if self.transport.hup() {
            info!("Peer is disconnecting, will unregister connection");
            self.interest = Ready::none();
        }
    }
}

struct Connection {
    connection_type: ConnectionType,
    server: Option<ServerConnection>,
    client: Option<ClientConnection>,
    peer_addr: SocketAddr,
}

#[allow(dead_code)]
impl Connection {
    fn new_server(server: Box<ServerFactory>,
                  peer_addr: SocketAddr,
                  socket: TcpListener)
                  -> Connection {
        Connection {
            connection_type: ConnectionType::Server,
            server: Some(ServerConnection {
                server: server,
                socket: socket,
            }),
            client: None,
            peer_addr: peer_addr,
        }
    }

    fn new_client(protocol: Box<Protocol>, peer_addr: SocketAddr, socket: TcpStream) -> Connection {
        Connection {
            connection_type: ConnectionType::Client,
            client: Some(ClientConnection::new(protocol, socket)),
            server: None,
            peer_addr: peer_addr,
        }
    }

    fn peer_addr(&self) -> SocketAddr {
        self.peer_addr
    }

    fn server_ref(&self) -> &ServerConnection {
        self.server.as_ref().unwrap()
    }

    fn client_ref(&self) -> &ClientConnection {
        self.client.as_ref().unwrap()
    }

    fn client_mut(&mut self) -> &mut ClientConnection {
        self.client.as_mut().unwrap()
    }

    fn alive(&self) -> bool {
        return match self.connection_type {
            ConnectionType::Server => true,
            ConnectionType::Client => {
                match self.client_ref().peer_addr() {
                    Ok(_) => true,
                    Err(_) => false,
                }
            }
        };
    }
}

/// The I/O Loop
pub struct Rio {
    poll: Poll,
    connections: Slab<Connection>,
    running: bool
}

impl Rio {
    /// Instanciate the IOLoop, should be called once.
    pub fn new() -> Rio {
        let poll: Poll = Poll::new().unwrap();
        let connections = Slab::with_capacity(CONNS_MAX);
        Rio {
            running: false,
            poll: poll,
            connections: connections,
        }
    }

    /// Will listen on the given address when the loop will start.
    /// The ServerFactory.build_protocol method will be called on every
    /// new client connection.
    pub fn listen(&mut self, addr: &str, server: Box<ServerFactory>) -> Result<Token, io::Error> {
        info!("Rio is listenning on {}", addr);
        let sock_addr: SocketAddr = FromStr::from_str(addr).unwrap();
        debug!("Bind the server socket {}", addr);
        let sock = TcpListener::bind(&sock_addr).unwrap();
        let result = self.connections.insert(Connection::new_server(server, sock_addr, sock));
        match result {
            Ok(token) => {
                let _ = self.poll.register(&self.connections[token].server_ref().socket,
                                           token,
                                           Ready::readable() | Ready::writable(),
                                           PollOpt::edge());
                return Ok(token);
            }
            Err(_) => {
                error!("Cannot register server {:?}", addr);
                return Err(io::Error::new(io::ErrorKind::Other, format!("Cannot register server {:?}", addr)));
            }
        }
    }

    /// Will listen on the given address when the loop will start.
    /// The ServerFactory.build_protocol method will be called on every
    /// new client connection.
    pub fn connect(&mut self, addr: &str, client: Box<Protocol>) -> Result<Token, io::Error> {
        info!("Connecting to socket {}", addr);
        let sock_addr: SocketAddr = FromStr::from_str(addr).unwrap();

        let sock = TcpStream::connect(&sock_addr).unwrap();
        let result = self.connections.insert(Connection::new_client(client, sock_addr, sock));
        match result {
            Ok(token) => {
                let client = self.connections[token].client_mut();
                client.protocol.connection_made(&mut client.transport);
                let _ = self.poll.register(&client.socket,
                                           token,
                                           Ready::all(),
                                           PollOpt::all());
                debug!(" socket {} registered in the poller", addr);
                return Ok(token);
            }
            Err(_) => {
                error!("Cannot register client {:?}", addr);
                return Err(io::Error::new(io::ErrorKind::Other, format!("Cannot register client {:?}", addr)));
            }
        }
    }

    /// Start the io loop
    pub fn run_forever(&mut self) {
        self.run_until(&|_: &Rio| -> bool { true });
    }

    pub fn run_until(&mut self, is_done: &Fn(&Rio) -> bool) {

        info!("Start polling");

        let timeout = Duration::new(1, 0);
        let mut events = Events::with_capacity(1024);

        self.running = true;
        while self.running {
            debug!("Polling...");
            self.poll.poll(&mut events, Some(timeout)).unwrap();

            for event in events.iter() {
                let token = event.token();
                debug!("Got event for {:?}", token);
                let _ = match self.connections[token].connection_type {
                    ConnectionType::Server => self.handle_server(token),
                    ConnectionType::Client => self.handle_client(token, event),
                };
            }
            self.running = is_done(self)
        }
    }

    pub fn contains(&self, token: Token) -> bool {
        return self.connections.contains(token)
    }

    fn handle_server(&mut self, token: Token) -> io::Result<()> {
        while self.running {
            let (sock, addr) = try!(self.connections[token].server_ref().socket.accept());

            info!("Accepting connection from {:?}", addr);

            debug!("Building procotol");
            let protocol = {
                let server = self.connections[token].server.as_ref();
                server.unwrap().server.build_protocol()
            };

            debug!("Take a token for the connection");
            let result = self.connections.insert(Connection::new_client(protocol, addr, sock));
            match result {
                Ok(client_token) => {
                    debug!("Registering procotol");
                    let mut client = self.connections[client_token].client_mut();
                    client.protocol.connection_made(&mut client.transport);
                    try!(self.poll.register(&client.socket,
                                            client_token,
                                            Ready::readable() | Ready::writable(),
                                            PollOpt::edge() | PollOpt::oneshot()));
                }
                Err(_) => error!("Cannot register client"),

            }
        }
        Ok(())
    }

    fn handle_client(&mut self, token: Token, event: Event) -> io::Result<()> {
        debug!("handle client, {:?}", event);

        if !&self.connections.contains(token) {
            error!("Ignoring unkown token to handle");
            return Ok(());
        }

        let kind = event.kind();

        if !&self.connections[token].alive() || kind.is_error() {
            error!("Connection failed {:?}", &self.connections[token].peer_addr);
            info!("Removing connection {:?}",
                  &self.connections[token].peer_addr);

            {
                let client = &mut self.connections[token].client_mut();
                client.protocol.connection_lost(Reason::ConnectionError);
            }
            self.connections.remove(token);
            return Ok(());
        }

        let mut finished = false;
        let client_addr = &self.connections[token].client_ref().peer_addr().unwrap().clone();
        {
            let mut client = &mut self.connections[token].client_mut();

            debug!("handle client {:?} {:?}", token, client_addr);

            if kind.is_hup() {
                debug!("handle hup {:?} {:?}", token, client_addr);
                client.handle_hup();
                finished = true;
            } else {
                if kind.is_readable() {
                    debug!("handle readable {:?} {:?}", token, client_addr);
                    info!("++++++++++++++++++++++++++++++");
                    try!(client.handle_read());
                    info!("******************************");
                }

                if kind.is_writable() || client.transport.should_write() {
                    debug!("handle writable {:?} {:?}", token, client_addr);
                    client.handle_write();
                }
            }

            if client.is_finished() {
                info!("Closing connection with {:?} {:?}", token, client_addr);
                match client.peer_addr() {
                    Ok(addr) => info!("Connection closed {:?}", addr),
                    Err(_) => error!("Connection closed (Peer already disconnected)"),
                }
                if client.transport.hup() {
                    info!("Peer hang up {:?} {:?}", token, client_addr);
                    client.protocol.connection_lost(Reason::HangUp);
                } else {
                    info!("Connection lost {:?} {:?}", token, client_addr);
                    client.protocol.connection_lost(Reason::ConnectionLost);
                }
                try!(self.poll.deregister(&client.socket));
                finished = true;
            } else {
                info!("Reregister token {:?} {:?}", token, client_addr);
                try!(self.poll.reregister(&client.socket, token, client.interest, PollOpt::edge()));
            }
        }

        if finished {
            info!("Removing connection {:?} {:?}", token, client_addr);
            self.connections.remove(token);
        }

        debug!("end handle client {:?} {:?}", token, client_addr);
        Ok(())
    }
}
<commit_msg>Change logging level<commit_after>use std::io;
use std::net::SocketAddr;
use std::str::FromStr;
use std::time::Duration;

use std::io::{Read, Write};  // Used for TcpStream.read,  TcpStream.write
use mio::{Poll, Token, Events, Event, Ready, PollOpt};
use mio::tcp::{TcpListener, TcpStream};

use slab;
use interface::{ServerFactory, Protocol, Reason};
use transport::Transport;

const CONNS_MAX: usize = 65_536;
const BUF_SIZE: usize = 4096;

type Slab<T> = slab::Slab<T, Token>;

#[derive(Clone)]
enum ConnectionType {
    Server,
    Client,
}

struct ServerConnection {
    server: Box<ServerFactory>,
    socket: TcpListener,
}

struct ClientConnection {
    protocol: Box<Protocol>,
    socket: TcpStream,
    interest: Ready,
    transport: Transport,
}

impl ClientConnection {
    fn new(protocol: Box<Protocol>, socket: TcpStream) -> ClientConnection {
        ClientConnection {
            protocol: protocol,
            socket: socket,
            interest: Ready::hup() | Ready::readable(),
            transport: Transport::new(),
        }
    }

    fn peer_addr(&self) -> io::Result<SocketAddr> {
        self.socket.peer_addr()
    }

    fn is_finished(&self) -> bool {
        self.interest == Ready::none()
    }

    fn handle_hup(&mut self) {
        self.interest = Ready::none();
    }

    fn handle_read(&mut self) -> io::Result<()> {
        let mut read_bytes: Vec<u8> = Vec::new();
        loop {
            let (buf, read_len) = {
                let mut buf = [0; BUF_SIZE];
                let read_len = try!(self.socket.read(&mut buf[..]));
                // let s_data = str::from_utf8(&buf).unwrap();
                // info!("<<< {}", s_data);
                (buf, read_len)
            };
            if read_len > 0 {
                read_bytes.extend(buf[0..read_len].iter());
                if read_len < BUF_SIZE {
                    debug!("Nothing more to read");
                    break;
                } else {
                    debug!("More data to read");
                }
            }
        }
        self.protocol.data_received(&read_bytes[..], &mut self.transport);
        Ok(())
    }

    fn handle_write(&mut self) {

        {
            // a block where transport muting

            debug!("handle write");
            let buf = &mut self.transport.buf();
            let to_write_len = buf.len();
            if to_write_len > 0 {
                // let s_data = str::from_utf8(&buf[..]).unwrap();
                // info!(">>> {}", s_data);

                let result = self.socket.write(&buf[..]);
                match result {
                    Ok(written_len) => {
                        debug!("Write {} bytes", written_len);
                        if to_write_len != written_len {
                            error!("{} bytes to write but {} written, hanging up",
                                   to_write_len,
                                   written_len);
                            self.interest = Ready::hup();
                        }
                    }
                    Err(err) => {
                        error!("Error {} while writing to the socket, disconnecting", err);
                        self.interest = Ready::hup();
                    }
                };
            }
        };

        self.transport.clear();

        if self.transport.hup() {
            info!("Peer is disconnecting, will unregister connection");
            self.interest = Ready::none();
        }
    }
}

struct Connection {
    connection_type: ConnectionType,
    server: Option<ServerConnection>,
    client: Option<ClientConnection>,
    peer_addr: SocketAddr,
}

#[allow(dead_code)]
impl Connection {
    fn new_server(server: Box<ServerFactory>,
                  peer_addr: SocketAddr,
                  socket: TcpListener)
                  -> Connection {
        Connection {
            connection_type: ConnectionType::Server,
            server: Some(ServerConnection {
                server: server,
                socket: socket,
            }),
            client: None,
            peer_addr: peer_addr,
        }
    }

    fn new_client(protocol: Box<Protocol>, peer_addr: SocketAddr, socket: TcpStream) -> Connection {
        Connection {
            connection_type: ConnectionType::Client,
            client: Some(ClientConnection::new(protocol, socket)),
            server: None,
            peer_addr: peer_addr,
        }
    }

    fn peer_addr(&self) -> SocketAddr {
        self.peer_addr
    }

    fn server_ref(&self) -> &ServerConnection {
        self.server.as_ref().unwrap()
    }

    fn client_ref(&self) -> &ClientConnection {
        self.client.as_ref().unwrap()
    }

    fn client_mut(&mut self) -> &mut ClientConnection {
        self.client.as_mut().unwrap()
    }

    fn alive(&self) -> bool {
        return match self.connection_type {
            ConnectionType::Server => true,
            ConnectionType::Client => {
                match self.client_ref().peer_addr() {
                    Ok(_) => true,
                    Err(_) => false,
                }
            }
        };
    }
}

/// The I/O Loop
pub struct Rio {
    poll: Poll,
    connections: Slab<Connection>,
    running: bool
}

impl Rio {
    /// Instanciate the IOLoop, should be called once.
    pub fn new() -> Rio {
        let poll: Poll = Poll::new().unwrap();
        let connections = Slab::with_capacity(CONNS_MAX);
        Rio {
            running: false,
            poll: poll,
            connections: connections,
        }
    }

    /// Will listen on the given address when the loop will start.
    /// The ServerFactory.build_protocol method will be called on every
    /// new client connection.
    pub fn listen(&mut self, addr: &str, server: Box<ServerFactory>) -> Result<Token, io::Error> {
        info!("Rio is listenning on {}", addr);
        let sock_addr: SocketAddr = FromStr::from_str(addr).unwrap();
        debug!("Bind the server socket {}", addr);
        let sock = TcpListener::bind(&sock_addr).unwrap();
        let result = self.connections.insert(Connection::new_server(server, sock_addr, sock));
        match result {
            Ok(token) => {
                let _ = self.poll.register(&self.connections[token].server_ref().socket,
                                           token,
                                           Ready::readable() | Ready::writable(),
                                           PollOpt::edge());
                return Ok(token);
            }
            Err(_) => {
                error!("Cannot register server {:?}", addr);
                return Err(io::Error::new(io::ErrorKind::Other, format!("Cannot register server {:?}", addr)));
            }
        }
    }

    /// Will listen on the given address when the loop will start.
    /// The ServerFactory.build_protocol method will be called on every
    /// new client connection.
    pub fn connect(&mut self, addr: &str, client: Box<Protocol>) -> Result<Token, io::Error> {
        info!("Connecting to socket {}", addr);
        let sock_addr: SocketAddr = FromStr::from_str(addr).unwrap();

        let sock = TcpStream::connect(&sock_addr).unwrap();
        let result = self.connections.insert(Connection::new_client(client, sock_addr, sock));
        match result {
            Ok(token) => {
                let client = self.connections[token].client_mut();
                client.protocol.connection_made(&mut client.transport);
                let _ = self.poll.register(&client.socket,
                                           token,
                                           Ready::all(),
                                           PollOpt::all());
                debug!(" socket {} registered in the poller", addr);
                return Ok(token);
            }
            Err(_) => {
                error!("Cannot register client {:?}", addr);
                return Err(io::Error::new(io::ErrorKind::Other, format!("Cannot register client {:?}", addr)));
            }
        }
    }

    /// Start the io loop
    pub fn run_forever(&mut self) {
        self.run_until(&|_: &Rio| -> bool { true });
    }

    pub fn run_until(&mut self, is_done: &Fn(&Rio) -> bool) {

        info!("Start polling");

        let timeout = Duration::new(1, 0);
        let mut events = Events::with_capacity(1024);

        self.running = true;
        while self.running {
            debug!("Polling...");
            self.poll.poll(&mut events, Some(timeout)).unwrap();

            for event in events.iter() {
                let token = event.token();
                debug!("Got event for {:?}", token);
                let _ = match self.connections[token].connection_type {
                    ConnectionType::Server => self.handle_server(token),
                    ConnectionType::Client => self.handle_client(token, event),
                };
            }
            self.running = is_done(self)
        }
    }

    pub fn contains(&self, token: Token) -> bool {
        return self.connections.contains(token)
    }

    fn handle_server(&mut self, token: Token) -> io::Result<()> {
        while self.running {
            let (sock, addr) = try!(self.connections[token].server_ref().socket.accept());

            info!("Accepting connection from {:?}", addr);

            debug!("Building procotol");
            let protocol = {
                let server = self.connections[token].server.as_ref();
                server.unwrap().server.build_protocol()
            };

            debug!("Take a token for the connection");
            let result = self.connections.insert(Connection::new_client(protocol, addr, sock));
            match result {
                Ok(client_token) => {
                    debug!("Registering procotol");
                    let mut client = self.connections[client_token].client_mut();
                    client.protocol.connection_made(&mut client.transport);
                    try!(self.poll.register(&client.socket,
                                            client_token,
                                            Ready::readable() | Ready::writable(),
                                            PollOpt::edge() | PollOpt::oneshot()));
                }
                Err(_) => error!("Cannot register client"),

            }
        }
        Ok(())
    }

    fn handle_client(&mut self, token: Token, event: Event) -> io::Result<()> {
        debug!("handle client, {:?}", event);

        if !&self.connections.contains(token) {
            error!("Ignoring unkown token to handle");
            return Ok(());
        }

        let kind = event.kind();

        if !&self.connections[token].alive() || kind.is_error() {
            error!("Connection failed {:?}", &self.connections[token].peer_addr);
            info!("Removing connection {:?}",
                  &self.connections[token].peer_addr);

            {
                let client = &mut self.connections[token].client_mut();
                client.protocol.connection_lost(Reason::ConnectionError);
            }
            self.connections.remove(token);
            return Ok(());
        }

        let mut finished = false;
        let client_addr = &self.connections[token].client_ref().peer_addr().unwrap().clone();
        {
            let mut client = &mut self.connections[token].client_mut();

            debug!("handle client {:?} {:?}", token, client_addr);

            if kind.is_hup() {
                debug!("handle hup {:?} {:?}", token, client_addr);
                client.handle_hup();
                finished = true;
            } else {
                if kind.is_readable() {
                    debug!("handle readable {:?} {:?}", token, client_addr);
                    info!("++++++++++++++++++++++++++++++");
                    try!(client.handle_read());
                    info!("******************************");
                }

                if kind.is_writable() || client.transport.should_write() {
                    debug!("handle writable {:?} {:?}", token, client_addr);
                    client.handle_write();
                }
            }

            if client.is_finished() {
                info!("Closing connection with {:?} {:?}", token, client_addr);
                match client.peer_addr() {
                    Ok(addr) => info!("Connection closed {:?}", addr),
                    Err(_) => error!("Connection closed (Peer already disconnected)"),
                }
                if client.transport.hup() {
                    info!("Peer hang up {:?} {:?}", token, client_addr);
                    client.protocol.connection_lost(Reason::HangUp);
                } else {
                    info!("Connection lost {:?} {:?}", token, client_addr);
                    client.protocol.connection_lost(Reason::ConnectionLost);
                }
                try!(self.poll.deregister(&client.socket));
                finished = true;
            } else {
                info!("Reregister token {:?} {:?}", token, client_addr);
                try!(self.poll.reregister(&client.socket, token, client.interest, PollOpt::edge()));
            }
        }

        if finished {
            info!("Removing connection {:?} {:?}", token, client_addr);
            self.connections.remove(token);
        }

        debug!("end handle client {:?} {:?}", token, client_addr);
        Ok(())
    }
}
<|endoftext|>