<commit_before>use std::iter::Iterator;
use std::time::{Instant, Duration};

pub struct ProgressRecord {

    /// How many elements before this
    num: usize,

    /// How long since we started iterating.
    iterating_for: Duration,

    size_hint: (usize, Option<usize>),

    recent_rate: f32,

    /// The timestamp of when the previous record was created. Will be None if this is first.
    previous_record_tm: Option<Instant>,

    /// When the iteration started
    started_iterating: Instant,

}

impl ProgressRecord {
    /// Returns a basic log message of where we are now. You can construct this yourself, but this
    /// is a helpful convience method.
    pub fn message(&self) -> String {
        format!("{} - Seen {} Rate {}/sec", self.duration_since_start().as_secs(), self.num_done(), self.recent_rate())
    }

    /// Duration since iteration started
    pub fn duration_since_start(&self) -> Duration {
        self.iterating_for
    }

    /// Number of items we've generated so far
    pub fn num_done(&self) -> usize {
        self.num
    }

    /// Instant for when the previous record was generated. None if there was no previous record.
    pub fn previous_record_tm(&self) -> Option<Instant> {
        self.previous_record_tm
    }

    /// When the iteration started
    pub fn started_iterating(&self) -> Instant {
        self.started_iterating
    }

    /// Prints a basic message
    pub fn print_message(&self) {
        println!("{}", self.message());
    }

    /// Number of items per second
    pub fn rate(&self) -> f32 {
        // number of items per second
        let duration_since_start = self.duration_since_start();
        (self.num_done() as f32) / (duration_since_start.as_secs() as f32)
    }

    /// None if we don't know how much we've done (as a fraction), otherwise a value form 0 to 1
    /// for what fraction along we are.
    pub fn fraction(&self) -> Option<f32> {
        if self.is_size_known() {
            let remaining = self.size_hint.0;
            let done = self.num_done();
            Some(( done as f32 ) / ( (remaining+done) as f32 ))
        } else {
            None
        }
    }

    /// None if we don't know how much we've done, otherwise value for 0 to 100 representing how
    /// far along as a percentage we are.
    pub fn percent(&self) -> Option<f32> {
        match self.fraction() {
            None => { None }
            Some(f) => { Some(f * 100.0) }
        }
    }

    /// Print out `msg`, but only if there has been `n` seconds since last printout
    pub fn print_every_n_sec<T: std::fmt::Display>(&self, n: f32, msg: T) {
        if self.should_do_every_n_sec(n) {
            print!("{}", msg);
        }
    }

    /// Do thing but only every n sec (as far as possible).
    /// Could be a print statement.
    pub fn do_every_n_sec<F: Fn(&Self)>(&self, n: f32, f: F) {
        if self.should_do_every_n_sec(n) {
            f(self);
        }
    }

    /// If we want to print every `n` sec, should we print now?
    pub fn should_do_every_n_sec(&self, n: f32) -> bool {
        // get the secs since start as a f32
        let duration_since_start = self.duration_since_start();
        let secs_since_start: f32 = duration_since_start.as_secs() as f32 + duration_since_start.subsec_nanos() as f32 / 1_000_000_000.0;

        match self.previous_record_tm() {
            None => {
                // This iteration is the first time, so we should print if more than `n` seconds
                // have gone past
                secs_since_start > n
            },
            Some(last_time) => {
                let last_time_offset = last_time - self.started_iterating();
                let last_time_offset: f32 = last_time_offset.as_secs() as f32 + last_time_offset.subsec_nanos() as f32 / 1_000_000_000.0;

                let current_step = secs_since_start / n;
                let last_step = last_time_offset / n;

                current_step.trunc() > last_step.trunc()
            },
        }
    }

    /// If we want to print every `n` items, should we print now?
    pub fn should_do_every_n_items(&self, n: usize) -> bool {
        (self.num_done() - 1) % n == 0
    }

    /// Print out `msg`, but only if there has been `n` items.
    /// Often you want to print out a debug message every 1,000 items or so. This function does
    /// that.
    pub fn print_every_n_items<T: std::fmt::Display>(&self, n: usize, msg: T) {
        if self.should_do_every_n_items(n) {
            print!("{}", msg);
        }
    }

    /// Do thing but only every n items.
    /// Could be a print statement.
    pub fn do_every_n_items<F: Fn(&Self)>(&self, n: usize, f: F) {
        if self.should_do_every_n_items(n) {
            f(self);
        }
    }

    /// Does the size_hint tell us exactly how many items are left? False iff there is some
    /// ambiguity/unknown
    fn is_size_known(&self) -> bool {
        match self.size_hint.1 {
            None => { false },
            Some(x) => { self.size_hint.0 == x },
        }
    }

    /// The rate of the last few items.
    pub fn recent_rate(&self) -> f32 {
        self.recent_rate
    }

}

/// Wraps an iterator and keeps track of state used for `ProgressRecord`'s
pub struct ProgressRecorderIter<I> {

    /// The iterator that we are iteating on
    iter: I,

    /// How many items have been seen
    count: usize,

    /// When did we start iterating
    started_iterating: Instant,

    /// Keeps track of recent times
    recent_times: Vec<Instant>
}

impl<I: Iterator> ProgressRecorderIter<I> {
    /// Create a new `ProgressRecorderIter` from another iterator.
    pub fn new(iter: I) -> ProgressRecorderIter<I> {
        ProgressRecorderIter{ iter: iter, count: 0, started_iterating: Instant::now(), recent_times: Vec::with_capacity(5) }
    }

    /// Calculate the current `ProgressRecord` for where we are now.
    fn generate_record(&mut self) -> ProgressRecord {
        // recent_times is a vec of times, with newer times at the end. However it'll always be <
        // 100 elements long.
        let now = Instant::now();
        self.recent_times.push(now);
        while self.recent_times.len() > 100 {
            self.recent_times.remove(0);
        }

        let recent_rate = match self.recent_times.get(0) {
            None => ::std::f32::INFINITY,
            Some(&first) => {
                let dur = now - first;
                (self.recent_times.len() as f32 ) / (dur.as_secs() as f32)
            },
        };

        // last element of recent_times will be the current time, for this record. so second last
        // will be the previous time. In python we'd do [-1] for the last, and [-2] for second
        // last.
        let previous_record_tm = match self.recent_times.len() {
            0 | 1 => { None },
            _ => {
                self.recent_times.get(self.recent_times.len()-2).map(|t| { t.clone() })
            }
        };

        self.count += 1;
        ProgressRecord{ num: self.count, iterating_for: now - self.started_iterating, size_hint: self.iter.size_hint(), recent_rate: recent_rate, previous_record_tm: previous_record_tm, started_iterating: self.started_iterating }
    }

}

/// An iterator that records it's progress as it goes along
pub trait ProgressableIter<I> {
    fn progress(self) -> ProgressRecorderIter<I>;
}

impl<I> ProgressableIter<I> for I where I: Iterator {
    /// Convert an iterator into a `ProgressRecorderIter`.
    fn progress(self) -> ProgressRecorderIter<I> {
        ProgressRecorderIter::new(self)
    }
}

impl<I> Iterator for ProgressRecorderIter<I> where I: Iterator {
    type Item = (ProgressRecord, <I as Iterator>::Item);

    #[inline]
    fn next(&mut self) -> Option<(ProgressRecord, <I as Iterator>::Item)> {
        self.iter.next().map(|a| {
            (self.generate_record(), a)
        })
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }

    #[inline]
    fn count(self) -> usize {
        self.iter.count()
    }
}

mod test {
    #[test]
    fn test_simple() {
        use super::ProgressableIter;
        use std::thread::sleep;
        use std::time::Duration;

        let vec: Vec<u8> = vec![0, 1, 2, 3, 4];
        let mut progressor = vec.iter().progress();

        sleep(Duration::from_millis(500));
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "0 - Seen 1 Rate inf/sec");
        // It'll always print on the first one
        assert_eq!(state.should_do_every_n_items(2), true);
        assert_eq!(state.should_do_every_n_items(3), true);
        assert_eq!(state.should_do_every_n_items(5), true);
        assert_eq!(state.rate(), ::std::f32::INFINITY);
        assert_eq!(state.recent_rate(), ::std::f32::INFINITY);
        // First run, so there should be nothing here
        assert!(state.previous_record_tm().is_none());

        assert_eq!(state.should_do_every_n_sec(1.), false);
        assert_eq!(state.should_do_every_n_sec(2.), false);
        assert_eq!(state.should_do_every_n_sec(0.3), true);

        sleep(Duration::from_millis(500));

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "1 - Seen 2 Rate inf/sec");
        assert_eq!(state.should_do_every_n_items(2), false);
        assert_eq!(state.should_do_every_n_items(3), false);
        assert_eq!(state.should_do_every_n_items(5), false);
        assert_eq!(state.rate(), 2.);
        //assert_eq!(state.recent_rate(), 2.);
        // This'll be the time for the first one
        assert!(state.previous_record_tm().is_some());
        let since_last_time = state.previous_record_tm().unwrap().elapsed();
        assert!(since_last_time < Duration::from_millis(550));
        assert!(since_last_time >= Duration::from_millis(500));
        assert_eq!(state.should_do_every_n_sec(1.), true);
        assert_eq!(state.should_do_every_n_sec(2.), false);
        assert_eq!(state.should_do_every_n_sec(0.8), true);

        sleep(Duration::from_millis(500));
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "1 - Seen 3 Rate 3/sec");
        assert_eq!(state.should_do_every_n_items(2), true);
        assert_eq!(state.should_do_every_n_items(3), false);
        assert_eq!(state.should_do_every_n_items(5), false);
        assert_eq!(state.rate(), 3.);
        assert_eq!(state.recent_rate(), 3.);
        assert_eq!(state.should_do_every_n_sec(1.), false);
        assert_eq!(state.should_do_every_n_sec(2.), false);
        assert_eq!(state.should_do_every_n_sec(0.8), false);
        assert_eq!(state.should_do_every_n_sec(1.5), true);

        sleep(Duration::from_millis(500));
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "2 - Seen 4 Rate 4/sec");
        assert_eq!(state.should_do_every_n_items(2), false);
        assert_eq!(state.should_do_every_n_items(3), true);
        assert_eq!(state.should_do_every_n_items(5), false);
        assert_eq!(state.rate(), 2.);
        assert_eq!(state.recent_rate(), 4.);
    }

    #[test]
    fn test_size_hint() {
        use super::ProgressableIter;

        let vec: Vec<u8> = vec![0, 1, 2, 3, 4];
        let mut progressor = vec.iter().progress();

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.fraction(), Some(0.2));
        assert_eq!(state.percent(), Some(20.));

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.fraction(), Some(0.4));
        assert_eq!(state.percent(), Some(40.));

        let mut progressor = (0..).progress();

        let (state, val) = progressor.next().unwrap();
        assert_eq!(val, 0);
        assert_eq!(state.fraction(), None);
        let (state, val) = progressor.next().unwrap();
        assert_eq!(val, 1);
        assert_eq!(state.fraction(), None);

    }
}

<commit_msg>feat: Add .into_inner() to get the inner iter back out<commit_after>use std::iter::Iterator;
use std::time::{Instant, Duration};

pub struct ProgressRecord {

    /// How many elements before this
    num: usize,

    /// How long since we started iterating.
    iterating_for: Duration,

    size_hint: (usize, Option<usize>),

    recent_rate: f32,

    /// The timestamp of when the previous record was created. Will be None if this is first.
    previous_record_tm: Option<Instant>,

    /// When the iteration started
    started_iterating: Instant,

}

impl ProgressRecord {
    /// Returns a basic log message of where we are now. You can construct this yourself, but this
    /// is a helpful convience method.
    pub fn message(&self) -> String {
        format!("{} - Seen {} Rate {}/sec", self.duration_since_start().as_secs(), self.num_done(), self.recent_rate())
    }

    /// Duration since iteration started
    pub fn duration_since_start(&self) -> Duration {
        self.iterating_for
    }

    /// Number of items we've generated so far
    pub fn num_done(&self) -> usize {
        self.num
    }

    /// Instant for when the previous record was generated. None if there was no previous record.
    pub fn previous_record_tm(&self) -> Option<Instant> {
        self.previous_record_tm
    }

    /// When the iteration started
    pub fn started_iterating(&self) -> Instant {
        self.started_iterating
    }

    /// Prints a basic message
    pub fn print_message(&self) {
        println!("{}", self.message());
    }

    /// Number of items per second
    pub fn rate(&self) -> f32 {
        // number of items per second
        let duration_since_start = self.duration_since_start();
        (self.num_done() as f32) / (duration_since_start.as_secs() as f32)
    }

    /// None if we don't know how much we've done (as a fraction), otherwise a value form 0 to 1
    /// for what fraction along we are.
    pub fn fraction(&self) -> Option<f32> {
        if self.is_size_known() {
            let remaining = self.size_hint.0;
            let done = self.num_done();
            Some(( done as f32 ) / ( (remaining+done) as f32 ))
        } else {
            None
        }
    }

    /// None if we don't know how much we've done, otherwise value for 0 to 100 representing how
    /// far along as a percentage we are.
    pub fn percent(&self) -> Option<f32> {
        match self.fraction() {
            None => { None }
            Some(f) => { Some(f * 100.0) }
        }
    }

    /// Print out `msg`, but only if there has been `n` seconds since last printout
    pub fn print_every_n_sec<T: std::fmt::Display>(&self, n: f32, msg: T) {
        if self.should_do_every_n_sec(n) {
            print!("{}", msg);
        }
    }

    /// Do thing but only every n sec (as far as possible).
    /// Could be a print statement.
    pub fn do_every_n_sec<F: Fn(&Self)>(&self, n: f32, f: F) {
        if self.should_do_every_n_sec(n) {
            f(self);
        }
    }

    /// If we want to print every `n` sec, should we print now?
    pub fn should_do_every_n_sec(&self, n: f32) -> bool {
        // get the secs since start as a f32
        let duration_since_start = self.duration_since_start();
        let secs_since_start: f32 = duration_since_start.as_secs() as f32 + duration_since_start.subsec_nanos() as f32 / 1_000_000_000.0;

        match self.previous_record_tm() {
            None => {
                // This iteration is the first time, so we should print if more than `n` seconds
                // have gone past
                secs_since_start > n
            },
            Some(last_time) => {
                let last_time_offset = last_time - self.started_iterating();
                let last_time_offset: f32 = last_time_offset.as_secs() as f32 + last_time_offset.subsec_nanos() as f32 / 1_000_000_000.0;

                let current_step = secs_since_start / n;
                let last_step = last_time_offset / n;

                current_step.trunc() > last_step.trunc()
            },
        }
    }

    /// If we want to print every `n` items, should we print now?
    pub fn should_do_every_n_items(&self, n: usize) -> bool {
        (self.num_done() - 1) % n == 0
    }

    /// Print out `msg`, but only if there has been `n` items.
    /// Often you want to print out a debug message every 1,000 items or so. This function does
    /// that.
    pub fn print_every_n_items<T: std::fmt::Display>(&self, n: usize, msg: T) {
        if self.should_do_every_n_items(n) {
            print!("{}", msg);
        }
    }

    /// Do thing but only every n items.
    /// Could be a print statement.
    pub fn do_every_n_items<F: Fn(&Self)>(&self, n: usize, f: F) {
        if self.should_do_every_n_items(n) {
            f(self);
        }
    }

    /// Does the size_hint tell us exactly how many items are left? False iff there is some
    /// ambiguity/unknown
    fn is_size_known(&self) -> bool {
        match self.size_hint.1 {
            None => { false },
            Some(x) => { self.size_hint.0 == x },
        }
    }

    /// The rate of the last few items.
    pub fn recent_rate(&self) -> f32 {
        self.recent_rate
    }

}

/// Wraps an iterator and keeps track of state used for `ProgressRecord`'s
pub struct ProgressRecorderIter<I> {

    /// The iterator that we are iteating on
    iter: I,

    /// How many items have been seen
    count: usize,

    /// When did we start iterating
    started_iterating: Instant,

    /// Keeps track of recent times
    recent_times: Vec<Instant>
}

impl<I: Iterator> ProgressRecorderIter<I> {
    /// Create a new `ProgressRecorderIter` from another iterator.
    pub fn new(iter: I) -> ProgressRecorderIter<I> {
        ProgressRecorderIter{ iter: iter, count: 0, started_iterating: Instant::now(), recent_times: Vec::with_capacity(5) }
    }

    /// Calculate the current `ProgressRecord` for where we are now.
    fn generate_record(&mut self) -> ProgressRecord {
        // recent_times is a vec of times, with newer times at the end. However it'll always be <
        // 100 elements long.
        let now = Instant::now();
        self.recent_times.push(now);
        while self.recent_times.len() > 100 {
            self.recent_times.remove(0);
        }

        let recent_rate = match self.recent_times.get(0) {
            None => ::std::f32::INFINITY,
            Some(&first) => {
                let dur = now - first;
                (self.recent_times.len() as f32 ) / (dur.as_secs() as f32)
            },
        };

        // last element of recent_times will be the current time, for this record. so second last
        // will be the previous time. In python we'd do [-1] for the last, and [-2] for second
        // last.
        let previous_record_tm = match self.recent_times.len() {
            0 | 1 => { None },
            _ => {
                self.recent_times.get(self.recent_times.len()-2).map(|t| { t.clone() })
            }
        };

        self.count += 1;
        ProgressRecord{ num: self.count, iterating_for: now - self.started_iterating, size_hint: self.iter.size_hint(), recent_rate: recent_rate, previous_record_tm: previous_record_tm, started_iterating: self.started_iterating }
    }

    /// Gets the original iterator back
    pub fn into_inner(self) -> I {
        self.iter
    }

}

/// An iterator that records it's progress as it goes along
pub trait ProgressableIter<I> {
    fn progress(self) -> ProgressRecorderIter<I>;
}

impl<I> ProgressableIter<I> for I where I: Iterator {
    /// Convert an iterator into a `ProgressRecorderIter`.
    fn progress(self) -> ProgressRecorderIter<I> {
        ProgressRecorderIter::new(self)
    }
}

impl<I> Iterator for ProgressRecorderIter<I> where I: Iterator {
    type Item = (ProgressRecord, <I as Iterator>::Item);

    #[inline]
    fn next(&mut self) -> Option<(ProgressRecord, <I as Iterator>::Item)> {
        self.iter.next().map(|a| {
            (self.generate_record(), a)
        })
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }

    #[inline]
    fn count(self) -> usize {
        self.iter.count()
    }
}

mod test {
    #[test]
    fn test_simple() {
        use super::ProgressableIter;
        use std::thread::sleep;
        use std::time::Duration;

        let vec: Vec<u8> = vec![0, 1, 2, 3, 4];
        let mut progressor = vec.iter().progress();

        sleep(Duration::from_millis(500));
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "0 - Seen 1 Rate inf/sec");
        // It'll always print on the first one
        assert_eq!(state.should_do_every_n_items(2), true);
        assert_eq!(state.should_do_every_n_items(3), true);
        assert_eq!(state.should_do_every_n_items(5), true);
        assert_eq!(state.rate(), ::std::f32::INFINITY);
        assert_eq!(state.recent_rate(), ::std::f32::INFINITY);
        // First run, so there should be nothing here
        assert!(state.previous_record_tm().is_none());

        assert_eq!(state.should_do_every_n_sec(1.), false);
        assert_eq!(state.should_do_every_n_sec(2.), false);
        assert_eq!(state.should_do_every_n_sec(0.3), true);

        sleep(Duration::from_millis(500));

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "1 - Seen 2 Rate inf/sec");
        assert_eq!(state.should_do_every_n_items(2), false);
        assert_eq!(state.should_do_every_n_items(3), false);
        assert_eq!(state.should_do_every_n_items(5), false);
        assert_eq!(state.rate(), 2.);
        //assert_eq!(state.recent_rate(), 2.);
        // This'll be the time for the first one
        assert!(state.previous_record_tm().is_some());
        let since_last_time = state.previous_record_tm().unwrap().elapsed();
        assert!(since_last_time < Duration::from_millis(550));
        assert!(since_last_time >= Duration::from_millis(500));
        assert_eq!(state.should_do_every_n_sec(1.), true);
        assert_eq!(state.should_do_every_n_sec(2.), false);
        assert_eq!(state.should_do_every_n_sec(0.8), true);

        sleep(Duration::from_millis(500));
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "1 - Seen 3 Rate 3/sec");
        assert_eq!(state.should_do_every_n_items(2), true);
        assert_eq!(state.should_do_every_n_items(3), false);
        assert_eq!(state.should_do_every_n_items(5), false);
        assert_eq!(state.rate(), 3.);
        assert_eq!(state.recent_rate(), 3.);
        assert_eq!(state.should_do_every_n_sec(1.), false);
        assert_eq!(state.should_do_every_n_sec(2.), false);
        assert_eq!(state.should_do_every_n_sec(0.8), false);
        assert_eq!(state.should_do_every_n_sec(1.5), true);

        sleep(Duration::from_millis(500));
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "2 - Seen 4 Rate 4/sec");
        assert_eq!(state.should_do_every_n_items(2), false);
        assert_eq!(state.should_do_every_n_items(3), true);
        assert_eq!(state.should_do_every_n_items(5), false);
        assert_eq!(state.rate(), 2.);
        assert_eq!(state.recent_rate(), 4.);
    }

    #[test]
    fn test_size_hint() {
        use super::ProgressableIter;

        let vec: Vec<u8> = vec![0, 1, 2, 3, 4];
        let mut progressor = vec.iter().progress();

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.fraction(), Some(0.2));
        assert_eq!(state.percent(), Some(20.));

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.fraction(), Some(0.4));
        assert_eq!(state.percent(), Some(40.));

        let mut progressor = (0..).progress();

        let (state, val) = progressor.next().unwrap();
        assert_eq!(val, 0);
        assert_eq!(state.fraction(), None);
        let (state, val) = progressor.next().unwrap();
        assert_eq!(val, 1);
        assert_eq!(state.fraction(), None);

    }
}

<|endoftext|>


<commit_before>#![crate_id = "staticfile"]
#![deny(missing_doc)]
#![feature(phase)]

//! Static file-serving middleware.

extern crate iron;
extern crate http;
#[phase(plugin, link)]
extern crate log;

use std::path::BytesContainer;
use std::str::from_utf8;

use iron::{Request, Response, Middleware, Alloy};
use iron::mixin::Serve;
use iron::middleware::{Status, Continue, Unwind};

use http::server::request::AbsolutePath;

/// The static file-serving `Middleware`.
#[deriving(Clone)]
pub struct Static {
    root_path: Path
}

impl Static {
    /// Create a new instance of `Static` with a given root path.
    ///
    /// This will attempt to serve static files from the given root path.
    /// The path may be relative or absolute. If `Path::new("")` is given,
    /// files will be served from the current directory.
    ///
    /// If a static file exists and can be read from, `enter` will serve it to
    /// the `Response` and `Unwind` the middleware stack with a status of `200`.
    ///
    /// In the case of any error, it will `Continue` through the stack.
    /// If a file should have been read but cannot, due to permissions or
    /// read errors, a different `Middleware` should handle it.
    ///
    /// If the path is '/', it will attempt to serve `index.html`.
    pub fn new(root_path: Path) -> Static {
        Static {
            root_path: root_path
        }
    }
}

impl Middleware for Static {
    fn enter(&mut self, req: &mut Request, res: &mut Response, _alloy: &mut Alloy) -> Status {
        match req.request_uri {
            AbsolutePath(ref path) => {
                debug!("Serving static file at {}{}.", from_utf8(self.root_path.container_as_bytes()).unwrap(), path);
                let mut relative_path = path.clone();
                if relative_path.eq(&"/".to_string()) {
                    relative_path = "index.html".to_string();
                } else {
                    relative_path.shift_char();
                }
                match res.serve_file(&self.root_path.join(Path::new(relative_path.to_string()))) {
                    Ok(()) => { Unwind },
                    Err(_) => { Continue }
                }
            },
            _ => {
                Continue
            }
        }
    }
}
<commit_msg>(refactor) Use req.url API.<commit_after>#![crate_id = "staticfile"]
#![deny(missing_doc)]
#![feature(phase)]

//! Static file-serving middleware.

extern crate iron;
#[phase(plugin, link)]
extern crate log;

use std::path::BytesContainer;
use std::str::from_utf8;

use iron::{Request, Response, Middleware, Alloy};
use iron::mixin::{GetUrl, Serve};
use iron::middleware::{Status, Continue, Unwind};

/// The static file-serving `Middleware`.
#[deriving(Clone)]
pub struct Static {
    root_path: Path
}

impl Static {
    /// Create a new instance of `Static` with a given root path.
    ///
    /// This will attempt to serve static files from the given root path.
    /// The path may be relative or absolute. If `Path::new("")` is given,
    /// files will be served from the current directory.
    ///
    /// If a static file exists and can be read from, `enter` will serve it to
    /// the `Response` and `Unwind` the middleware stack with a status of `200`.
    ///
    /// In the case of any error, it will `Continue` through the stack.
    /// If a file should have been read but cannot, due to permissions or
    /// read errors, a different `Middleware` should handle it.
    ///
    /// If the path is '/', it will attempt to serve `index.html`.
    pub fn new(root_path: Path) -> Static {
        Static {
            root_path: root_path
        }
    }
}

impl Middleware for Static {
    fn enter(&mut self, req: &mut Request, res: &mut Response, _alloy: &mut Alloy) -> Status {
        match req.url() {
            Some(path) => {
                debug!("Serving static file at {}{}.", from_utf8(self.root_path.container_as_bytes()).unwrap(), path);
                let mut relative_path = path.clone();
                if relative_path.eq(&"/".to_string()) {
                    relative_path = "index.html".to_string();
                } else {
                    relative_path.shift_char();
                }
                match res.serve_file(&self.root_path.join(Path::new(relative_path.to_string()))) {
                    Ok(()) => { Unwind },
                    Err(_) => { Continue }
                }
            },
            None => {
                Continue
            }
        }
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import Method %>

<% data.new_style_struct("Text",
                         inherited=False,
                         gecko_name="TextReset",
                         additional_methods=[Method("has_underline", "bool"),
                                             Method("has_overline", "bool"),
                                             Method("has_line_through", "bool")]) %>

${helpers.single_keyword("text-overflow", "clip ellipsis")}

${helpers.single_keyword("unicode-bidi", "normal embed isolate bidi-override isolate-override plaintext")}

<%helpers:longhand name="text-decoration" custom_cascade="${product == 'servo'}">
    use cssparser::ToCss;
    use std::fmt;
    use values::computed::ComputedValueAsSpecified;

    impl ComputedValueAsSpecified for SpecifiedValue {}

    #[derive(PartialEq, Eq, Copy, Clone, Debug, HeapSizeOf)]
    pub struct SpecifiedValue {
        pub underline: bool,
        pub overline: bool,
        pub line_through: bool,
        // 'blink' is accepted in the parser but ignored.
        // Just not blinking the text is a conforming implementation per CSS 2.1.
    }

    impl ToCss for SpecifiedValue {
        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
            let mut space = false;
            if self.underline {
                try!(dest.write_str("underline"));
                space = true;
            }
            if self.overline {
                if space {
                    try!(dest.write_str(" "));
                }
                try!(dest.write_str("overline"));
                space = true;
            }
            if self.line_through {
                if space {
                    try!(dest.write_str(" "));
                }
                try!(dest.write_str("line-through"));
            }
            Ok(())
        }
    }
    pub mod computed_value {
        pub type T = super::SpecifiedValue;
        #[allow(non_upper_case_globals)]
        pub const none: T = super::SpecifiedValue {
            underline: false, overline: false, line_through: false
        };
    }
    #[inline] pub fn get_initial_value() -> computed_value::T {
        computed_value::none
    }
    /// none | [ underline || overline || line-through || blink ]
    pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
        let mut result = SpecifiedValue {
            underline: false, overline: false, line_through: false,
        };
        if input.try(|input| input.expect_ident_matching("none")).is_ok() {
            return Ok(result)
        }
        let mut blink = false;
        let mut empty = true;
        while let Ok(ident) = input.expect_ident() {
            match_ignore_ascii_case! { ident,
                "underline" => if result.underline { return Err(()) }
                              else { empty = false; result.underline = true },
                "overline" => if result.overline { return Err(()) }
                              else { empty = false; result.overline = true },
                "line-through" => if result.line_through { return Err(()) }
                                  else { empty = false; result.line_through = true },
                "blink" => if blink { return Err(()) }
                           else { empty = false; blink = true },
                _ => break
            }
        }
        if !empty { Ok(result) } else { Err(()) }
    }

    % if product == "servo":
        fn cascade_property_custom<C: ComputedValues>(
                                   _declaration: &PropertyDeclaration,
                                   _inherited_style: &C,
                                   context: &mut computed::Context<C>,
                                   _seen: &mut PropertyBitField,
                                   _cacheable: &mut bool,
                                   _error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
                longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(context);
        }
    % endif
</%helpers:longhand>

${helpers.single_keyword("text-decoration-style",
                         "-moz-none solid double dotted dashed wavy",
                         products="gecko")}

${helpers.predefined_type(
    "text-decoration-color", "CSSColor",
    "CSSParserColor::RGBA(RGBA { red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0 })",
    products="gecko")}
<commit_msg>Make text-decoration-style initial value 'solid'.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />
<% from data import Method %>

<% data.new_style_struct("Text",
                         inherited=False,
                         gecko_name="TextReset",
                         additional_methods=[Method("has_underline", "bool"),
                                             Method("has_overline", "bool"),
                                             Method("has_line_through", "bool")]) %>

${helpers.single_keyword("text-overflow", "clip ellipsis")}

${helpers.single_keyword("unicode-bidi", "normal embed isolate bidi-override isolate-override plaintext")}

<%helpers:longhand name="text-decoration" custom_cascade="${product == 'servo'}">
    use cssparser::ToCss;
    use std::fmt;
    use values::computed::ComputedValueAsSpecified;

    impl ComputedValueAsSpecified for SpecifiedValue {}

    #[derive(PartialEq, Eq, Copy, Clone, Debug, HeapSizeOf)]
    pub struct SpecifiedValue {
        pub underline: bool,
        pub overline: bool,
        pub line_through: bool,
        // 'blink' is accepted in the parser but ignored.
        // Just not blinking the text is a conforming implementation per CSS 2.1.
    }

    impl ToCss for SpecifiedValue {
        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
            let mut space = false;
            if self.underline {
                try!(dest.write_str("underline"));
                space = true;
            }
            if self.overline {
                if space {
                    try!(dest.write_str(" "));
                }
                try!(dest.write_str("overline"));
                space = true;
            }
            if self.line_through {
                if space {
                    try!(dest.write_str(" "));
                }
                try!(dest.write_str("line-through"));
            }
            Ok(())
        }
    }
    pub mod computed_value {
        pub type T = super::SpecifiedValue;
        #[allow(non_upper_case_globals)]
        pub const none: T = super::SpecifiedValue {
            underline: false, overline: false, line_through: false
        };
    }
    #[inline] pub fn get_initial_value() -> computed_value::T {
        computed_value::none
    }
    /// none | [ underline || overline || line-through || blink ]
    pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
        let mut result = SpecifiedValue {
            underline: false, overline: false, line_through: false,
        };
        if input.try(|input| input.expect_ident_matching("none")).is_ok() {
            return Ok(result)
        }
        let mut blink = false;
        let mut empty = true;
        while let Ok(ident) = input.expect_ident() {
            match_ignore_ascii_case! { ident,
                "underline" => if result.underline { return Err(()) }
                              else { empty = false; result.underline = true },
                "overline" => if result.overline { return Err(()) }
                              else { empty = false; result.overline = true },
                "line-through" => if result.line_through { return Err(()) }
                                  else { empty = false; result.line_through = true },
                "blink" => if blink { return Err(()) }
                           else { empty = false; blink = true },
                _ => break
            }
        }
        if !empty { Ok(result) } else { Err(()) }
    }

    % if product == "servo":
        fn cascade_property_custom<C: ComputedValues>(
                                   _declaration: &PropertyDeclaration,
                                   _inherited_style: &C,
                                   context: &mut computed::Context<C>,
                                   _seen: &mut PropertyBitField,
                                   _cacheable: &mut bool,
                                   _error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
                longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(context);
        }
    % endif
</%helpers:longhand>

${helpers.single_keyword("text-decoration-style",
                         "solid double dotted dashed wavy -moz-none",
                         products="gecko")}

${helpers.predefined_type(
    "text-decoration-color", "CSSColor",
    "CSSParserColor::RGBA(RGBA { red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0 })",
    products="gecko")}
<|endoftext|>


<commit_before>// Copyright 2014-2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Myers bit-parallel approximate pattern matching algorithm.
//! Finds all matches up to a given edit distance. The pattern has to fit into a bitvector,
//! and is here limited to 64 symbols.
//! Complexity: O(n)
//!
//! # Example
//!
//! ```
//! # extern crate itertools;
//! # extern crate bio;
//! use bio::pattern_matching::myers::Myers;
//! use itertools::Itertools;
//!
//! # fn main() {
//! let text = b"ACCGTGGATGAGCGCCATAG";
//! let pattern = b"TGAGCGT";
//!
//! let myers = Myers::new(pattern);
//! let occ = myers.find_all_end(text, 1).collect_vec();
//!
//! assert_eq!(occ, [(13, 1), (14, 1)]);
//! # }
//! ```

use std::iter;
use std::u64;

use utils::{TextSlice, IntoTextIterator, TextIterator};

/// Myers algorithm.
pub struct Myers {
    peq: [u64; 256],
    bound: u64,
    m: u8,
}

impl Myers {
    /// Create a new instance of Myers algorithm for a given pattern.
    pub fn new<'a, P: IntoTextIterator<'a>>(pattern: P) -> Self
        where P::IntoIter: ExactSizeIterator
    {
        let pattern = pattern.into_iter();
        let m = pattern.len();
        assert!(m <= 64 && m > 0);

        let mut peq = [0; 256];
        for (i, &a) in pattern.enumerate() {
            peq[a as usize] |= 1 << i;
        }

        Myers {
            peq: peq,
            bound: 1 << (m - 1),
            m: m as u8,
        }
    }

    /// Create a new instance of Myers algorithm for a given pattern and a wildcard character
    /// that shall match any character.
    pub fn with_wildcard(pattern: TextSlice, wildcard: u8) -> Self {
        let mut myers = Self::new(pattern);
        // wildcard matches all symbols of the pattern.
        myers.peq[wildcard as usize] = u64::MAX;

        myers
    }

    fn step(&self, state: &mut State, a: u8) {
        let eq = self.peq[a as usize];
        let xv = eq | state.mv;
        let xh = ((eq & state.pv).saturating_add(state.pv) ^ state.pv) | eq;

        let mut ph = state.mv | !(xh | state.pv);
        let mut mh = state.pv & xh;

        if ph & self.bound > 0 {
            state.dist += 1;
        } else if mh & self.bound > 0 {
            state.dist -= 1;
        }

        ph <<= 1;
        mh <<= 1;
        state.pv = mh | !(xv | ph);
        state.mv = ph & xv;
    }

    /// Calculate the global distance of the pattern to the given text.
    pub fn distance<'a, I: IntoTextIterator<'a>>(&self, text: I) -> u8 {
        let mut state = State::new(self.m);
        for &a in text {
            self.step(&mut state, a);
        }
        state.dist
    }

    /// Find all matches of pattern in the given text up to a given maximum distance.
    /// Matches are returned as an iterator over pairs of end position and distance.
    pub fn find_all_end<'a, I: IntoTextIterator<'a>>(&'a self,
                                                     text: I,
                                                     max_dist: u8)
                                                     -> Matches<I::IntoIter> {
        Matches {
            myers: self,
            state: State::new(self.m),
            text: text.into_iter().enumerate(),
            max_dist: max_dist,
        }
    }
}

/// The current algorithm state.
struct State {
    pv: u64,
    mv: u64,
    dist: u8,
}

impl State {
    /// Create new state.
    pub fn new(m: u8) -> Self {
        State {
            pv: (1 << m) - 1,
            mv: 0,
            dist: m,
        }
    }
}

/// Iterator over pairs of end positions and distance of matches.
pub struct Matches<'a, I: TextIterator<'a>> {
    myers: &'a Myers,
    state: State,
    text: iter::Enumerate<I>,
    max_dist: u8,
}

impl<'a, I: Iterator<Item = &'a u8>> Iterator for Matches<'a, I> {
    type Item = (usize, u8);

    fn next(&mut self) -> Option<(usize, u8)> {
        for (i, &a) in self.text.by_ref() {
            self.myers.step(&mut self.state, a);
            if self.state.dist <= self.max_dist {
                return Some((i, self.state.dist));
            }
        }
        None
    }
}

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

    #[test]
    fn test_find_all_end() {
        let text = b"ACCGTGGATGAGCGCCATAG";
        let pattern = b"TGAGCGT";
        let myers = Myers::new(pattern);
        let occ = myers.find_all_end(text, 1).collect_vec();
        assert_eq!(occ, [(13, 1), (14, 1)]);
    }

    #[test]
    fn test_distance() {
        let text = b"TGAGCNT";
        let pattern = b"TGAGCGT";

        let myers = Myers::new(pattern);
        assert_eq!(myers.distance(text), 1);

        let myers_wildcard = Myers::with_wildcard(pattern, b'N');
        assert_eq!(myers_wildcard.distance(text), 0);
    }

    #[test]
    fn test_long() {
        let text = b"ACCGTGGATGAGCGCCATAGACCGTGGATGAGCGCCATAGACCGTGGATGAGCGCCATAGACCGTGGATGAGCGCCATAGACCGTGGATGAGCGCCATAG";
        let pattern = b"TGAGCGTTGAGCGTTGAGCGTTGAGCGTTGAGCGTTGAGCGT";
        let myers = Myers::new(&pattern[..]);
        let occ = myers.find_all_end(&text[..], 1).collect_vec();
        println!("{:?}", occ);
    }
}
<commit_msg>Use wrapping_add instead of saturating_add.<commit_after>// Copyright 2014-2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Myers bit-parallel approximate pattern matching algorithm.
//! Finds all matches up to a given edit distance. The pattern has to fit into a bitvector,
//! and is here limited to 64 symbols.
//! Complexity: O(n)
//!
//! # Example
//!
//! ```
//! # extern crate itertools;
//! # extern crate bio;
//! use bio::pattern_matching::myers::Myers;
//! use itertools::Itertools;
//!
//! # fn main() {
//! let text = b"ACCGTGGATGAGCGCCATAG";
//! let pattern = b"TGAGCGT";
//!
//! let myers = Myers::new(pattern);
//! let occ = myers.find_all_end(text, 1).collect_vec();
//!
//! assert_eq!(occ, [(13, 1), (14, 1)]);
//! # }
//! ```

use std::iter;
use std::u64;

use utils::{TextSlice, IntoTextIterator, TextIterator};

/// Myers algorithm.
pub struct Myers {
    peq: [u64; 256],
    bound: u64,
    m: u8,
}

impl Myers {
    /// Create a new instance of Myers algorithm for a given pattern.
    pub fn new<'a, P: IntoTextIterator<'a>>(pattern: P) -> Self
        where P::IntoIter: ExactSizeIterator
    {
        let pattern = pattern.into_iter();
        let m = pattern.len();
        assert!(m <= 64 && m > 0);

        let mut peq = [0; 256];
        for (i, &a) in pattern.enumerate() {
            peq[a as usize] |= 1 << i;
        }

        Myers {
            peq: peq,
            bound: 1 << (m - 1),
            m: m as u8,
        }
    }

    /// Create a new instance of Myers algorithm for a given pattern and a wildcard character
    /// that shall match any character.
    pub fn with_wildcard(pattern: TextSlice, wildcard: u8) -> Self {
        let mut myers = Self::new(pattern);
        // wildcard matches all symbols of the pattern.
        myers.peq[wildcard as usize] = u64::MAX;

        myers
    }

    fn step(&self, state: &mut State, a: u8) {
        let eq = self.peq[a as usize];
        let xv = eq | state.mv;
        let xh = ((eq & state.pv).wrapping_add(state.pv) ^ state.pv) | eq;

        let mut ph = state.mv | !(xh | state.pv);
        let mut mh = state.pv & xh;

        if ph & self.bound > 0 {
            state.dist += 1;
        } else if mh & self.bound > 0 {
            state.dist -= 1;
        }

        ph <<= 1;
        mh <<= 1;
        state.pv = mh | !(xv | ph);
        state.mv = ph & xv;
    }

    /// Calculate the global distance of the pattern to the given text.
    pub fn distance<'a, I: IntoTextIterator<'a>>(&self, text: I) -> u8 {
        let mut state = State::new(self.m);
        for &a in text {
            self.step(&mut state, a);
        }
        state.dist
    }

    /// Find all matches of pattern in the given text up to a given maximum distance.
    /// Matches are returned as an iterator over pairs of end position and distance.
    pub fn find_all_end<'a, I: IntoTextIterator<'a>>(&'a self,
                                                     text: I,
                                                     max_dist: u8)
                                                     -> Matches<I::IntoIter> {
        Matches {
            myers: self,
            state: State::new(self.m),
            text: text.into_iter().enumerate(),
            max_dist: max_dist,
        }
    }
}

/// The current algorithm state.
struct State {
    pv: u64,
    mv: u64,
    dist: u8,
}

impl State {
    /// Create new state.
    pub fn new(m: u8) -> Self {
        State {
            pv: (1 << m) - 1,
            mv: 0,
            dist: m,
        }
    }
}

/// Iterator over pairs of end positions and distance of matches.
pub struct Matches<'a, I: TextIterator<'a>> {
    myers: &'a Myers,
    state: State,
    text: iter::Enumerate<I>,
    max_dist: u8,
}

impl<'a, I: Iterator<Item = &'a u8>> Iterator for Matches<'a, I> {
    type Item = (usize, u8);

    fn next(&mut self) -> Option<(usize, u8)> {
        for (i, &a) in self.text.by_ref() {
            self.myers.step(&mut self.state, a);
            if self.state.dist <= self.max_dist {
                return Some((i, self.state.dist));
            }
        }
        None
    }
}

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

    #[test]
    fn test_find_all_end() {
        let text = b"ACCGTGGATGAGCGCCATAG";
        let pattern = b"TGAGCGT";
        let myers = Myers::new(pattern);
        let occ = myers.find_all_end(text, 1).collect_vec();
        assert_eq!(occ, [(13, 1), (14, 1)]);
    }

    #[test]
    fn test_distance() {
        let text = b"TGAGCNT";
        let pattern = b"TGAGCGT";

        let myers = Myers::new(pattern);
        assert_eq!(myers.distance(text), 1);

        let myers_wildcard = Myers::with_wildcard(pattern, b'N');
        assert_eq!(myers_wildcard.distance(text), 0);
    }

    #[test]
    fn test_long() {
        let text = b"ACCGTGGATGAGCGCCATAGACCGTGGATGAGCGCCATAGACCGTGGATGAGCGCCATAGACCGTGGATGAGCGCCATAGACCGTGGATGAGCGCCATAG";
        let pattern = b"TGAGCGTTGAGCGTTGAGCGTTGAGCGTTGAGCGTTGAGCGT";
        let myers = Myers::new(&pattern[..]);
        let occ = myers.find_all_end(&text[..], 1).collect_vec();
        println!("{:?}", occ);
    }
}
<|endoftext|>


<commit_before><commit_msg>add `disjoint()` and `merge()`<commit_after><|endoftext|>


<commit_before>// (c) 2016 Joost Yervante Damad <joost@productize.be>

use std::fmt;

// get from parent
use ERes;
use err;
use read_file;

#[derive(Debug)]
pub struct Schematic {
    libraries:Vec<String>,
    description:Description,
    components:Vec<Component>,
}

impl Schematic {
    fn new() -> Schematic {
        Schematic {
            libraries:vec![],
            description:Description::new(),
            components:vec![],
        }
    }

    fn add_library(&mut self, s:&str) {
        self.libraries.push(String::from(s))
    }

    fn set_description(&mut self, d:&Description) {
        self.description.clone_from(d)
    }

    fn append_component(&mut self, c:Component) {
        self.components.push(c)
    }

}

impl fmt::Display for Schematic {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        try!(writeln!(f, "EESchema Schematic File Version 2"));
        for v in &self.libraries[..] {
            try!(writeln!(f, "LIBS:{}", v))
        }
        try!(write!(f, "{}", self.description));
        for v in &self.components[..] {
            try!(write!(f, "{}", v))
        }
        Ok(())
    }
}

macro_rules! assume_line {
    ($s:expr, $exp:expr) => (
        if $s.eof() {
            return err("end of file reached")
        }
        if $s.here() != $exp {
            return Err(format!("expected '{}', got '{}'", $exp, $s.here()))
        }
        $s.i += 1;
    )
}

#[derive(Debug)]
struct ParseState {
    i:usize,
    v:Vec<String>,
}

impl ParseState {
    fn here(&self) -> &String {
        return &self.v[self.i]
    }

    fn next(&mut self) -> () {
        self.i += 1
    }

    fn eof(&self) -> bool {
        self.i >= self.v.len()
    }
    fn parse_description(&mut self) -> ERes<Description> {
        Ok(Description::new())
    }
    fn parse_component(&mut self) -> ERes<Component> {
        Ok(Component::new())
    }
}

#[derive(Debug,Clone)]
pub struct Description {
    size:String
}

impl Description {
    fn new() -> Description {
        Description { size:String::from("A4") }
    }
}

impl fmt::Display for Description {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        try!(writeln!(f, "$Descr {}", self.size));
        writeln!(f, "$EndDescr")
    }
}

#[derive(Debug)]
struct Component {
    name:String,
    reference:String,
}

impl Component {
    fn new() -> Component {
        Component {
            name:String::from("EFM32HG310"),
            reference:String::from("U1"),
        }
    }
}

impl fmt::Display for Component {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        try!(writeln!(f, "$Comp"));
        try!(writeln!(f, "L {} {}", self.name, self.reference));
        writeln!(f, "$EndComp")
    }
}

fn parse(s: &str) -> ERes<Schematic> {
    let mut sch = Schematic::new();
    let v:Vec<&str> = s.lines().collect();
    let v = v.iter().map(|x| String::from(*x)).collect();
    let mut p = ParseState {i:0, v: v };
    assume_line!(p, "EESchema Schematic File Version 2");
    while !p.eof() {
        {
          let s = p.here();
          if !s.starts_with("LIBS:") {
              break
          }
            sch.add_library(&s[5..]);
        }
        p.next();
    }
    assume_line!(p, "EELAYER 25 0");
    assume_line!(p, "EELAYER END");
    while !p.eof() {
        match &p.here()[..] {
            "$Descr" => {
                let d = try!(p.parse_description());
                sch.set_description(&d)
            },
            "$Comp" => {
                let c = try!(p.parse_component());
                sch.append_component(c)
            },
            _ => println!("TODO: parse other")
        }
        p.next()
    }
    Ok(sch)
}

pub fn parse_str(s: &str) -> Schematic {
    parse(s).unwrap()
}

pub fn parse_file(name: &str) -> Schematic {
    let s = read_file(name).unwrap();
    parse(&s[..]).unwrap()
}

<commit_msg>fix mutability<commit_after>// (c) 2016 Joost Yervante Damad <joost@productize.be>

use std::fmt;

// get from parent
use ERes;
use err;
use read_file;

#[derive(Debug)]
pub struct Schematic {
    libraries:Vec<String>,
    description:Description,
    components:Vec<Component>,
}

impl Schematic {
    fn new() -> Schematic {
        Schematic {
            libraries:vec![],
            description:Description::new(),
            components:vec![],
        }
    }

    fn add_library(&mut self, s:&str) {
        self.libraries.push(String::from(s))
    }

    fn set_description(&mut self, d:&Description) {
        self.description.clone_from(d)
    }

    fn append_component(&mut self, c:Component) {
        self.components.push(c)
    }
}

impl fmt::Display for Schematic {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        try!(writeln!(f, "EESchema Schematic File Version 2"));
        for v in &self.libraries[..] {
            try!(writeln!(f, "LIBS:{}", v))
        }
        try!(write!(f, "{}", self.description));
        for v in &self.components[..] {
            try!(write!(f, "{}", v))
        }
        Ok(())
    }
}

macro_rules! assume_line {
    ($s:expr, $exp:expr) => (
        if $s.eof() {
            return err("end of file reached")
        }
        if $s.here() != $exp {
            return Err(format!("expected '{}', got '{}'", $exp, $s.here()))
        }
        $s.i += 1;
    )
}

#[derive(Debug)]
struct ParseState {
    i:usize,
    v:Vec<String>,
}

impl ParseState {
    fn new(v2:Vec<&str>) -> ParseState {
        ParseState {
            i:0,
            v:v2.iter().map(|x| String::from(*x)).collect(),
        }
    }

    fn here(&self) -> &String {
        return &self.v[self.i]
    }

    fn next(&mut self) {
        self.i += 1;
    }

    fn eof(&self) -> bool {
        self.i >= self.v.len()
    }
}

#[derive(Debug,Clone)]
pub struct Description {
    size:String
}

impl Description {
    fn new() -> Description {
        Description { size:String::from("A4") }
    }
}

impl fmt::Display for Description {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        try!(writeln!(f, "$Descr {}", self.size));
        writeln!(f, "$EndDescr")
    }
}

#[derive(Debug)]
struct Component {
    name:String,
    reference:String,
}

impl Component {
    fn new() -> Component {
        Component {
            name:String::from("EFM32HG310"),
            reference:String::from("U1"),
        }
    }
}

impl fmt::Display for Component {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        try!(writeln!(f, "$Comp"));
        try!(writeln!(f, "L {} {}", self.name, self.reference));
        writeln!(f, "$EndComp")
    }
}

fn parse_description(p:&mut ParseState) -> ERes<Description> {
    Ok(Description::new())
}

fn parse_component(p:&mut ParseState) -> ERes<Component> {
    Ok(Component::new())
}

fn parse(s: &str) -> ERes<Schematic> {
    let mut sch = Schematic::new();
    let v:Vec<&str> = s.lines().collect();
    let p = &mut ParseState::new(v);
    assume_line!(p, "EESchema Schematic File Version 2");
    while !p.eof() {
        {
          let s = p.here();
          if !s.starts_with("LIBS:") {
              break
          }
            sch.add_library(&s[5..]);
        }
        p.next();
    }
    assume_line!(p, "EELAYER 25 0");
    assume_line!(p, "EELAYER END");
    while !p.eof() {
        {
            match &p.here()[..] {
                "$Descr" => {
                    let d = try!(parse_description(p));
                    sch.set_description(&d)
                },
                "$Comp" => {
                    let d = try!(parse_component(p));
                    sch.append_component(d)
                },
                _ => {
                    println!("TODO other parts");
                }
            }
        }
        p.next()
    }
    Ok(sch)
}

pub fn parse_str(s: &str) -> Schematic {
    parse(s).unwrap()
}

pub fn parse_file(name: &str) -> Schematic {
    let s = read_file(name).unwrap();
    parse(&s[..]).unwrap()
}

<|endoftext|>


<commit_before>use crate::sys;
use crate::SBMemoryRegionInfo;

/// A list of [memory regions].
///
/// This is returned from
/// [`SBProcess::get_memory_regions()`](crate::SBProcess::get_memory_regions).
///
/// [memory regions]: SBMemoryRegionInfo
#[derive(Debug)]
pub struct SBMemoryRegionInfoList {
    /// The underlying raw `SBMemoryRegionInfoListRef`.
    pub raw: sys::SBMemoryRegionInfoListRef,
}

impl SBMemoryRegionInfoList {
    /// Construct a new `SBMemoryRegionInfoList`.
    pub(crate) fn wrap(raw: sys::SBMemoryRegionInfoListRef) -> SBMemoryRegionInfoList {
        SBMemoryRegionInfoList { raw }
    }

    #[allow(missing_docs)]
    pub fn append(&self, region: SBMemoryRegionInfo) {
        unsafe { sys::SBMemoryRegionInfoListAppend(self.raw, region.raw) };
    }

    #[allow(missing_docs)]
    pub fn append_list(&self, region_list: SBMemoryRegionInfoList) {
        unsafe { sys::SBMemoryRegionInfoListAppendList(self.raw, region_list.raw) };
    }

    /// Is this memory region list empty?
    pub fn is_empty(&self) -> bool {
        unsafe { sys::SBMemoryRegionInfoListGetSize(self.raw) == 0 }
    }

    /// Clear this memory region list.
    pub fn clear(&self) {
        unsafe { sys::SBMemoryRegionInfoListClear(self.raw) };
    }

    /// Iterate over this memory region list.
    pub fn iter(&self) -> SBMemoryRegionInfoListIter {
        SBMemoryRegionInfoListIter { list: self, idx: 0 }
    }
}

impl Clone for SBMemoryRegionInfoList {
    fn clone(&self) -> Self {
        Self {
            raw: unsafe { sys::CloneSBMemoryRegionInfoList(self.raw) },
        }
    }
}

impl Drop for SBMemoryRegionInfoList {
    fn drop(&mut self) {
        unsafe { sys::DisposeSBMemoryRegionInfoList(self.raw) };
    }
}

/// An iterator over the [memory regions] in an [`SBMemoryRegionInfoList`].
///
/// [memory regions]: SBMemoryRegionInfo
pub struct SBMemoryRegionInfoListIter<'d> {
    list: &'d SBMemoryRegionInfoList,
    idx: u32,
}

impl<'d> Iterator for SBMemoryRegionInfoListIter<'d> {
    type Item = SBMemoryRegionInfo;

    fn next(&mut self) -> Option<SBMemoryRegionInfo> {
        if self.idx < unsafe { sys::SBMemoryRegionInfoListGetSize(self.list.raw) } {
            let info = SBMemoryRegionInfo::default();
            let r = if unsafe {
                sys::SBMemoryRegionInfoListGetMemoryRegionAtIndex(self.list.raw, self.idx, info.raw)
            } {
                Some(info)
            } else {
                None
            };
            self.idx += 1;
            r
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let sz = unsafe { sys::SBMemoryRegionInfoListGetSize(self.list.raw) } as usize;
        (sz - self.idx as usize, Some(sz))
    }
}

impl<'d> ExactSizeIterator for SBMemoryRegionInfoListIter<'d> {}
<commit_msg>Add missing unsafe impl Sync,Send for SBMemoryRegionInfoList.<commit_after>use crate::sys;
use crate::SBMemoryRegionInfo;

/// A list of [memory regions].
///
/// This is returned from
/// [`SBProcess::get_memory_regions()`](crate::SBProcess::get_memory_regions).
///
/// [memory regions]: SBMemoryRegionInfo
#[derive(Debug)]
pub struct SBMemoryRegionInfoList {
    /// The underlying raw `SBMemoryRegionInfoListRef`.
    pub raw: sys::SBMemoryRegionInfoListRef,
}

impl SBMemoryRegionInfoList {
    /// Construct a new `SBMemoryRegionInfoList`.
    pub(crate) fn wrap(raw: sys::SBMemoryRegionInfoListRef) -> SBMemoryRegionInfoList {
        SBMemoryRegionInfoList { raw }
    }

    #[allow(missing_docs)]
    pub fn append(&self, region: SBMemoryRegionInfo) {
        unsafe { sys::SBMemoryRegionInfoListAppend(self.raw, region.raw) };
    }

    #[allow(missing_docs)]
    pub fn append_list(&self, region_list: SBMemoryRegionInfoList) {
        unsafe { sys::SBMemoryRegionInfoListAppendList(self.raw, region_list.raw) };
    }

    /// Is this memory region list empty?
    pub fn is_empty(&self) -> bool {
        unsafe { sys::SBMemoryRegionInfoListGetSize(self.raw) == 0 }
    }

    /// Clear this memory region list.
    pub fn clear(&self) {
        unsafe { sys::SBMemoryRegionInfoListClear(self.raw) };
    }

    /// Iterate over this memory region list.
    pub fn iter(&self) -> SBMemoryRegionInfoListIter {
        SBMemoryRegionInfoListIter { list: self, idx: 0 }
    }
}

impl Clone for SBMemoryRegionInfoList {
    fn clone(&self) -> Self {
        Self {
            raw: unsafe { sys::CloneSBMemoryRegionInfoList(self.raw) },
        }
    }
}

impl Drop for SBMemoryRegionInfoList {
    fn drop(&mut self) {
        unsafe { sys::DisposeSBMemoryRegionInfoList(self.raw) };
    }
}

unsafe impl Send for SBMemoryRegionInfoList {}
unsafe impl Sync for SBMemoryRegionInfoList {}

/// An iterator over the [memory regions] in an [`SBMemoryRegionInfoList`].
///
/// [memory regions]: SBMemoryRegionInfo
pub struct SBMemoryRegionInfoListIter<'d> {
    list: &'d SBMemoryRegionInfoList,
    idx: u32,
}

impl<'d> Iterator for SBMemoryRegionInfoListIter<'d> {
    type Item = SBMemoryRegionInfo;

    fn next(&mut self) -> Option<SBMemoryRegionInfo> {
        if self.idx < unsafe { sys::SBMemoryRegionInfoListGetSize(self.list.raw) } {
            let info = SBMemoryRegionInfo::default();
            let r = if unsafe {
                sys::SBMemoryRegionInfoListGetMemoryRegionAtIndex(self.list.raw, self.idx, info.raw)
            } {
                Some(info)
            } else {
                None
            };
            self.idx += 1;
            r
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let sz = unsafe { sys::SBMemoryRegionInfoListGetSize(self.list.raw) } as usize;
        (sz - self.idx as usize, Some(sz))
    }
}

impl<'d> ExactSizeIterator for SBMemoryRegionInfoListIter<'d> {}
<|endoftext|>


<commit_before>// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.

//! jsonrpc server over unix sockets
//!
//! ```no_run
//! extern crate jsonrpc_core;
//! extern crate json_ipc_server;
//! extern crate rand;
//!
//! use std::sync::Arc;
//! use jsonrpc_core::*;
//! use json_ipc_server::Server;
//!
//! struct SayHello;
//! impl MethodCommand for SayHello {
//! 	fn execute(&self, _params: Params) -> Result<Value, Error> {
//! 		Ok(Value::String("hello".to_string()))
//! 	}
//! }
//!
//! fn main() {
//! 	let io = IoHandler::new();
//! 	io.add_method("say_hello", SayHello);
//! 	let server = Server::new("/tmp/json-ipc-test.ipc", &Arc::new(io)).unwrap();
//!     ::std::thread::spawn(move || server.run());
//! }
//! ```

use mio::*;
use mio::unix::*;
use bytes::{Buf, ByteBuf, MutByteBuf};
use std::io;
use jsonrpc_core::IoHandler;
use std::sync::*;
use std::sync::atomic::*;
use std;
use slab;
use validator;
#[cfg(test)]
use tests;

const SERVER: Token = Token(0);
const MAX_CONCURRENT_CONNECTIONS: usize = 16;
const MAX_WRITE_LENGTH: usize = 8192;

struct SocketConnection {
    socket: UnixStream,
    buf: Option<ByteBuf>,
    mut_buf: Option<MutByteBuf>,
    token: Option<Token>,
    interest: EventSet,
}

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

impl SocketConnection {
    fn new(sock: UnixStream) -> Self {
        SocketConnection {
            socket: sock,
            buf: None,
            mut_buf: Some(ByteBuf::mut_with_capacity(4096)),
            token: None,
            interest: EventSet::hup(),
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<RpcServer>, _handler: &IoHandler) -> io::Result<()> {
        use std::io::Write;
        if let Some(buf) = self.buf.take() {
			if buf.remaining() < MAX_WRITE_LENGTH {
	            try!(self.socket.write_all(&buf.bytes()));
				self.interest.remove(EventSet::writable());
				self.interest.insert(EventSet::readable());
			}
			else {
				try!(self.socket.write_all(&buf.bytes()[0..MAX_WRITE_LENGTH]));
				self.buf = Some(ByteBuf::from_slice(&buf.bytes()[MAX_WRITE_LENGTH..]));
			}
        }

        event_loop.reregister(&self.socket, self.token.unwrap(), self.interest, PollOpt::edge() | PollOpt::oneshot())
    }

    fn readable(&mut self, event_loop: &mut EventLoop<RpcServer>, handler: &IoHandler) -> io::Result<()> {
        let mut buf = self.mut_buf.take().unwrap_or_else(|| panic!("unwrapping mutable buffer which is None"));

        match self.socket.try_read_buf(&mut buf) {
            Ok(None) => {
                self.mut_buf = Some(buf);
            }
            Ok(Some(_)) => {
                let (requests, last_index) = validator::extract_requests(buf.bytes());
                if requests.len() > 0 {
                    let mut response_bytes = Vec::new();
                    for rpc_msg in requests {
                        trace!(target: "ipc", "Request: {}", rpc_msg);
                        let response: Option<String> = handler.handle_request(&rpc_msg);
                        if let Some(response_str) = response {
                            trace!(target: "ipc", "Response: {}", &response_str);
                            response_bytes.extend(response_str.into_bytes());
                        }
                    }
                    self.buf = Some(ByteBuf::from_slice(&response_bytes[..]));

                    let mut new_buf = ByteBuf::mut_with_capacity(4096);
                    new_buf.write_slice(&buf.bytes()[last_index..]);
                    self.mut_buf = Some(new_buf);

                    self.interest.remove(EventSet::readable());
                    self.interest.insert(EventSet::writable());
                }
                else {
                    self.mut_buf = Some(buf);
                }
            }
            Err(e) => {
                trace!(target: "ipc", "Error receiving data: {:?}", e);
                self.interest.remove(EventSet::readable());
            }

        };

        event_loop.reregister(&self.socket, self.token.unwrap(), self.interest, PollOpt::edge() | PollOpt::oneshot())
    }
}

struct RpcServer {
    socket: UnixListener,
    connections: Slab<SocketConnection>,
    io_handler: Arc<IoHandler>,
}

pub struct Server {
    rpc_server: Arc<RwLock<RpcServer>>,
    event_loop: Arc<RwLock<EventLoop<RpcServer>>>,
    is_stopping: Arc<AtomicBool>,
    is_stopped: Arc<AtomicBool>,
    addr: String,
}

#[derive(Debug)]
pub enum Error {
    Io(std::io::Error),
    NotStarted,
    AlreadyStopping,
    NotStopped,
    IsStopping,
}

impl std::convert::From<std::io::Error> for Error {
    fn from(io_error: std::io::Error) -> Error {
        Error::Io(io_error)
    }
}

impl Server {
    /// New server
    pub fn new(socket_addr: &str, io_handler: &Arc<IoHandler>) -> Result<Server, Error> {
        let (server, event_loop) = try!(RpcServer::start(socket_addr, io_handler));
        Ok(Server {
            rpc_server: Arc::new(RwLock::new(server)),
            event_loop: Arc::new(RwLock::new(event_loop)),
            is_stopping: Arc::new(AtomicBool::new(false)),
            is_stopped: Arc::new(AtomicBool::new(true)),
            addr: socket_addr.to_owned(),
        })
    }

    /// Run server (in current thread)
    pub fn run(&self) {
        let mut event_loop = self.event_loop.write().unwrap();
        let mut server = self.rpc_server.write().unwrap();
        event_loop.run(&mut server).unwrap();
    }

    /// Poll server requests (for manual async scenarios)
    pub fn poll(&self) {
        let mut event_loop = self.event_loop.write().unwrap();
        let mut server = self.rpc_server.write().unwrap();

        event_loop.run_once(&mut server, Some(100)).unwrap();
    }

    /// Run server (in separate thread)
    pub fn run_async(&self) -> Result<(), Error> {
        if self.is_stopping.load(Ordering::Relaxed) { return Err(Error::IsStopping) }
        if !self.is_stopped.load(Ordering::Relaxed) { return Err(Error::NotStopped) }

        self.is_stopped.store(false, Ordering::Relaxed);

        let event_loop = self.event_loop.clone();
        let server = self.rpc_server.clone();
        let thread_stopping = self.is_stopping.clone();
        let thread_stopped = self.is_stopped.clone();
        std::thread::spawn(move || {
            let mut event_loop = event_loop.write().unwrap();
            let mut server = server.write().unwrap();
            while !thread_stopping.load(Ordering::Relaxed) {
                event_loop.run_once(&mut server, Some(100)).unwrap();
            }
            thread_stopped.store(true, Ordering::Relaxed);
        });
        Ok(())
    }

    pub fn stop_async(&self) -> Result<(), Error> {
        if self.is_stopped.load(Ordering::Relaxed) { return Err(Error::NotStarted) }
        if self.is_stopping.load(Ordering::Relaxed) { return Err(Error::AlreadyStopping)}
        self.is_stopping.store(true, Ordering::Relaxed);
        Ok(())
    }

    pub fn stop(&self) -> Result<(), Error> {
        if self.is_stopped.load(Ordering::Relaxed) { return Err(Error::NotStarted) }
        if self.is_stopping.load(Ordering::Relaxed) { return Err(Error::AlreadyStopping)}
        self.is_stopping.store(true, Ordering::Relaxed);
        while !self.is_stopped.load(Ordering::Relaxed) { std::thread::sleep(std::time::Duration::new(0, 10)); }
        Ok(())
    }
}

impl Drop for Server {
    fn drop(&mut self) {
        self.stop().unwrap_or_else(|_| {}); // ignore error - can be stopped already
        ::std::fs::remove_file(&self.addr).unwrap_or_else(|_| {}); // ignoer error - server could have never been started
    }
}

impl RpcServer {

    /// start ipc rpc server (blocking)
    pub fn start(addr: &str, io_handler: &Arc<IoHandler>) -> Result<(RpcServer, EventLoop<RpcServer>), Error> {
        let mut event_loop = try!(EventLoop::new());
        ::std::fs::remove_file(addr).unwrap_or_else(|_| {} ); // ignore error (if no file)
        let socket = try!(UnixListener::bind(&addr));
        event_loop.register(&socket, SERVER, EventSet::readable(), PollOpt::edge()).unwrap();
        let server = RpcServer {
            socket: socket,
            connections: Slab::new_starting_at(Token(1), MAX_CONCURRENT_CONNECTIONS),
            io_handler: io_handler.clone(),
        };
        Ok((server, event_loop))
    }

    fn accept(&mut self, event_loop: &mut EventLoop<RpcServer>) -> io::Result<()> {
        let new_client_socket = self.socket.accept().unwrap().unwrap();
        let connection = SocketConnection::new(new_client_socket);
        if self.connections.count() >= MAX_CONCURRENT_CONNECTIONS {
            let oldest_token = self.connections.iter().nth(0)
                .expect("fatal: impossible since count > MAX_CONCURRENT_CONNECTIONS and we request first one")
                .token.unwrap().clone();
            self.connections.remove(oldest_token);
        }
        let token = self.connections.insert(connection).ok().expect("fatal: Could not add connection to slab (memory issue?)");

        self.connections[token].token = Some(token);
        event_loop.register(
            &self.connections[token].socket,
            token,
            EventSet::readable(),
            PollOpt::edge() | PollOpt::oneshot()
        ).ok().expect("fatal: could not register socket with event loop (memory issue?)");

        Ok(())
    }

    fn connection_readable(&mut self, event_loop: &mut EventLoop<RpcServer>, tok: Token) -> io::Result<()> {
        let io_handler = self.io_handler.clone();
        self.connection(tok).readable(event_loop, &io_handler)
    }

    fn connection_writable(&mut self, event_loop: &mut EventLoop<RpcServer>, tok: Token) -> io::Result<()> {
        let io_handler = self.io_handler.clone();
        self.connection(tok).writable(event_loop, &io_handler)
    }

    fn connection<'a>(&'a mut self, tok: Token) -> &'a mut SocketConnection {
        &mut self.connections[tok]
    }
}

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

    fn ready(&mut self, event_loop: &mut EventLoop<RpcServer>, token: Token, events: EventSet) {
        if events.is_readable() {
            match token {
                SERVER => self.accept(event_loop).unwrap(),
                _ => self.connection_readable(event_loop, token).unwrap()
            };
        }

        if events.is_writable() {
            match token {
                SERVER => { },
                _ => self.connection_writable(event_loop, token).unwrap_or_else(|_| {}), // todo: disqualify connection from list on error
            };
        }
    }
}

#[test]
pub fn test_reqrep_poll() {
    let addr = tests::random_ipc_endpoint();
    let io = tests::dummy_io_handler();
    let server = Server::new(&addr, &io).unwrap();
    std::thread::spawn(move || {
        loop {
            server.poll();
        }
    });

    let request = r#"{"jsonrpc": "2.0", "method": "say_hello", "params": [42, 23], "id": 1}"#;
    let response = r#"{"jsonrpc":"2.0","result":"hello 42! you sent 23","id":1}"#;
    assert_eq!(String::from_utf8(tests::dummy_request(&addr, request.as_bytes())).unwrap(), response.to_string());

    std::thread::sleep(std::time::Duration::from_millis(500));
}

#[test]
pub fn test_file_removed() {
    let addr = tests::random_ipc_endpoint();
    let io = tests::dummy_io_handler();
    {
        let server = Server::new(&addr, &io).unwrap();
        server.run_async().unwrap();
        std::thread::sleep(std::time::Duration::from_millis(50));

        let request = r#"{"jsonrpc": "2.0", "method": "say_hello", "params": [42, 23], "id": 1}"#;
        let response = r#"{"jsonrpc":"2.0","result":"hello 42! you sent 23","id":1}"#;
        assert_eq!(String::from_utf8(tests::dummy_request(&addr, request.as_bytes())).unwrap(), response.to_string());
    }
    assert!(::std::fs::metadata(addr).is_err()); // err is file not exists
}
<commit_msg>+1 char there<commit_after>// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.

//! jsonrpc server over unix sockets
//!
//! ```no_run
//! extern crate jsonrpc_core;
//! extern crate json_ipc_server;
//! extern crate rand;
//!
//! use std::sync::Arc;
//! use jsonrpc_core::*;
//! use json_ipc_server::Server;
//!
//! struct SayHello;
//! impl MethodCommand for SayHello {
//! 	fn execute(&self, _params: Params) -> Result<Value, Error> {
//! 		Ok(Value::String("hello".to_string()))
//! 	}
//! }
//!
//! fn main() {
//! 	let io = IoHandler::new();
//! 	io.add_method("say_hello", SayHello);
//! 	let server = Server::new("/tmp/json-ipc-test.ipc", &Arc::new(io)).unwrap();
//!     ::std::thread::spawn(move || server.run());
//! }
//! ```

use mio::*;
use mio::unix::*;
use bytes::{Buf, ByteBuf, MutByteBuf};
use std::io;
use jsonrpc_core::IoHandler;
use std::sync::*;
use std::sync::atomic::*;
use std;
use slab;
use validator;
#[cfg(test)]
use tests;

const SERVER: Token = Token(0);
const MAX_CONCURRENT_CONNECTIONS: usize = 16;
const MAX_WRITE_LENGTH: usize = 8192;

struct SocketConnection {
    socket: UnixStream,
    buf: Option<ByteBuf>,
    mut_buf: Option<MutByteBuf>,
    token: Option<Token>,
    interest: EventSet,
}

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

impl SocketConnection {
    fn new(sock: UnixStream) -> Self {
        SocketConnection {
            socket: sock,
            buf: None,
            mut_buf: Some(ByteBuf::mut_with_capacity(4096)),
            token: None,
            interest: EventSet::hup(),
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<RpcServer>, _handler: &IoHandler) -> io::Result<()> {
        use std::io::Write;
        if let Some(buf) = self.buf.take() {
			if buf.remaining() < MAX_WRITE_LENGTH {
	            try!(self.socket.write_all(&buf.bytes()));
				self.interest.remove(EventSet::writable());
				self.interest.insert(EventSet::readable());
			}
			else {
				try!(self.socket.write_all(&buf.bytes()[0..MAX_WRITE_LENGTH]));
				self.buf = Some(ByteBuf::from_slice(&buf.bytes()[MAX_WRITE_LENGTH..]));
			}
        }

        event_loop.reregister(&self.socket, self.token.unwrap(), self.interest, PollOpt::edge() | PollOpt::oneshot())
    }

    fn readable(&mut self, event_loop: &mut EventLoop<RpcServer>, handler: &IoHandler) -> io::Result<()> {
        let mut buf = self.mut_buf.take().unwrap_or_else(|| panic!("unwrapping mutable buffer which is None"));

        match self.socket.try_read_buf(&mut buf) {
            Ok(None) => {
                self.mut_buf = Some(buf);
            }
            Ok(Some(_)) => {
                let (requests, last_index) = validator::extract_requests(buf.bytes());
                if requests.len() > 0 {
                    let mut response_bytes = Vec::new();
                    for rpc_msg in requests {
                        trace!(target: "ipc", "Request: {}", rpc_msg);
                        let response: Option<String> = handler.handle_request(&rpc_msg);
                        if let Some(response_str) = response {
                            trace!(target: "ipc", "Response: {}", &response_str);
                            response_bytes.extend(response_str.into_bytes());
                        }
                    }
                    self.buf = Some(ByteBuf::from_slice(&response_bytes[..]));

                    let mut new_buf = ByteBuf::mut_with_capacity(4096);
                    new_buf.write_slice(&buf.bytes()[last_index+1..]);
                    self.mut_buf = Some(new_buf);

                    self.interest.remove(EventSet::readable());
                    self.interest.insert(EventSet::writable());
                }
                else {
                    self.mut_buf = Some(buf);
                }
            }
            Err(e) => {
                trace!(target: "ipc", "Error receiving data: {:?}", e);
                self.interest.remove(EventSet::readable());
            }

        };

        event_loop.reregister(&self.socket, self.token.unwrap(), self.interest, PollOpt::edge() | PollOpt::oneshot())
    }
}

struct RpcServer {
    socket: UnixListener,
    connections: Slab<SocketConnection>,
    io_handler: Arc<IoHandler>,
}

pub struct Server {
    rpc_server: Arc<RwLock<RpcServer>>,
    event_loop: Arc<RwLock<EventLoop<RpcServer>>>,
    is_stopping: Arc<AtomicBool>,
    is_stopped: Arc<AtomicBool>,
    addr: String,
}

#[derive(Debug)]
pub enum Error {
    Io(std::io::Error),
    NotStarted,
    AlreadyStopping,
    NotStopped,
    IsStopping,
}

impl std::convert::From<std::io::Error> for Error {
    fn from(io_error: std::io::Error) -> Error {
        Error::Io(io_error)
    }
}

impl Server {
    /// New server
    pub fn new(socket_addr: &str, io_handler: &Arc<IoHandler>) -> Result<Server, Error> {
        let (server, event_loop) = try!(RpcServer::start(socket_addr, io_handler));
        Ok(Server {
            rpc_server: Arc::new(RwLock::new(server)),
            event_loop: Arc::new(RwLock::new(event_loop)),
            is_stopping: Arc::new(AtomicBool::new(false)),
            is_stopped: Arc::new(AtomicBool::new(true)),
            addr: socket_addr.to_owned(),
        })
    }

    /// Run server (in current thread)
    pub fn run(&self) {
        let mut event_loop = self.event_loop.write().unwrap();
        let mut server = self.rpc_server.write().unwrap();
        event_loop.run(&mut server).unwrap();
    }

    /// Poll server requests (for manual async scenarios)
    pub fn poll(&self) {
        let mut event_loop = self.event_loop.write().unwrap();
        let mut server = self.rpc_server.write().unwrap();

        event_loop.run_once(&mut server, Some(100)).unwrap();
    }

    /// Run server (in separate thread)
    pub fn run_async(&self) -> Result<(), Error> {
        if self.is_stopping.load(Ordering::Relaxed) { return Err(Error::IsStopping) }
        if !self.is_stopped.load(Ordering::Relaxed) { return Err(Error::NotStopped) }

        self.is_stopped.store(false, Ordering::Relaxed);

        let event_loop = self.event_loop.clone();
        let server = self.rpc_server.clone();
        let thread_stopping = self.is_stopping.clone();
        let thread_stopped = self.is_stopped.clone();
        std::thread::spawn(move || {
            let mut event_loop = event_loop.write().unwrap();
            let mut server = server.write().unwrap();
            while !thread_stopping.load(Ordering::Relaxed) {
                event_loop.run_once(&mut server, Some(100)).unwrap();
            }
            thread_stopped.store(true, Ordering::Relaxed);
        });
        Ok(())
    }

    pub fn stop_async(&self) -> Result<(), Error> {
        if self.is_stopped.load(Ordering::Relaxed) { return Err(Error::NotStarted) }
        if self.is_stopping.load(Ordering::Relaxed) { return Err(Error::AlreadyStopping)}
        self.is_stopping.store(true, Ordering::Relaxed);
        Ok(())
    }

    pub fn stop(&self) -> Result<(), Error> {
        if self.is_stopped.load(Ordering::Relaxed) { return Err(Error::NotStarted) }
        if self.is_stopping.load(Ordering::Relaxed) { return Err(Error::AlreadyStopping)}
        self.is_stopping.store(true, Ordering::Relaxed);
        while !self.is_stopped.load(Ordering::Relaxed) { std::thread::sleep(std::time::Duration::new(0, 10)); }
        Ok(())
    }
}

impl Drop for Server {
    fn drop(&mut self) {
        self.stop().unwrap_or_else(|_| {}); // ignore error - can be stopped already
        ::std::fs::remove_file(&self.addr).unwrap_or_else(|_| {}); // ignoer error - server could have never been started
    }
}

impl RpcServer {

    /// start ipc rpc server (blocking)
    pub fn start(addr: &str, io_handler: &Arc<IoHandler>) -> Result<(RpcServer, EventLoop<RpcServer>), Error> {
        let mut event_loop = try!(EventLoop::new());
        ::std::fs::remove_file(addr).unwrap_or_else(|_| {} ); // ignore error (if no file)
        let socket = try!(UnixListener::bind(&addr));
        event_loop.register(&socket, SERVER, EventSet::readable(), PollOpt::edge()).unwrap();
        let server = RpcServer {
            socket: socket,
            connections: Slab::new_starting_at(Token(1), MAX_CONCURRENT_CONNECTIONS),
            io_handler: io_handler.clone(),
        };
        Ok((server, event_loop))
    }

    fn accept(&mut self, event_loop: &mut EventLoop<RpcServer>) -> io::Result<()> {
        let new_client_socket = self.socket.accept().unwrap().unwrap();
        let connection = SocketConnection::new(new_client_socket);
        if self.connections.count() >= MAX_CONCURRENT_CONNECTIONS {
            let oldest_token = self.connections.iter().nth(0)
                .expect("fatal: impossible since count > MAX_CONCURRENT_CONNECTIONS and we request first one")
                .token.unwrap().clone();
            self.connections.remove(oldest_token);
        }
        let token = self.connections.insert(connection).ok().expect("fatal: Could not add connection to slab (memory issue?)");

        self.connections[token].token = Some(token);
        event_loop.register(
            &self.connections[token].socket,
            token,
            EventSet::readable(),
            PollOpt::edge() | PollOpt::oneshot()
        ).ok().expect("fatal: could not register socket with event loop (memory issue?)");

        Ok(())
    }

    fn connection_readable(&mut self, event_loop: &mut EventLoop<RpcServer>, tok: Token) -> io::Result<()> {
        let io_handler = self.io_handler.clone();
        self.connection(tok).readable(event_loop, &io_handler)
    }

    fn connection_writable(&mut self, event_loop: &mut EventLoop<RpcServer>, tok: Token) -> io::Result<()> {
        let io_handler = self.io_handler.clone();
        self.connection(tok).writable(event_loop, &io_handler)
    }

    fn connection<'a>(&'a mut self, tok: Token) -> &'a mut SocketConnection {
        &mut self.connections[tok]
    }
}

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

    fn ready(&mut self, event_loop: &mut EventLoop<RpcServer>, token: Token, events: EventSet) {
        if events.is_readable() {
            match token {
                SERVER => self.accept(event_loop).unwrap(),
                _ => self.connection_readable(event_loop, token).unwrap()
            };
        }

        if events.is_writable() {
            match token {
                SERVER => { },
                _ => self.connection_writable(event_loop, token).unwrap_or_else(|_| {}), // todo: disqualify connection from list on error
            };
        }
    }
}

#[test]
pub fn test_reqrep_poll() {
    let addr = tests::random_ipc_endpoint();
    let io = tests::dummy_io_handler();
    let server = Server::new(&addr, &io).unwrap();
    std::thread::spawn(move || {
        loop {
            server.poll();
        }
    });

    let request = r#"{"jsonrpc": "2.0", "method": "say_hello", "params": [42, 23], "id": 1}"#;
    let response = r#"{"jsonrpc":"2.0","result":"hello 42! you sent 23","id":1}"#;
    assert_eq!(String::from_utf8(tests::dummy_request(&addr, request.as_bytes())).unwrap(), response.to_string());

    std::thread::sleep(std::time::Duration::from_millis(500));
}

#[test]
pub fn test_file_removed() {
    let addr = tests::random_ipc_endpoint();
    let io = tests::dummy_io_handler();
    {
        let server = Server::new(&addr, &io).unwrap();
        server.run_async().unwrap();
        std::thread::sleep(std::time::Duration::from_millis(50));

        let request = r#"{"jsonrpc": "2.0", "method": "say_hello", "params": [42, 23], "id": 1}"#;
        let response = r#"{"jsonrpc":"2.0","result":"hello 42! you sent 23","id":1}"#;
        assert_eq!(String::from_utf8(tests::dummy_request(&addr, request.as_bytes())).unwrap(), response.to_string());
    }
    assert!(::std::fs::metadata(addr).is_err()); // err is file not exists
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate atty;

use self::super::Size;
use self::libc::{c_ulong, c_ushort, STDOUT_FILENO};
use self::libc::ioctl;

#[cfg(not(target_os = "macos"))]
const TIOCGWINSZ: c_ulong = 0x00005413;

#[cfg(target_os = "macos")]
const TIOCGWINSZ: c_ulong = 0x40087468;

/// A representation of the size of the current terminal
#[repr(C)]
#[derive(Debug)]
pub struct UnixSize {
  /// number of rows
  pub rows: c_ushort,
  /// number of columns
  pub cols: c_ushort,
  x: c_ushort,
  y: c_ushort
}

/// Gets the current terminal size
pub fn get() -> Option<Size> {
    // http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc
    if atty::isnt() {
        return None;
    }
    let us = UnixSize { rows: 0, cols: 0, x: 0, y: 0 };
    let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &us) };
    if r == 0 { Some(Size { rows: us.rows, cols: us.cols }) } else { None }
}
<commit_msg>simple test<commit_after>extern crate libc;
extern crate atty;

use self::super::Size;
use self::libc::{c_ulong, c_ushort, STDOUT_FILENO};
use self::libc::ioctl;

#[cfg(not(target_os = "macos"))]
const TIOCGWINSZ: c_ulong = 0x00005413;

#[cfg(target_os = "macos")]
const TIOCGWINSZ: c_ulong = 0x40087468;

/// A representation of the size of the current terminal
#[repr(C)]
#[derive(Debug)]
pub struct UnixSize {
  /// number of rows
  pub rows: c_ushort,
  /// number of columns
  pub cols: c_ushort,
  x: c_ushort,
  y: c_ushort
}

/// Gets the current terminal size
pub fn get() -> Option<Size> {
    // http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc
    if atty::isnt() {
        return None;
    }
    let us = UnixSize { rows: 0, cols: 0, x: 0, y: 0 };
    let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &us) };
    if r == 0 { Some(Size { rows: us.rows, cols: us.cols }) } else { None }
}

#[cfg(test)]
mod tests {
    use std::process::Command;
    use std::process::Stdio;
    use super::super::Size;
    use super::get;

    #[test]
    #[cfg(target_os = "macos")]
    fn test_shell() {
        let output = Command::new("stty")
            .arg("-f").arg("/dev/stderr")
            .arg("size")
            .stderr(Stdio::inherit())
            .output()
            .unwrap();
        assert!(output.status.success());
        let stdout = String::from_utf8(
             output.stdout
        ).unwrap();
        let mut data = stdout.split_whitespace();
        let rs = data.next().unwrap().parse::<u16>().unwrap();
        let cs = data.next().unwrap().parse::<u16>().unwrap();
        if let Some(Size { rows, cols }) = get() {
            assert_eq!(rows, rs);
            assert_eq!(cols, cs);
        }
    }
}
<|endoftext|>


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

use algebra::{Field, CommutativeRing};

/// A number that can be written without a fractional or decimal component.
///
/// # Handling of Division and Modulus
///
/// The most interesting part of this trait is the support for different
/// interpretations of integer division and modulus for discrete numbers. This
/// topic is discussed in greater depth in Daan Leijen's
/// _[Division and Modulus for Computer Scientists]
/// (http://legacy.cs.uu.nl/daan/download/papers/divmodnote-letter.pdf)_.
trait Integral
    : Eq + Ord
    + CommutativeRing {
    /// Truncated division satisfying:
    ///
    /// ~~~
    /// t_div(a, b) = trunc(a / b)              ∀ a, b ∈ Self where b ≠ 0
    /// ~~~
    ///
    /// This is the form of division adopted by the ISO C99 standard for the `/`
    /// operator, and is usually more efficient than `f_div` due to better
    /// support on processors.
    fn t_div(a: &Self, b: &Self) -> Self;

    /// The remainder after truncated division satisfying:
    ///
    /// ~~~
    /// t_mod(a, b) = a - (b * t_div(a, b))     ∀ a, b ∈ Self where b ≠ 0
    /// ~~~
    ///
    /// This is the form of modulus adopted by the ISO C99 standard for the `%`
    /// operator, and is usually more efficient than `f_mod` due to better
    /// support on processors.
    fn t_mod(a: &Self, b: &Self) -> Self;

    /// Calculates `t_div` and `t_mod` simultaneously.
    fn t_div_mod(a: &Self, b: &Self) -> (Self, Self);

    /// Floored division satisfying:
    ///
    /// ~~~
    /// f_div(a, b) = ⌊a / b⌋                   ∀ a, b ∈ Self where b ≠ 0
    /// ~~~
    fn f_div(a: &Self, b: &Self) -> Self;

    /// The remainder after floored division satisfying:
    ///
    /// ~~~
    /// f_mod(a, b) = a - (b * f_div(a, b))     ∀ a, b where b ≠ 0
    /// ~~~
    fn f_mod(a: &Self, b: &Self) -> Self;

    /// Calculates `f_div` and `f_mod` simultaneously.
    fn f_div_mod(a: &Self, b: &Self) -> (Self, Self);

    /// Greatest Common Divisor (GCD)
    fn gcd(a: &Self, b: &Self) -> Self;

    /// Lowest Common Multiple (LCM)
    fn lcm(a: &Self, b: &Self) -> Self;
}

#[inline]
pub fn t_div<T: Integral>(a: &T, b: &T) -> T {
    Integral::t_div(a, b)
}

#[inline]
pub fn t_mod<T: Integral>(a: &T, b: &T) -> T {
    Integral::t_mod(a, b)
}

#[inline]
pub fn t_div_mod<T: Integral>(a: &T, b: &T) -> (T, T) {
    Integral::t_div_mod(a, b)
}

#[inline]
pub fn f_div<T: Integral>(a: &T, b: &T) -> T {
    Integral::f_div(a, b)
}

#[inline]
pub fn f_mod<T: Integral>(a: &T, b: &T) -> T {
    Integral::f_mod(a, b)
}

#[inline]
pub fn f_div_mod<T: Integral>(a: &T, b: &T) -> (T, T) {
    Integral::f_div_mod(a, b)
}

trait Real
    : PartialOrd
    + Field {
}

impl Real for f32  {}
impl Real for f64  {}
<commit_msg>Update Integer<commit_after>// Copyright 2013 The Num-rs Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::num::{zero, one};

use algebra::{Field, CommutativeRing};

/// A number that can be written without a fractional or decimal component.
///
/// # Handling of Division and Modulus
///
/// The most interesting part of this trait is the support for different
/// interpretations of integer division and modulus for discrete numbers. This
/// topic is discussed in greater depth in Daan Leijen's
/// _[Division and Modulus for Computer Scientists]
/// (http://legacy.cs.uu.nl/daan/download/papers/divmodnote-letter.pdf)_.
trait Integer
    : Eq + Ord
    + CommutativeRing {
    #[inline]
    fn succ(&self) -> Self { *self + one() }

    /// Truncated division satisfying:
    ///
    /// ~~~
    /// t_div(a, b) = trunc(a / b)              ∀ a, b ∈ Self where b ≠ 0
    /// ~~~
    ///
    /// This is the form of division adopted by the ISO C99 standard for the `/`
    /// operator, and is usually more efficient than `f_div` due to better
    /// support on processors.
    fn t_div(a: &Self, b: &Self) -> Self;

    /// The remainder after truncated division satisfying:
    ///
    /// ~~~
    /// t_mod(a, b) = a - (b * t_div(a, b))     ∀ a, b ∈ Self where b ≠ 0
    /// ~~~
    ///
    /// This is the form of modulus adopted by the ISO C99 standard for the `%`
    /// operator, and is usually more efficient than `f_mod` due to better
    /// support on processors.
    fn t_mod(a: &Self, b: &Self) -> Self;

    /// Calculates `t_div` and `t_mod` simultaneously.
    #[inline]
    fn t_div_mod(a: &Self, b: &Self) -> (Self, Self) {
        (t_div(a, b), t_mod(a, b))
    }

    /// Floored division satisfying:
    ///
    /// ~~~
    /// f_div(a, b) = ⌊a / b⌋                   ∀ a, b ∈ Self where b ≠ 0
    /// ~~~
    fn f_div(a: &Self, b: &Self) -> Self;

    /// The remainder after floored division satisfying:
    ///
    /// ~~~
    /// f_mod(a, b) = a - (b * f_div(a, b))     ∀ a, b where b ≠ 0
    /// ~~~
    fn f_mod(a: &Self, b: &Self) -> Self;

    /// Calculates `f_div` and `f_mod` simultaneously.
    #[inline]
    fn f_div_mod(a: &Self, b: &Self) -> (Self, Self) {
        (f_div(a, b), f_mod(a, b))
    }

    /// Greatest Common Divisor (GCD)
    fn gcd(a: &Self, b: &Self) -> Self;

    /// Lowest Common Multiple (LCM)
    fn lcm(a: &Self, b: &Self) -> Self;
}

pub trait ModularInteger
    : Integer {
    fn min_value() -> Self;
    fn max_value() -> Self;
    fn congruent(x: &Self, y: &Self) -> bool;
    #[inline]
    fn pred(&self) -> Self { *self - one() }
}

#[inline]
pub fn t_div<T: Integer>(a: &T, b: &T) -> T {
    Integer::t_div(a, b)
}

#[inline]
pub fn t_mod<T: Integer>(a: &T, b: &T) -> T {
    Integer::t_mod(a, b)
}

#[inline]
pub fn t_div_mod<T: Integer>(a: &T, b: &T) -> (T, T) {
    Integer::t_div_mod(a, b)
}

#[inline]
pub fn f_div<T: Integer>(a: &T, b: &T) -> T {
    Integer::f_div(a, b)
}

#[inline]
pub fn f_mod<T: Integer>(a: &T, b: &T) -> T {
    Integer::f_mod(a, b)
}

#[inline]
pub fn f_div_mod<T: Integer>(a: &T, b: &T) -> (T, T) {
    Integer::f_div_mod(a, b)
}

trait Real
    : PartialOrd
    + Field {
}

impl Real for f32  {}
impl Real for f64  {}
<|endoftext|>