<commit_before>//! Module containing a few common error wrappers which allows more information to be saved for
//! later display to the user
use std::any::Any;
use std::error::Error as StdError;
use std::fmt;

use ast;

/// An error type which can represent multiple errors.
#[derive(Debug, PartialEq)]
pub struct Errors<T> {
    pub errors: Vec<T>,
}

impl<T> Errors<T> {
    /// Creates a new, empty `Errors` instance.
    pub fn new() -> Errors<T> {
        Errors { errors: Vec::new() }
    }

    /// Returns true if `self` contains any errors
    pub fn has_errors(&self) -> bool {
        !self.errors.is_empty()
    }

    /// Adds an error to `self`
    pub fn error(&mut self, t: T) {
        self.errors.push(t);
    }
}

impl<T: fmt::Display> fmt::Display for Errors<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for error in &self.errors {
            try!(write!(f, "{}\n", error));
        }
        Ok(())
    }
}

impl<T: fmt::Display + fmt::Debug + Any> StdError for Errors<T> {
    fn description(&self) -> &str {
        "Errors"
    }
}

#[derive(Debug)]
struct SourceContext<E> {
    context: String,
    error: ast::Spanned<E>,
}

fn extract_context<E>(lines: &[&str], error: ast::Spanned<E>) -> SourceContext<E> {
    SourceContext {
        context: String::from(lines.get((error.span.start.row - 1) as usize)
                                   .cloned()
                                   .unwrap_or("N/A")),
        error: error,
    }
}

/// Error type which contains information of which file and where in the file the error occured
#[derive(Debug)]
pub struct InFile<E> {
    file: String,
    error: Errors<SourceContext<E>>,
}

impl<E> InFile<E> {
    /// Creates a new `InFile` error which states that the error occured in `file` using the file
    /// contents in `contents` to provide a context to the span.
    pub fn new(file: String, contents: &str, error: Errors<ast::Spanned<E>>) -> InFile<E> {
        let lines: Vec<_> = contents.lines().collect();
        InFile {
            file: file,
            error: Errors {
                errors: error.errors
                             .into_iter()
                             .map(|error| extract_context(&lines, error))
                             .collect(),
            },
        }
    }
}

impl<E: fmt::Display> fmt::Display for InFile<E> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for error in &self.error.errors {
            try!(write!(f, "{}:{}\n{}\n", self.file, error.error, error.context));
            for _ in 1..error.error.span.start.column {
                try!(write!(f, " "));
            }
            try!(write!(f, "^"));
            for _ in error.error.span.start.column..(error.error.span.end.column - 1) {
                try!(write!(f, "~"));
            }
        }
        Ok(())
    }
}

impl<T: fmt::Display + fmt::Debug + Any> StdError for InFile<T> {
    fn description(&self) -> &str {
        "Error in file"
    }
}
<commit_msg>fix: Write a newline between each error<commit_after>//! Module containing a few common error wrappers which allows more information to be saved for
//! later display to the user
use std::any::Any;
use std::error::Error as StdError;
use std::fmt;

use ast;

/// An error type which can represent multiple errors.
#[derive(Debug, PartialEq)]
pub struct Errors<T> {
    pub errors: Vec<T>,
}

impl<T> Errors<T> {
    /// Creates a new, empty `Errors` instance.
    pub fn new() -> Errors<T> {
        Errors { errors: Vec::new() }
    }

    /// Returns true if `self` contains any errors
    pub fn has_errors(&self) -> bool {
        !self.errors.is_empty()
    }

    /// Adds an error to `self`
    pub fn error(&mut self, t: T) {
        self.errors.push(t);
    }
}

impl<T: fmt::Display> fmt::Display for Errors<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for error in &self.errors {
            try!(write!(f, "{}\n", error));
        }
        Ok(())
    }
}

impl<T: fmt::Display + fmt::Debug + Any> StdError for Errors<T> {
    fn description(&self) -> &str {
        "Errors"
    }
}

#[derive(Debug)]
struct SourceContext<E> {
    context: String,
    error: ast::Spanned<E>,
}

fn extract_context<E>(lines: &[&str], error: ast::Spanned<E>) -> SourceContext<E> {
    SourceContext {
        context: String::from(lines.get((error.span.start.row - 1) as usize)
                                   .cloned()
                                   .unwrap_or("N/A")),
        error: error,
    }
}

/// Error type which contains information of which file and where in the file the error occured
#[derive(Debug)]
pub struct InFile<E> {
    file: String,
    error: Errors<SourceContext<E>>,
}

impl<E> InFile<E> {
    /// Creates a new `InFile` error which states that the error occured in `file` using the file
    /// contents in `contents` to provide a context to the span.
    pub fn new(file: String, contents: &str, error: Errors<ast::Spanned<E>>) -> InFile<E> {
        let lines: Vec<_> = contents.lines().collect();
        InFile {
            file: file,
            error: Errors {
                errors: error.errors
                             .into_iter()
                             .map(|error| extract_context(&lines, error))
                             .collect(),
            },
        }
    }
}

impl<E: fmt::Display> fmt::Display for InFile<E> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for error in &self.error.errors {
            try!(write!(f, "{}:{}\n{}\n", self.file, error.error, error.context));
            for _ in 1..error.error.span.start.column {
                try!(write!(f, " "));
            }
            try!(write!(f, "^"));
            for _ in error.error.span.start.column..(error.error.span.end.column - 1) {
                try!(write!(f, "~"));
            }
            try!(writeln!(f, ""));
        }
        Ok(())
    }
}

impl<T: fmt::Display + fmt::Debug + Any> StdError for InFile<T> {
    fn description(&self) -> &str {
        "Error in file"
    }
}
<|endoftext|>


<commit_before>#![feature(test)]
extern crate test;

// Ugly hack to allow benchmarking private modules
#[path = "../src/bit_iterator.rs"] mod bit_iterator;
#[path = "../src/packet.rs"] mod packet;
use test::Bencher;
use packet::Packet;

#[bench]
fn bench_decode(b: &mut Bencher) {
    let buf = [0x21, 0x00, 0x41, 0xa8, 0x99, 0x2f, 0xd0, 0x2a, 0x9f, 0x4a,
               0x26, 0x21, 0x00, 0x10, 0x00, 0x00, 0x3a, 0xf2, 0x6c, 0x79,
               0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a];
    b.iter(|| { let _ = Packet::decode(&buf); });
}

#[bench]
fn bench_encode(b: &mut Bencher) {
    let payload = [1, 2, 3, 4, 5, 6];
    let mut packet = Packet::new();
    packet.payload = payload.to_vec();

    b.iter(|| {
        let _ = test::black_box(packet.bytes());
    });
}
<commit_msg>Silence dead code warnings in packet benchmark.<commit_after>#![feature(test)]
#![allow(dead_code)]
extern crate test;

// Ugly hack to allow benchmarking private modules
#[path = "../src/bit_iterator.rs"] mod bit_iterator;
#[path = "../src/packet.rs"] mod packet;
use test::Bencher;
use packet::Packet;

#[bench]
fn bench_decode(b: &mut Bencher) {
    let buf = [0x21, 0x00, 0x41, 0xa8, 0x99, 0x2f, 0xd0, 0x2a, 0x9f, 0x4a,
               0x26, 0x21, 0x00, 0x10, 0x00, 0x00, 0x3a, 0xf2, 0x6c, 0x79,
               0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a];
    b.iter(|| { let _ = Packet::decode(&buf); });
}

#[bench]
fn bench_encode(b: &mut Bencher) {
    let payload = [1, 2, 3, 4, 5, 6];
    let mut packet = Packet::new();
    packet.payload = payload.to_vec();

    b.iter(|| {
        let _ = test::black_box(packet.bytes());
    });
}
<|endoftext|>


<commit_before>use codec::{
    async_trait::async_trait, eyre::Result, stencila_schema::Node, utils::vec_string, Codec,
    CodecTrait, DecodeOptions, EncodeOptions,
};
use codec_pandoc::{decode, encode, PandocCodec};

/// A codec for LaTeX
pub struct LatexCodec {}

#[async_trait]
impl CodecTrait for LatexCodec {
    fn spec() -> Codec {
        let pandoc_codec = PandocCodec::spec();
        Codec {
            status: "alpha".to_string(),
            formats: vec_string!["latex"],
            root_types: vec_string!["Article"],
            from_string: true,
            from_path: true,
            to_string: true,
            to_path: true,
            unsupported_types: [
                pandoc_codec.unsupported_types,
                vec_string![
                    // TODO: Add support for these. See https://github.com/stencila/encoda/blob/master/src/codecs/latex/__fixtures__/code.tex
                    "CodeChunk",
                    "CodeExpression"
                ],
            ]
            .concat(),
            ..Default::default()
        }
    }

    async fn from_str_async(str: &str, _options: Option<DecodeOptions>) -> Result<Node> {
        decode(str, None, "latex", &[]).await
    }

    async fn to_string_async(node: &Node, _options: Option<EncodeOptions>) -> Result<String> {
        encode(node, None, "latex", &[]).await
    }
}
<commit_msg>chore(LaTeX codec): Update spec<commit_after>use codec::{
    async_trait::async_trait, eyre::Result, stencila_schema::Node, utils::vec_string, Codec,
    CodecTrait, DecodeOptions, EncodeOptions,
};
use codec_pandoc::{decode, encode, PandocCodec};

/// A codec for LaTeX
pub struct LatexCodec {}

#[async_trait]
impl CodecTrait for LatexCodec {
    fn spec() -> Codec {
        let pandoc_codec = PandocCodec::spec();
        Codec {
            status: "alpha".to_string(),
            formats: vec_string!["latex"],
            root_types: vec_string!["Article"],
            unsupported_types: [
                pandoc_codec.unsupported_types,
                vec_string![
                    // TODO: Add support for these. See https://github.com/stencila/encoda/blob/master/src/codecs/latex/__fixtures__/code.tex
                    "CodeChunk",
                    "CodeExpression",
                    "Parameter"
                ],
            ]
            .concat(),
            ..Default::default()
        }
    }

    async fn from_str_async(str: &str, _options: Option<DecodeOptions>) -> Result<Node> {
        decode(str, None, "latex", &[]).await
    }

    async fn to_string_async(node: &Node, _options: Option<EncodeOptions>) -> Result<String> {
        encode(node, None, "latex", &[]).await
    }
}
<|endoftext|>


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

//! Utilities for collecting metrics.

use std::time::SystemTime;
use std::fmt::Arguments;

/// Adds given metric with given value.
///
/// Metric name should be in the following format: `module_name.metric_name`, where `module_name`
/// is a high level name. For example `storage` or `node` (not `storage_proof_list_index`).
///
/// Value is a string and can be formatted similar to the `println!`. See `std::fmt` and example
/// for details.
///
/// Metrics output direction is determined by the corresponding `metrics-...` feature. If
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate exonum;
/// # fn main() {
/// let val = 10;
/// let other_val = "some value";
///
/// metric!("mod_name.metric_name", "{} and {}", val, other_val);
/// # }
/// ```
#[macro_export]
macro_rules! metric {
    ($name:expr, $($arg:tt)+) => ({
        $crate::helpers::metrics::add_metric($name, &format_args!($($arg)+));
    })
}

// Do not use directly, use `metric!` macro instead.
#[doc(hidden)]
pub fn add_metric(metric_name: &str, value: &Arguments) {
    // TODO: Convert time to some meaningful format.
    let time = format!("{:?}", SystemTime::now());

    if cfg!(feature = "metrics-hadoop") {
        write_to_hadoop(metric_name, value, &time);
    }

    if cfg!(feature = "metrics-log") {
        trace!("{} {} {}", metric_name, value, time);
    }
}

fn write_to_hadoop(_metric_name: &str, _value: &Arguments, _time: &str) {
    // TODO: Add implementation.
}
<commit_msg>Use cfg attribute instead of macro<commit_after>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Utilities for collecting metrics.

use std::time::SystemTime;
use std::fmt::Arguments;

/// Adds given metric with given value.
///
/// Metric name should be in the following format: `module_name.metric_name`, where `module_name`
/// is a high level name. For example `storage` or `node` (not `storage_proof_list_index`).
///
/// Value is a string and can be formatted similar to the `println!`. See `std::fmt` and example
/// for details.
///
/// Metrics output direction is determined by the corresponding `metrics-...` feature. If
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate exonum;
/// # fn main() {
/// let val = 10;
/// let other_val = "some value";
///
/// metric!("mod_name.metric_name", "{} and {}", val, other_val);
/// # }
/// ```
#[macro_export]
macro_rules! metric {
    ($name:expr, $($arg:tt)+) => ({
        $crate::helpers::metrics::add_metric($name, &format_args!($($arg)+));
    })
}

// Do not use directly, use `metric!` macro instead.
#[doc(hidden)]
#[allow(unused_variables)]
pub fn add_metric(metric_name: &str, value: &Arguments) {
    // TODO: Convert time to some meaningful format.
    let time = format!("{:?}", SystemTime::now());

    #[cfg(feature = "metrics-hadoop")]
    {
        write_to_hadoop(metric_name, value, &time);
    }

    #[cfg(feature = "metrics-log")]
    {
        trace!("{} {} {}", metric_name, value, time);
    }
}

#[cfg(feature = "metrics-hadoop")]
fn write_to_hadoop(_metric_name: &str, _value: &Arguments, _time: &str) {
    // TODO: Add implementation.
}
<|endoftext|>


<commit_before>// xfail-stage1
// xfail-stage2
// xfail-stage3
// -*- rust -*-

fn x(s: str, n: int) { log s; log n; }

fn main() {
    spawn x("hello from first spawned fn", 65);
    spawn x("hello from second spawned fn", 66);
    spawn x("hello from third spawned fn", 67);
    let i: int = 30;
    while i > 0 { i = i - 1; log "parent sleeping"; yield; }
}<commit_msg>Bring run-pass/spawn-fn up to date and un-XFAIL<commit_after>// -*- rust -*-

use std;
import std::task::yield;

fn x(s: str, n: int) { log s; log n; }

fn main() {
    spawn x("hello from first spawned fn", 65);
    spawn x("hello from second spawned fn", 66);
    spawn x("hello from third spawned fn", 67);
    let i: int = 30;
    while i > 0 { i = i - 1; log "parent sleeping"; yield(); }
}<|endoftext|>


<commit_before>use std::io;
use std::io::{Read, Seek};
use byteorder::{ReadBytesExt, LittleEndian};

use image::ImageError;
use image::ImageResult;
use image::ImageDecoder;
use image::DecodingResult;
use color::ColorType;

enum ImageType {
    NoImageData = 0,
    /// Uncompressed images
    RawColorMap = 1,
    RawTrueColor = 2,
    RawGrayScale = 3,
    /// Run length encoded images
    RunColorMap = 9,
    RunTrueColor = 10,
    RunGrayScale = 11,
    Unknown,
}

impl ImageType {
    /// Create a new image type from a u8
    fn new(img_type: u8) -> ImageType {
        match img_type {
            0  => ImageType::NoImageData,

            1  => ImageType::RawColorMap,
            2  => ImageType::RawTrueColor,
            3  => ImageType::RawGrayScale,

            9  => ImageType::RunColorMap,
            10 => ImageType::RunTrueColor,
            11 => ImageType::RunGrayScale,

            _  => ImageType::Unknown,
        }
    }

    /// Check if the image format uses colors as opposed to gray scale
    fn is_color(&self) -> bool {
        match *self {
            ImageType::RawColorMap  |
            ImageType::RawTrueColor |
            ImageType::RunTrueColor |
            ImageType::RunColorMap => true,
            _ => false,
        }
    }

    /// Does the image use a color map
    fn is_color_mapped(&self) -> bool {
        match *self {
            ImageType::RawColorMap |
            ImageType::RunColorMap => true,
            _ => false,
        }
    }

    /// Is the image run length encoded
    fn is_encoded(&self) -> bool {
        match *self {
            ImageType::RunColorMap |
            ImageType::RunTrueColor |
            ImageType::RunGrayScale => true,
            _ => false,
        }
    }
}

/// Header used by TGA image files
#[derive(Debug)]
struct Header {
    id_length: u8,         // length of ID string
    map_type: u8,          // color map type
    image_type: u8,        // image type code
    map_origin: u16,       // starting index of map
    map_length: u16,      // length of map
    map_entry_size: u8,    // size of map entries in bits
    x_origin: u16,         // x-origin of image
    y_origin: u16,         // y-origin of image
    image_width: u16,      // width of image
    image_height: u16,     // height of image
    pixel_depth: u8,       // bits per pixel
    image_desc: u8,        // image descriptor
}

impl Header {
    /// Create a header with all valuse set to zero
    fn new() -> Header {
        Header {
            id_length: 0,
            map_type: 0,
            image_type: 0,
            map_origin: 0,
            map_length: 0,
            map_entry_size: 0,
            x_origin: 0,
            y_origin: 0,
            image_width: 0,
            image_height: 0,
            pixel_depth: 0,
            image_desc: 0,
        }
    }

    /// Load the header with values from the reader
    fn from_reader(r: &mut Read) -> ImageResult<Header> {
        Ok(Header {
            id_length:         try!(r.read_u8()),
            map_type:          try!(r.read_u8()),
            image_type:        try!(r.read_u8()),
            map_origin:        try!(r.read_u16::<LittleEndian>()),
            map_length:        try!(r.read_u16::<LittleEndian>()),
            map_entry_size:    try!(r.read_u8()),
            x_origin:          try!(r.read_u16::<LittleEndian>()),
            y_origin:          try!(r.read_u16::<LittleEndian>()),
            image_width:       try!(r.read_u16::<LittleEndian>()),
            image_height:      try!(r.read_u16::<LittleEndian>()),
            pixel_depth:       try!(r.read_u8()),
            image_desc:        try!(r.read_u8()),
        })
    }
}

struct ColorMap {
    /// sizes in bytes
    start_offset: usize,
    entry_size: usize,
    bytes: Vec<u8>,
}

impl ColorMap {
    pub fn from_reader(r: &mut Read,
                       start_offset: u16,
                       num_entries: u16,
                       bits_per_entry: u8)
        -> ImageResult<ColorMap> {
            let bytes_per_entry = (bits_per_entry as usize + 7) / 8;

            let mut bytes = vec![0; bytes_per_entry * num_entries as usize];
            try!(r.read_exact(&mut bytes));

            Ok(ColorMap {
                entry_size: bytes_per_entry,
                start_offset: start_offset as usize,
                bytes: bytes,
            })
        }

    /// Get one entry from the color map
    pub fn get(&self, index: usize) -> &[u8] {
        let entry = self.start_offset + self.entry_size * index;
        &self.bytes[entry..entry + self.entry_size]
    }
}

/// The representation of a TGA decoder
pub struct TGADecoder<R> {
    r: R,

    width: usize,
    height: usize,
    bytes_per_pixel: usize,
    has_loaded_metadata: bool,

    image_type: ImageType,
    color_type: ColorType,

    header: Header,
    color_map: Option<ColorMap>,
}

impl<R: Read + Seek> TGADecoder<R> {
    /// Create a new decoder that decodes from the stream `r`
    pub fn new(r: R) -> TGADecoder<R> {
        TGADecoder {
            r: r,

            width: 0,
            height: 0,
            bytes_per_pixel: 0,
            has_loaded_metadata: false,

            image_type: ImageType::Unknown,
            color_type: ColorType::Gray(1),

            header: Header::new(),
            color_map: None,
        }
    }

    fn read_header(&mut self) -> ImageResult<()> {
        self.header = try!(Header::from_reader(&mut self.r));
        self.image_type = ImageType::new(self.header.image_type);
        self.width = self.header.image_width as usize;
        self.height = self.header.image_height as usize;
        self.bytes_per_pixel = (self.header.pixel_depth as usize + 7) / 8;
        Ok(())
    }

    fn read_metadata(&mut self) -> ImageResult<()> {
        if !self.has_loaded_metadata {
            try!(self.read_header());
            try!(self.read_image_id());
            try!(self.read_color_map());
            try!(self.read_color_information());
            self.has_loaded_metadata = true;
        }
        Ok(())
    }

    /// Loads the color information for the decoder
    ///
    /// To keep things simple, we won't handle bit depths that aren't divisible
    /// by 8 and are less than 32.
    fn read_color_information(&mut self) -> ImageResult<()> {
        if self.header.pixel_depth % 8 != 0 {
            return Err(ImageError::UnsupportedError("\
                Bit depth must be divisible by 8".to_string()));
        }
        if self.header.pixel_depth > 32 {
            return Err(ImageError::UnsupportedError("\
                Bit depth must be less than 32".to_string()));
        }

        let num_alpha_bits = self.header.image_desc & 0b1111;

        let other_channel_bits = if self.header.map_type != 0 {
            self.header.map_entry_size
        } else {
            self.header.pixel_depth - num_alpha_bits
        };
        let color = self.image_type.is_color();

        match (num_alpha_bits, other_channel_bits, color) {
            // really, the encoding is BGR and BGRA, this is fixed
            // up with `TGADecoder::reverse_encoding`.
            (8, 24, true) => self.color_type = ColorType::RGBA(8),
            (0, 24, true) => self.color_type = ColorType::RGB(8),
            (8, 8, false) => self.color_type = ColorType::GrayA(8),
            (0, 8, false) => self.color_type = ColorType::Gray(8),
            _ => return Err(ImageError::UnsupportedError(format!("\
                    Color format not supported. Bit depth: {}, Alpha bits: {}",
                    other_channel_bits, num_alpha_bits).to_string())),
        }
        Ok(())
    }

    /// Read the image id field
    ///
    /// We're not interested in this field, so this function skips it if it
    /// is present
    fn read_image_id(&mut self) -> ImageResult<()> {
        try!(self.r.seek(io::SeekFrom::Current(self.header.id_length as i64)));
        Ok(())
    }

    fn read_color_map(&mut self) -> ImageResult<()> {
        if self.header.map_type == 1 {
            self.color_map = Some(try!(
                ColorMap::from_reader(&mut self.r,
                                      self.header.map_origin,
                                      self.header.map_length,
                                      self.header.map_entry_size)));
        }
        Ok(())
    }

    /// Expands indices into its mapped color
    fn expand_color_map(&mut self, pixel_data: Vec<u8>) -> Vec<u8> {
        #[inline]
        fn bytes_to_index(bytes: &[u8]) -> usize {
            let mut result = 0usize;
            for byte in bytes.iter() {
                result = result << 8 | *byte as usize;
            }
            result
        }

        let bytes_per_entry = (self.header.map_entry_size as usize + 7) / 8;
        let mut result = Vec::with_capacity(self.width * self.height *
                                            bytes_per_entry);

        let color_map = match self.color_map {
            Some(ref color_map) => color_map,
            None => unreachable!(),
        };

        for chunk in pixel_data.chunks(self.bytes_per_pixel) {
            let index = bytes_to_index(chunk);
            result.extend(color_map.get(index).iter().map(|&c| c));
        }

        result
    }

    fn read_image_data(&mut self) -> ImageResult<Vec<u8>> {
        // read the pixels from the data region
        let mut pixel_data = if self.image_type.is_encoded() {
            try!(self.read_encoded_data())
        } else {
            let num_raw_bytes = self.width * self.height * self.bytes_per_pixel;
            let mut buf = vec![0; num_raw_bytes];
            try!(self.r.by_ref().read_exact(&mut buf));
            buf
        };

        // expand the indices using the color map if necessary
        if self.image_type.is_color_mapped() {
            pixel_data = self.expand_color_map(pixel_data)
        }

        self.reverse_encoding(&mut pixel_data);

        self.flip_vertically(&mut pixel_data);

        Ok(pixel_data)
    }

    /// Reads a run length encoded packet
    fn read_encoded_data(&mut self) -> ImageResult<Vec<u8>> {
        let num_bytes = self.width * self.height * self.bytes_per_pixel;
        let mut pixel_data = Vec::with_capacity(num_bytes);

        while pixel_data.len() < num_bytes {
            let run_packet = try!(self.r.read_u8());
            // If the highest bit in `run_packet` is set, then we repeat pixels
            //
            // Note: the TGA format adds 1 to both counts because having a count
            // of 0 would be pointless.
            if (run_packet & 0x80) != 0 {
                // high bit set, so we will repeat the data
                let repeat_count = ((run_packet & !0x80) + 1) as usize;
                let mut data = Vec::with_capacity(self.bytes_per_pixel);
                try!(self.r.by_ref().take(self.bytes_per_pixel as u64).read_to_end(&mut data));
                for _ in 0usize..repeat_count {
                    pixel_data.extend(data.iter().map(|&c| c));
                }
            } else {
                // not set, so `run_packet+1` is the number of non-encoded pixels
                let num_raw_bytes = (run_packet + 1) as usize * self.bytes_per_pixel;
                try!(self.r.by_ref().take(num_raw_bytes as u64).read_to_end(&mut pixel_data));
            }
        }

        Ok(pixel_data)
    }

    /// Reverse from BGR encoding to RGB encoding
    ///
    /// TGA files are stored in the BGRA encoding. This function swaps
    /// the blue and red bytes in the `pixels` array.
    fn reverse_encoding(&mut self, pixels: &mut [u8]) {
        // We only need to reverse the encoding of color images
        match self.color_type {
            ColorType::RGB(8) => {
                for chunk in pixels.chunks_mut(self.bytes_per_pixel) {
                    let r = chunk[0];
                    chunk[0] = chunk[2];
                    chunk[2] = r;
                }
            }
            ColorType::RGBA(8) => {
                for chunk in pixels.chunks_mut(self.bytes_per_pixel) {
                    let r = chunk[0];
                    chunk[0] = chunk[2];
                    chunk[2] = r;
                }
            }
            _ => { }
        }
    }

    /// Flip the image vertically depending on the screen origin bit
    ///
    /// The bit in position 5 of the image descriptor byte is the screen origin bit.
    /// If it's 1, the origin is in the top left corner.
    /// If it's 0, the origin is in the bottom left corner.
    /// This function checks the bit, and if it's 0, flips the image vertically.
    fn flip_vertically(&mut self, pixels: &mut [u8]) {
        let screen_origin_bit = 0b100000 & self.header.image_desc != 0;

        if !screen_origin_bit {
            let num_bytes = pixels.len();

            // Make a copy of the current pixels that we can take values from when flipping.
            let mut pixels_copy = Vec::with_capacity(num_bytes);
            for i in 0..pixels.len() {
                pixels_copy.push(pixels[i]);
            }

            let width_bytes = num_bytes / self.height;

            // Flip the image vertically.
            for vertical_index in 0..self.height {
                let vertical_target = (self.height - vertical_index) * width_bytes - width_bytes;

                for horizontal_index in 0..width_bytes {
                    let source = vertical_index * width_bytes + horizontal_index;
                    let target = vertical_target + horizontal_index;

                    pixels[target] = pixels_copy[source];
                }
            }
        }
    }
}

impl<R: Read + Seek> ImageDecoder for TGADecoder<R> {
    fn dimensions(&mut self) -> ImageResult<(u32, u32)> {
        try!(self.read_metadata());

        Ok((self.width as u32, self.height as u32))
    }

    fn colortype(&mut self) -> ImageResult<ColorType> {
        try!(self.read_metadata());

        Ok(self.color_type)
    }

    fn row_len(&mut self) -> ImageResult<usize> {
        try!(self.read_metadata());

        Ok(self.bytes_per_pixel * 8 * self.width)
    }

    fn read_scanline(&mut self, _buf: &mut [u8]) -> ImageResult<u32> {
        unimplemented!();
    }

    fn read_image(&mut self) -> ImageResult<DecodingResult> {
        try!(self.read_metadata());
        self.read_image_data().map(|v| DecodingResult::U8(v) )
    }
}
<commit_msg>Flip value by value instead of copying the entire image before flipping<commit_after>use std::io;
use std::io::{Read, Seek};
use byteorder::{ReadBytesExt, LittleEndian};

use image::ImageError;
use image::ImageResult;
use image::ImageDecoder;
use image::DecodingResult;
use color::ColorType;

enum ImageType {
    NoImageData = 0,
    /// Uncompressed images
    RawColorMap = 1,
    RawTrueColor = 2,
    RawGrayScale = 3,
    /// Run length encoded images
    RunColorMap = 9,
    RunTrueColor = 10,
    RunGrayScale = 11,
    Unknown,
}

impl ImageType {
    /// Create a new image type from a u8
    fn new(img_type: u8) -> ImageType {
        match img_type {
            0  => ImageType::NoImageData,

            1  => ImageType::RawColorMap,
            2  => ImageType::RawTrueColor,
            3  => ImageType::RawGrayScale,

            9  => ImageType::RunColorMap,
            10 => ImageType::RunTrueColor,
            11 => ImageType::RunGrayScale,

            _  => ImageType::Unknown,
        }
    }

    /// Check if the image format uses colors as opposed to gray scale
    fn is_color(&self) -> bool {
        match *self {
            ImageType::RawColorMap  |
            ImageType::RawTrueColor |
            ImageType::RunTrueColor |
            ImageType::RunColorMap => true,
            _ => false,
        }
    }

    /// Does the image use a color map
    fn is_color_mapped(&self) -> bool {
        match *self {
            ImageType::RawColorMap |
            ImageType::RunColorMap => true,
            _ => false,
        }
    }

    /// Is the image run length encoded
    fn is_encoded(&self) -> bool {
        match *self {
            ImageType::RunColorMap |
            ImageType::RunTrueColor |
            ImageType::RunGrayScale => true,
            _ => false,
        }
    }
}

/// Header used by TGA image files
#[derive(Debug)]
struct Header {
    id_length: u8,         // length of ID string
    map_type: u8,          // color map type
    image_type: u8,        // image type code
    map_origin: u16,       // starting index of map
    map_length: u16,      // length of map
    map_entry_size: u8,    // size of map entries in bits
    x_origin: u16,         // x-origin of image
    y_origin: u16,         // y-origin of image
    image_width: u16,      // width of image
    image_height: u16,     // height of image
    pixel_depth: u8,       // bits per pixel
    image_desc: u8,        // image descriptor
}

impl Header {
    /// Create a header with all valuse set to zero
    fn new() -> Header {
        Header {
            id_length: 0,
            map_type: 0,
            image_type: 0,
            map_origin: 0,
            map_length: 0,
            map_entry_size: 0,
            x_origin: 0,
            y_origin: 0,
            image_width: 0,
            image_height: 0,
            pixel_depth: 0,
            image_desc: 0,
        }
    }

    /// Load the header with values from the reader
    fn from_reader(r: &mut Read) -> ImageResult<Header> {
        Ok(Header {
            id_length:         try!(r.read_u8()),
            map_type:          try!(r.read_u8()),
            image_type:        try!(r.read_u8()),
            map_origin:        try!(r.read_u16::<LittleEndian>()),
            map_length:        try!(r.read_u16::<LittleEndian>()),
            map_entry_size:    try!(r.read_u8()),
            x_origin:          try!(r.read_u16::<LittleEndian>()),
            y_origin:          try!(r.read_u16::<LittleEndian>()),
            image_width:       try!(r.read_u16::<LittleEndian>()),
            image_height:      try!(r.read_u16::<LittleEndian>()),
            pixel_depth:       try!(r.read_u8()),
            image_desc:        try!(r.read_u8()),
        })
    }
}

struct ColorMap {
    /// sizes in bytes
    start_offset: usize,
    entry_size: usize,
    bytes: Vec<u8>,
}

impl ColorMap {
    pub fn from_reader(r: &mut Read,
                       start_offset: u16,
                       num_entries: u16,
                       bits_per_entry: u8)
        -> ImageResult<ColorMap> {
            let bytes_per_entry = (bits_per_entry as usize + 7) / 8;

            let mut bytes = vec![0; bytes_per_entry * num_entries as usize];
            try!(r.read_exact(&mut bytes));

            Ok(ColorMap {
                entry_size: bytes_per_entry,
                start_offset: start_offset as usize,
                bytes: bytes,
            })
        }

    /// Get one entry from the color map
    pub fn get(&self, index: usize) -> &[u8] {
        let entry = self.start_offset + self.entry_size * index;
        &self.bytes[entry..entry + self.entry_size]
    }
}

/// The representation of a TGA decoder
pub struct TGADecoder<R> {
    r: R,

    width: usize,
    height: usize,
    bytes_per_pixel: usize,
    has_loaded_metadata: bool,

    image_type: ImageType,
    color_type: ColorType,

    header: Header,
    color_map: Option<ColorMap>,
}

impl<R: Read + Seek> TGADecoder<R> {
    /// Create a new decoder that decodes from the stream `r`
    pub fn new(r: R) -> TGADecoder<R> {
        TGADecoder {
            r: r,

            width: 0,
            height: 0,
            bytes_per_pixel: 0,
            has_loaded_metadata: false,

            image_type: ImageType::Unknown,
            color_type: ColorType::Gray(1),

            header: Header::new(),
            color_map: None,
        }
    }

    fn read_header(&mut self) -> ImageResult<()> {
        self.header = try!(Header::from_reader(&mut self.r));
        self.image_type = ImageType::new(self.header.image_type);
        self.width = self.header.image_width as usize;
        self.height = self.header.image_height as usize;
        self.bytes_per_pixel = (self.header.pixel_depth as usize + 7) / 8;
        Ok(())
    }

    fn read_metadata(&mut self) -> ImageResult<()> {
        if !self.has_loaded_metadata {
            try!(self.read_header());
            try!(self.read_image_id());
            try!(self.read_color_map());
            try!(self.read_color_information());
            self.has_loaded_metadata = true;
        }
        Ok(())
    }

    /// Loads the color information for the decoder
    ///
    /// To keep things simple, we won't handle bit depths that aren't divisible
    /// by 8 and are less than 32.
    fn read_color_information(&mut self) -> ImageResult<()> {
        if self.header.pixel_depth % 8 != 0 {
            return Err(ImageError::UnsupportedError("\
                Bit depth must be divisible by 8".to_string()));
        }
        if self.header.pixel_depth > 32 {
            return Err(ImageError::UnsupportedError("\
                Bit depth must be less than 32".to_string()));
        }

        let num_alpha_bits = self.header.image_desc & 0b1111;

        let other_channel_bits = if self.header.map_type != 0 {
            self.header.map_entry_size
        } else {
            self.header.pixel_depth - num_alpha_bits
        };
        let color = self.image_type.is_color();

        match (num_alpha_bits, other_channel_bits, color) {
            // really, the encoding is BGR and BGRA, this is fixed
            // up with `TGADecoder::reverse_encoding`.
            (8, 24, true) => self.color_type = ColorType::RGBA(8),
            (0, 24, true) => self.color_type = ColorType::RGB(8),
            (8, 8, false) => self.color_type = ColorType::GrayA(8),
            (0, 8, false) => self.color_type = ColorType::Gray(8),
            _ => return Err(ImageError::UnsupportedError(format!("\
                    Color format not supported. Bit depth: {}, Alpha bits: {}",
                    other_channel_bits, num_alpha_bits).to_string())),
        }
        Ok(())
    }

    /// Read the image id field
    ///
    /// We're not interested in this field, so this function skips it if it
    /// is present
    fn read_image_id(&mut self) -> ImageResult<()> {
        try!(self.r.seek(io::SeekFrom::Current(self.header.id_length as i64)));
        Ok(())
    }

    fn read_color_map(&mut self) -> ImageResult<()> {
        if self.header.map_type == 1 {
            self.color_map = Some(try!(
                ColorMap::from_reader(&mut self.r,
                                      self.header.map_origin,
                                      self.header.map_length,
                                      self.header.map_entry_size)));
        }
        Ok(())
    }

    /// Expands indices into its mapped color
    fn expand_color_map(&mut self, pixel_data: Vec<u8>) -> Vec<u8> {
        #[inline]
        fn bytes_to_index(bytes: &[u8]) -> usize {
            let mut result = 0usize;
            for byte in bytes.iter() {
                result = result << 8 | *byte as usize;
            }
            result
        }

        let bytes_per_entry = (self.header.map_entry_size as usize + 7) / 8;
        let mut result = Vec::with_capacity(self.width * self.height *
                                            bytes_per_entry);

        let color_map = match self.color_map {
            Some(ref color_map) => color_map,
            None => unreachable!(),
        };

        for chunk in pixel_data.chunks(self.bytes_per_pixel) {
            let index = bytes_to_index(chunk);
            result.extend(color_map.get(index).iter().map(|&c| c));
        }

        result
    }

    fn read_image_data(&mut self) -> ImageResult<Vec<u8>> {
        // read the pixels from the data region
        let mut pixel_data = if self.image_type.is_encoded() {
            try!(self.read_encoded_data())
        } else {
            let num_raw_bytes = self.width * self.height * self.bytes_per_pixel;
            let mut buf = vec![0; num_raw_bytes];
            try!(self.r.by_ref().read_exact(&mut buf));
            buf
        };

        // expand the indices using the color map if necessary
        if self.image_type.is_color_mapped() {
            pixel_data = self.expand_color_map(pixel_data)
        }

        self.reverse_encoding(&mut pixel_data);

        self.flip_vertically(&mut pixel_data);

        Ok(pixel_data)
    }

    /// Reads a run length encoded packet
    fn read_encoded_data(&mut self) -> ImageResult<Vec<u8>> {
        let num_bytes = self.width * self.height * self.bytes_per_pixel;
        let mut pixel_data = Vec::with_capacity(num_bytes);

        while pixel_data.len() < num_bytes {
            let run_packet = try!(self.r.read_u8());
            // If the highest bit in `run_packet` is set, then we repeat pixels
            //
            // Note: the TGA format adds 1 to both counts because having a count
            // of 0 would be pointless.
            if (run_packet & 0x80) != 0 {
                // high bit set, so we will repeat the data
                let repeat_count = ((run_packet & !0x80) + 1) as usize;
                let mut data = Vec::with_capacity(self.bytes_per_pixel);
                try!(self.r.by_ref().take(self.bytes_per_pixel as u64).read_to_end(&mut data));
                for _ in 0usize..repeat_count {
                    pixel_data.extend(data.iter().map(|&c| c));
                }
            } else {
                // not set, so `run_packet+1` is the number of non-encoded pixels
                let num_raw_bytes = (run_packet + 1) as usize * self.bytes_per_pixel;
                try!(self.r.by_ref().take(num_raw_bytes as u64).read_to_end(&mut pixel_data));
            }
        }

        Ok(pixel_data)
    }

    /// Reverse from BGR encoding to RGB encoding
    ///
    /// TGA files are stored in the BGRA encoding. This function swaps
    /// the blue and red bytes in the `pixels` array.
    fn reverse_encoding(&mut self, pixels: &mut [u8]) {
        // We only need to reverse the encoding of color images
        match self.color_type {
            ColorType::RGB(8) => {
                for chunk in pixels.chunks_mut(self.bytes_per_pixel) {
                    let r = chunk[0];
                    chunk[0] = chunk[2];
                    chunk[2] = r;
                }
            }
            ColorType::RGBA(8) => {
                for chunk in pixels.chunks_mut(self.bytes_per_pixel) {
                    let r = chunk[0];
                    chunk[0] = chunk[2];
                    chunk[2] = r;
                }
            }
            _ => { }
        }
    }

    /// Flip the image vertically depending on the screen origin bit
    ///
    /// The bit in position 5 of the image descriptor byte is the screen origin bit.
    /// If it's 1, the origin is in the top left corner.
    /// If it's 0, the origin is in the bottom left corner.
    /// This function checks the bit, and if it's 0, flips the image vertically.
    fn flip_vertically(&mut self, pixels: &mut [u8]) {
        let screen_origin_bit = 0b100000 & self.header.image_desc != 0;

        if !screen_origin_bit {
            let num_bytes = pixels.len();

            let width_bytes = num_bytes / self.height;

            // Flip the image vertically.
            for vertical_index in 0..(self.height / 2) {
                let vertical_target = (self.height - vertical_index) * width_bytes - width_bytes;

                for horizontal_index in 0..width_bytes {
                    let source = vertical_index * width_bytes + horizontal_index;
                    let target = vertical_target + horizontal_index;

                    let stash = pixels[target];
                    pixels[target] = pixels[source];
                    pixels[source] = stash;
                }
            }
        }
    }
}

impl<R: Read + Seek> ImageDecoder for TGADecoder<R> {
    fn dimensions(&mut self) -> ImageResult<(u32, u32)> {
        try!(self.read_metadata());

        Ok((self.width as u32, self.height as u32))
    }

    fn colortype(&mut self) -> ImageResult<ColorType> {
        try!(self.read_metadata());

        Ok(self.color_type)
    }

    fn row_len(&mut self) -> ImageResult<usize> {
        try!(self.read_metadata());

        Ok(self.bytes_per_pixel * 8 * self.width)
    }

    fn read_scanline(&mut self, _buf: &mut [u8]) -> ImageResult<u32> {
        unimplemented!();
    }

    fn read_image(&mut self) -> ImageResult<DecodingResult> {
        try!(self.read_metadata());
        self.read_image_data().map(|v| DecodingResult::U8(v) )
    }
}
<|endoftext|>


<commit_before>use std::boxed::FnBox;
use std::thread::{self, spawn, JoinHandle};
use std::sync::mpsc::{channel, Sender, SendError, Receiver, TryRecvError};
use std::sync::{Arc, Mutex};
use std::error::Error;
use std::fmt;

use queue;
use mpmc_channel;

trait Runner {
    fn run(self: Box<Self>);
}

impl <F: FnBox()> Runner for F {
    fn run(self: Box<F>) {
        self.call_box(())
    }
}

type Proc<'a> = Box<Runner + Send + 'a>;

pub struct Thread {
    inner: ThreadInner
}

struct ThreadInner {
    sender: Sender<Proc<'static>>,
    result: Receiver<thread::Result<()>>,
}

impl Thread {
    fn new(sender: Sender<Proc<'static>>, result: Receiver<thread::Result<()>>) -> Thread {
        Thread {
            inner: ThreadInner {
                       sender: sender,
                       result: result,
                   },
        }
    }

    pub fn start(&self, f: Proc<'static>) -> Result<(), SendError<Proc<'static>>> {
        self.inner.sender.send(f)
    }

    pub fn join(&self) -> thread::Result<()> {
        self.inner.result.recv().expect("Could not get result")
    }
}

pub struct ThreadPool {
    free_sender: Sender<Thread>, // Keep this to spawn new threads
    free_threads: Receiver<Thread>, // Threads will send themselves when they are free.
    active_threads: usize,
    max_threads: usize,
}

fn spawn_thread(id: usize, free: Sender<Thread>) {
        spawn(move || {
            let sentinel = Sentinel::new(id, free.clone());
            ThreadRunner::new(id, free).run();
            sentinel.done();
        });
}

impl ThreadPool {
    pub fn new(init_threads: usize, max_threads: usize) -> ThreadPool {
        let (sn, rc) = channel();
        for i in 0..init_threads {
            spawn_thread(i, sn.clone());
        }

        // TODO: Wait for threads to come up

        ThreadPool {
            free_sender: sn,
            free_threads: rc,
            active_threads: init_threads,
            max_threads: max_threads
        }
    }

    pub fn thread(&mut self) -> Result<Thread, ThreadError> {
        let res = self.free_threads.try_recv();
        match res {
            Ok(thr) => Ok(thr),
            Err(TryRecvError::Empty) => {
                if self.active_threads >= self.max_threads {
                    Err(ThreadError)
                } else {
                    self.active_threads += 1;
                    spawn_thread(self.active_threads, self.free_sender.clone());
                    let thr = self.free_threads.recv().expect("Could not receive thread");
                    Ok(thr)
                }
            }
            Err(TryRecvError::Disconnected) => panic!("channel closed"),
        }
    }
}

#[derive(Debug, Clone)]
pub struct ThreadError;

impl Error for ThreadError {
    fn description(&self) -> &str {
        "Could not make any more threads."
    }
}

impl fmt::Display for ThreadError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        "Could not make any more threads.".fmt(f)
    }
}

struct Sentinel {
    id: usize,
    free_threads: Sender<Thread>,
    active: bool,
}

// Idea taken from https://github.com/rust-lang/threadpool/blob/b9416b4cb591a3ac8bac8efef19e5cbf5e212a9d/src/lib.rs#L40
impl Sentinel {
    fn new(id: usize, free_threads: Sender<Thread>) -> Sentinel {
        Sentinel {
            id: id,
            free_threads: free_threads,
            active: true,
        }
    }

    // Cancel and destroy this sentinel.
    fn done(mut self) {
        self.active = false;
    }
}

impl Drop for Sentinel {
    fn drop(&mut self) {
        if self.active {
            // Spawn new thread and remove old one.
            spawn_thread(self.id, self.free_threads.clone());
        }
    }
}

struct ThreadRunner {
    id: usize,
    free_chan: Sender<Thread>, // ThreadRunner will send its Thread when it is ready to do work
}

impl ThreadRunner {
    pub fn new(id: usize, free_chan: Sender<Thread>) -> ThreadRunner {
        ThreadRunner {
            id: id,
            free_chan: free_chan,
        }
    }

    fn run(self) {
        loop {
            let (thr, jobs) = channel();
            let (res_sender, res_recver) = channel();
            let thread = Thread::new(thr, res_recver);

            let res = self.free_chan.send(thread);
            if res.is_err() {
                // ThreadPool has disconnected
                return
            }
            let res = jobs.recv();
            if res.is_err() {
                // Thread has disconnected
                return
            }
            let job = res.unwrap();
            let res = thread::catch_panic(move || { job.run(); });
            res_sender.send(res).expect("Could not send result");
        }
    }
}

#[cfg(test)]
mod test {
    use std::sync::mpsc::{channel};
    use std::thread;
    use std::time;
    use thread_pool::{ThreadPool, Runner};

    #[test]
    fn test_runable() {
        let (sn, rc) = channel::<u8>();
        let f = box move || {
            sn.send(0u8).unwrap();
        };
        f.run();
        assert!(rc.recv().unwrap() == 0);
    }

    #[test]
    fn test_thread_pool_thread_and_start() {
        let (sn, rc) = channel::<u8>();
        let (init, max) = (1, 2);
        let mut pool = ThreadPool::new(init, max);

        let f = box move || {
            sn.send(0u8).unwrap();
        };

        let thr1 = pool.thread();
        let thr2 = pool.thread();
        let thr3 = pool.thread();
        assert!(thr3.is_err());

        assert!(thr1.is_ok());
        let thr1 = thr1.ok().unwrap();

        let res = thr1.start(f);
        assert!(res.is_ok());

        assert!(rc.recv().unwrap() == 0);
    }

    #[test]
    fn test_thread_pool_join() {
        let (sn1, rc1) = channel::<u8>();
        let (init, max) = (1, 2);
        let mut pool = ThreadPool::new(init, max);

        let f1 = box move || {
            sn1.send(0u8).unwrap();
        };

        let f2 = box move || {
            panic!();
        };

        // Initial thread.
        let thr1 = pool.thread();
        // Start a new one.
        let thr2 = pool.thread();

        assert!(thr1.is_ok());
        let thr1 = thr1.ok().unwrap();

        assert!(thr2.is_ok());
        let thr2 = thr2.ok().unwrap();

        let res = thr1.start(f1);
        assert!(res.is_ok());
        thr2.start(f2);
        let res = thr1.join();
        assert!(res.is_ok());
        assert!(rc1.recv().unwrap() == 0);

        let res = thr2.join();
        assert!(res.is_err());
    }

    #[test]
    fn test_thread_pool_max_threads_panic() {
        let (sn1, rc1) = channel::<u8>();
        let (sn3, rc3) = channel::<u8>();
        let (init, max) = (1, 2);
        let mut pool = ThreadPool::new(init, max);

        let f1 = box move || {
            sn1.send(0u8).unwrap();
        };

        let f3 = box move || {
            sn3.send(0u8).unwrap();
        };

        let f2 = box move || {
            panic!();
        };

        // Initial thread.
        let thr1 = pool.thread();
        // Start a new one.
        let thr2 = pool.thread();
        let thr1 = thr1.ok().unwrap();
        let thr2 = thr2.ok().unwrap();

        thr2.start(f2);
        let res = thr2.join();
        assert!(res.is_err());

        let thr3 = pool.thread();
        // Can still get thread after panic
        assert!(thr3.is_ok());
        let thr3 = thr3.ok().unwrap();
        thr3.start(f3);
        let res = thr3.join();
        assert!(res.is_ok());
        assert!(rc3.recv().unwrap() == 0);

        thr1.start(f1);
        let res = thr1.join();
        assert!(res.is_ok());
        assert!(rc1.recv().unwrap() == 0);
    }
}
<commit_msg>Wait for threads to start up before returning the ThreadPool<commit_after>use std::boxed::FnBox;
use std::thread::{self, spawn, JoinHandle};
use std::sync::mpsc::{channel, Sender, SendError, Receiver, TryRecvError};
use std::sync::{Arc, Mutex};
use std::error::Error;
use std::fmt;

use queue;
use mpmc_channel;

trait Runner {
    fn run(self: Box<Self>);
}

impl <F: FnBox()> Runner for F {
    fn run(self: Box<F>) {
        self.call_box(())
    }
}

type Proc<'a> = Box<Runner + Send + 'a>;

pub struct Thread {
    inner: ThreadInner
}

struct ThreadInner {
    sender: Sender<Proc<'static>>,
    result: Receiver<thread::Result<()>>,
}

impl Thread {
    fn new(sender: Sender<Proc<'static>>, result: Receiver<thread::Result<()>>) -> Thread {
        Thread {
            inner: ThreadInner {
                       sender: sender,
                       result: result,
                   },
        }
    }

    pub fn start(&self, f: Proc<'static>) -> Result<(), SendError<Proc<'static>>> {
        self.inner.sender.send(f)
    }

    pub fn join(&self) -> thread::Result<()> {
        self.inner.result.recv().expect("Could not get result")
    }
}

pub struct ThreadPool {
    free_sender: Sender<Thread>, // Keep this to spawn new threads
    free_threads: Receiver<Thread>, // Threads will send themselves when they are free.
    active_threads: usize,
    max_threads: usize,
}

fn spawn_thread(id: usize, free: Sender<Thread>) {
        spawn(move || {
            let sentinel = Sentinel::new(id, free.clone());
            ThreadRunner::new(id, free).run();
            sentinel.done();
        });
}

impl ThreadPool {
    pub fn new(init_threads: usize, max_threads: usize) -> ThreadPool {
        let (sn, rc) = channel();
        let mut thrs = Vec::new();
        for i in 0..init_threads {
            spawn_thread(i, sn.clone());
            let thr = rc.recv().expect("Could not receive initial thread");
            thrs.push(thr);
        }

        for t in thrs.into_iter() {
            sn.send(t).expect("Could not reinsert threads");
        }

        ThreadPool {
            free_sender: sn,
            free_threads: rc,
            active_threads: init_threads,
            max_threads: max_threads
        }
    }

    pub fn thread(&mut self) -> Result<Thread, ThreadError> {
        let res = self.free_threads.try_recv();
        match res {
            Ok(thr) => Ok(thr),
            Err(TryRecvError::Empty) => {
                if self.active_threads >= self.max_threads {
                    Err(ThreadError)
                } else {
                    self.active_threads += 1;
                    spawn_thread(self.active_threads, self.free_sender.clone());
                    let thr = self.free_threads.recv().expect("Could not receive thread");
                    Ok(thr)
                }
            }
            Err(TryRecvError::Disconnected) => panic!("channel closed"),
        }
    }
}

#[derive(Debug, Clone)]
pub struct ThreadError;

impl Error for ThreadError {
    fn description(&self) -> &str {
        "Could not make any more threads."
    }
}

impl fmt::Display for ThreadError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        "Could not make any more threads.".fmt(f)
    }
}

struct Sentinel {
    id: usize,
    free_threads: Sender<Thread>,
    active: bool,
}

// Idea taken from https://github.com/rust-lang/threadpool/blob/b9416b4cb591a3ac8bac8efef19e5cbf5e212a9d/src/lib.rs#L40
impl Sentinel {
    fn new(id: usize, free_threads: Sender<Thread>) -> Sentinel {
        Sentinel {
            id: id,
            free_threads: free_threads,
            active: true,
        }
    }

    // Cancel and destroy this sentinel.
    fn done(mut self) {
        self.active = false;
    }
}

impl Drop for Sentinel {
    fn drop(&mut self) {
        if self.active {
            // Spawn new thread and remove old one.
            spawn_thread(self.id, self.free_threads.clone());
        }
    }
}

struct ThreadRunner {
    id: usize,
    free_chan: Sender<Thread>, // ThreadRunner will send its Thread when it is ready to do work
}

impl ThreadRunner {
    pub fn new(id: usize, free_chan: Sender<Thread>) -> ThreadRunner {
        ThreadRunner {
            id: id,
            free_chan: free_chan,
        }
    }

    fn run(self) {
        loop {
            let (thr, jobs) = channel();
            let (res_sender, res_recver) = channel();
            let thread = Thread::new(thr, res_recver);

            let res = self.free_chan.send(thread);
            if res.is_err() {
                // ThreadPool has disconnected
                return
            }
            let res = jobs.recv();
            if res.is_err() {
                // Thread has disconnected
                return
            }
            let job = res.unwrap();
            let res = thread::catch_panic(move || { job.run(); });
            res_sender.send(res).expect("Could not send result");
        }
    }
}

#[cfg(test)]
mod test {
    use std::sync::mpsc::{channel};
    use std::thread;
    use std::time;
    use thread_pool::{ThreadPool, Runner};

    #[test]
    fn test_runable() {
        let (sn, rc) = channel::<u8>();
        let f = box move || {
            sn.send(0u8).unwrap();
        };
        f.run();
        assert!(rc.recv().unwrap() == 0);
    }

    #[test]
    fn test_thread_pool_thread_and_start() {
        let (sn, rc) = channel::<u8>();
        let (init, max) = (1, 2);
        let mut pool = ThreadPool::new(init, max);

        let f = box move || {
            sn.send(0u8).unwrap();
        };

        let thr1 = pool.thread();
        let thr2 = pool.thread();
        let thr3 = pool.thread();
        assert!(thr3.is_err());

        assert!(thr1.is_ok());
        let thr1 = thr1.ok().unwrap();

        let res = thr1.start(f);
        assert!(res.is_ok());

        assert!(rc.recv().unwrap() == 0);
    }

    #[test]
    fn test_thread_pool_join() {
        let (sn1, rc1) = channel::<u8>();
        let (init, max) = (1, 2);
        let mut pool = ThreadPool::new(init, max);

        let f1 = box move || {
            sn1.send(0u8).unwrap();
        };

        let f2 = box move || {
            panic!();
        };

        // Initial thread.
        let thr1 = pool.thread();
        // Start a new one.
        let thr2 = pool.thread();

        assert!(thr1.is_ok());
        let thr1 = thr1.ok().unwrap();

        assert!(thr2.is_ok());
        let thr2 = thr2.ok().unwrap();

        let res = thr1.start(f1);
        assert!(res.is_ok());
        thr2.start(f2);
        let res = thr1.join();
        assert!(res.is_ok());
        assert!(rc1.recv().unwrap() == 0);

        let res = thr2.join();
        assert!(res.is_err());
    }

    #[test]
    fn test_thread_pool_max_threads_panic() {
        let (sn1, rc1) = channel::<u8>();
        let (sn3, rc3) = channel::<u8>();
        let (init, max) = (1, 2);
        let mut pool = ThreadPool::new(init, max);

        let f1 = box move || {
            sn1.send(0u8).unwrap();
        };

        let f3 = box move || {
            sn3.send(0u8).unwrap();
        };

        let f2 = box move || {
            panic!();
        };

        // Initial thread.
        let thr1 = pool.thread();
        // Start a new one.
        let thr2 = pool.thread();
        let thr1 = thr1.ok().unwrap();
        let thr2 = thr2.ok().unwrap();

        thr2.start(f2);
        let res = thr2.join();
        assert!(res.is_err());

        let thr3 = pool.thread();
        // Can still get thread after panic
        assert!(thr3.is_ok());
        let thr3 = thr3.ok().unwrap();
        thr3.start(f3);
        let res = thr3.join();
        assert!(res.is_ok());
        assert!(rc3.recv().unwrap() == 0);

        thr1.start(f1);
        let res = thr1.join();
        assert!(res.is_ok());
        assert!(rc1.recv().unwrap() == 0);
    }
}
<|endoftext|>


<commit_before>use vec_shift::Shift;
use std::str::FromStr;
use std::error::Error as StdError;
use utils::parse_quotes;

/// Defines how an operation on an `Args` method failed.
#[derive(Debug)]
pub enum Error {
    /// "END-OF-STRING", more precisely, there isn't anything to parse anymore.
    Eos,
    /// A parsing operation failed; the error in it can be of any returned from the `FromStr`
    /// trait.
    Parse(Box<StdError>),
}

type Result<T> = ::std::result::Result<T, Error>;

#[derive(Debug, Clone)]
pub struct Args {
    delimiter: String,
    delimiter_split: Vec<String>,
}

impl Args {
    pub fn new(message: &str, delimiter: &str) -> Self {
        let split = if message.trim().is_empty() {
            Vec::new()
        } else {
            message.split(delimiter).map(|s| s.to_string()).collect()
        };

        Args {
            delimiter: delimiter.to_string(),
            delimiter_split: split,
        }
    }

    /// Removes the first element, parses it to a specific type if necessary, returns.
    pub fn single<T: FromStr>(&mut self) -> Result<T>
        where T::Err: StdError + 'static {
        if self.delimiter_split.is_empty() {
            return Err(Error::Eos);
        }

        self.delimiter_split
            .shift()
            .ok_or(Error::Eos)?
            .parse::<T>()
            .map_err(|e| Error::Parse(Box::new(e)))
    }

    /// Like [`single`], but doesn't remove the element.
    ///
    /// [`single`]: #method.single
    pub fn single_n<T: FromStr>(&self) -> Result<T>
        where T::Err: StdError + 'static {
        if self.delimiter_split.is_empty() {
            return Err(Error::Eos);
        }

        self.delimiter_split
            .get(0)
            .ok_or(Error::Eos)?
            .parse::<T>()
            .map_err(|e| Error::Parse(Box::new(e)))
    }

    /// Skips if there's a first element, but also returns it.
    pub fn skip(&mut self) -> Option<String> { self.delimiter_split.shift() }

    /// Like [`skip`], but allows for multiple at once.
    ///
    /// [`skip`]: #method.skip
    pub fn skip_for(&mut self, i: u32) -> Option<Vec<String>> {
        let mut vec = Vec::with_capacity(i as usize);

        for _ in 0..i {
            vec.push(match self.delimiter_split.shift() {
                Some(x) => x,
                None => return None,
            });
        }

        Some(vec)
    }

    /// Like [`single`], but takes quotes into account.
    ///
    /// [`single`]: #method.single
    pub fn single_quoted<T: FromStr>(&mut self) -> Result<T>
        where T::Err: StdError + 'static {
        parse_quotes(&self.delimiter_split.shift().ok_or(Error::Eos)?)
            .remove(0)
            .parse::<T>()
            .map_err(|e| Error::Parse(Box::new(e)))
    }

    /// Like [`single_quoted`], but doesn't remove the element.
    ///
    /// [`single_quoted`]: #method.single_quoted
    pub fn single_quoted_n<T: FromStr>(&self) -> Result<T>
        where T::Err: StdError + 'static {
        parse_quotes(&self.delimiter_split.get(0).ok_or(Error::Eos)?)
            .remove(0)
            .parse::<T>()
            .map_err(|e| Error::Parse(Box::new(e)))
    }

    /// Like [`list`], but takes quotes into account.
    ///
    /// [`list`]: #method.list
    pub fn multiple_quoted<T: FromStr>(self) -> Result<Vec<T>>
        where T::Err: StdError + 'static {
        if self.delimiter_split.is_empty() {
            return Err(Error::Eos);
        }

        parse_quotes(&self.delimiter_split.join(&self.delimiter))
            .into_iter()
            .map(|s| s.parse::<T>().map_err(|e| Error::Parse(Box::new(e))))
            .collect()
    }

    /// Empty outs the internal vector while parsing (if necessary) and returning them
    pub fn list<T: FromStr>(self) -> Result<Vec<T>>
        where T::Err: StdError + 'static {
        if self.delimiter_split.is_empty() {
            return Err(Error::Eos);
        }

        self.delimiter_split
            .into_iter()
            .map(|s| s.parse::<T>().map_err(|e| Error::Parse(Box::new(e))))
            .collect()
    }

    /// This method is just `internal_vector.join(delimiter)`
    pub fn full(&self) -> String { self.delimiter_split.join(&self.delimiter) }
}

impl ::std::ops::Deref for Args {
    type Target = [String];

    fn deref(&self) -> &Self::Target { &self.delimiter_split }
}
<commit_msg>Add find and find_n (#153)<commit_after>use vec_shift::Shift;
use std::str::FromStr;
use std::error::Error as StdError;
use utils::parse_quotes;

/// Defines how an operation on an `Args` method failed.
#[derive(Debug)]
pub enum Error {
    /// "END-OF-STRING", more precisely, there isn't anything to parse anymore.
    Eos,
    /// A parsing operation failed; the error in it can be of any returned from the `FromStr`
    /// trait.
    Parse(Box<StdError>),
}

type Result<T> = ::std::result::Result<T, Error>;

#[derive(Debug, Clone)]
pub struct Args {
    delimiter: String,
    delimiter_split: Vec<String>,
}

impl Args {
    pub fn new(message: &str, delimiter: &str) -> Self {
        let split = if message.trim().is_empty() {
            Vec::new()
        } else {
            message.split(delimiter).map(|s| s.to_string()).collect()
        };

        Args {
            delimiter: delimiter.to_string(),
            delimiter_split: split,
        }
    }

    /// Removes the first element, parses it to a specific type if necessary, returns.
    pub fn single<T: FromStr>(&mut self) -> Result<T>
        where T::Err: StdError + 'static {
        if self.delimiter_split.is_empty() {
            return Err(Error::Eos);
        }

        self.delimiter_split
            .shift()
            .ok_or(Error::Eos)?
            .parse::<T>()
            .map_err(|e| Error::Parse(Box::new(e)))
    }

    /// Like [`single`], but doesn't remove the element.
    ///
    /// [`single`]: #method.single
    pub fn single_n<T: FromStr>(&self) -> Result<T>
        where T::Err: StdError + 'static {
        if self.delimiter_split.is_empty() {
            return Err(Error::Eos);
        }

        self.delimiter_split
            .get(0)
            .ok_or(Error::Eos)?
            .parse::<T>()
            .map_err(|e| Error::Parse(Box::new(e)))
    }

    /// Skips if there's a first element, but also returns it.
    pub fn skip(&mut self) -> Option<String> { self.delimiter_split.shift() }

    /// Like [`skip`], but allows for multiple at once.
    ///
    /// [`skip`]: #method.skip
    pub fn skip_for(&mut self, i: u32) -> Option<Vec<String>> {
        let mut vec = Vec::with_capacity(i as usize);

        for _ in 0..i {
            vec.push(match self.delimiter_split.shift() {
                Some(x) => x,
                None => return None,
            });
        }

        Some(vec)
    }

    /// Like [`single`], but takes quotes into account.
    ///
    /// [`single`]: #method.single
    pub fn single_quoted<T: FromStr>(&mut self) -> Result<T>
        where T::Err: StdError + 'static {
        parse_quotes(&self.delimiter_split.shift().ok_or(Error::Eos)?)
            .remove(0)
            .parse::<T>()
            .map_err(|e| Error::Parse(Box::new(e)))
    }

    /// Like [`single_quoted`], but doesn't remove the element.
    ///
    /// [`single_quoted`]: #method.single_quoted
    pub fn single_quoted_n<T: FromStr>(&self) -> Result<T>
        where T::Err: StdError + 'static {
        parse_quotes(&self.delimiter_split.get(0).ok_or(Error::Eos)?)
            .remove(0)
            .parse::<T>()
            .map_err(|e| Error::Parse(Box::new(e)))
    }

    /// Like [`list`], but takes quotes into account.
    ///
    /// [`list`]: #method.list
    pub fn multiple_quoted<T: FromStr>(self) -> Result<Vec<T>>
        where T::Err: StdError + 'static {
        if self.delimiter_split.is_empty() {
            return Err(Error::Eos);
        }

        parse_quotes(&self.delimiter_split.join(&self.delimiter))
            .into_iter()
            .map(|s| s.parse::<T>().map_err(|e| Error::Parse(Box::new(e))))
            .collect()
    }

    /// Empty outs the internal vector while parsing (if necessary) and returning them
    pub fn list<T: FromStr>(self) -> Result<Vec<T>>
        where T::Err: StdError + 'static {
        if self.delimiter_split.is_empty() {
            return Err(Error::Eos);
        }

        self.delimiter_split
            .into_iter()
            .map(|s| s.parse::<T>().map_err(|e| Error::Parse(Box::new(e))))
            .collect()
    }

    /// This method is just `internal_vector.join(delimiter)`
    pub fn full(&self) -> String { self.delimiter_split.join(&self.delimiter) }

    /// Returns the first argument that can be converted and removes it from the list.
    pub fn find<T: FromStr>(&mut self) -> Result<T>
        where T::Err: StdError + 'static {
        if self.delimiter_split.is_empty() {
            return Err(Error::Eos);
        }

        match self.delimiter_split.iter().position(
            |e| e.parse::<T>().is_ok(),
        ) {
            Some(index) => {
                let value = self.delimiter_split
                    .get(index)
                    .ok_or(Error::Eos)?
                    .parse::<T>()
                    .map_err(|e| Error::Parse(Box::new(e)));

                self.delimiter_split.remove(index);

                value
            },
            _ => Err(Error::Eos),
        }
    }

    /// Returns the first argument that can be converted and does not remove it from the list.
    pub fn find_n<T: FromStr>(&self) -> Result<T>
        where T::Err: StdError + 'static {
        if self.delimiter_split.is_empty() {
            return Err(Error::Eos);
        }

        self.delimiter_split
            .iter()
            .find(|e| e.parse::<T>().is_ok())
            .ok_or(Error::Eos)?
            .parse::<T>()
            .map_err(|e| Error::Parse(Box::new(e)))
    }
}

impl ::std::ops::Deref for Args {
    type Target = [String];

    fn deref(&self) -> &Self::Target { &self.delimiter_split }
}
<|endoftext|>