<commit_before>use core::ops;
use vmx;
use cpu;
use core::sync::atomic::{AtomicUsize, AtomicBool, ATOMIC_BOOL_INIT, Ordering};

lazy_static! {
    static ref CLI_COUNT: cpu::PerCoreVariable<AtomicUsize> = Default::default();
}

pub fn are_interrupts_enabled() -> bool {
    (vmx::read_flags() & 0x200) != 0
}

#[cfg(not(test))]
pub fn cli() {
    unsafe {
        asm!("cli" : : :);
    }
}

#[cfg(test)]
pub fn cli() {}

#[cfg(not(test))]
pub fn sti() {
    unsafe {
        asm!("sti" : : :);
    }
}

#[cfg(test)]
pub fn sti() {}

#[derive(Default)]
pub struct ClearLocalInterrupts<T> {
    guarded: T,
}

pub struct ClearLocalInterruptsGuard<'a, T: 'a> {
    guarded: &'a T,
    acquired: AtomicBool,
}

pub struct ClearLocalInterruptsGuardMut<'a, T: 'a> {
    guarded: &'a mut T,
    acquired: AtomicBool,
}

impl<T> ClearLocalInterrupts<T> {
    pub fn new(guarded: T) -> Self {
        ClearLocalInterrupts { guarded: guarded }
    }

    pub fn cli_mut(&mut self) -> ClearLocalInterruptsGuardMut<T> {
        ClearLocalInterruptsGuardMut {
            guarded: &mut self.guarded,
            acquired: ATOMIC_BOOL_INIT,
        }
    }

    pub fn cli(&self) -> ClearLocalInterruptsGuard<T> {
        ClearLocalInterruptsGuard {
            guarded: &self.guarded,
            acquired: ATOMIC_BOOL_INIT,
        }
    }
}

impl<'a, T> ops::Deref for ClearLocalInterruptsGuard<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        if !self.acquired.compare_and_swap(false, true, Ordering::AcqRel) {
            if CLI_COUNT.get().fetch_add(1, Ordering::AcqRel) == 0 {
                cli();
            }
        }
        self.guarded
    }
}

impl<'a, T> ops::Deref for ClearLocalInterruptsGuardMut<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        if !self.acquired.compare_and_swap(false, true, Ordering::AcqRel) {
            if CLI_COUNT.get().fetch_add(1, Ordering::AcqRel) == 0 {
                cli();
            }
        }
        self.guarded
    }
}

impl<'a, T> ops::DerefMut for ClearLocalInterruptsGuardMut<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        if !self.acquired.compare_and_swap(false, true, Ordering::AcqRel) {
            if CLI_COUNT.get().fetch_add(1, Ordering::AcqRel) == 0 {
                cli();
            }
        }
        self.guarded
    }
}

impl<'a, T> Drop for ClearLocalInterruptsGuard<'a, T> {
    fn drop(&mut self) {
        if CLI_COUNT.get().fetch_sub(1, Ordering::AcqRel) == 1 {
            sti();
        }
    }
}

impl<'a, T> Drop for ClearLocalInterruptsGuardMut<'a, T> {
    fn drop(&mut self) {
        if CLI_COUNT.get().fetch_sub(1, Ordering::AcqRel) == 1 {
            sti();
        }
    }
}

#[cfg(feature = "runtime_tests")]
pub mod runtime_tests {
    use super::are_interrupts_enabled;
    use super::ClearLocalInterrupts;

    struct Guardee {
        data: u16,
    }

    lazy_static! {
        static ref STATIC_GUARDEE: ClearLocalInterrupts<Guardee> =
            ClearLocalInterrupts::new(Guardee { data: 0 });
    }

    impl Guardee {
        fn do_work(&self) {}
    }

    pub fn run() {
        info!("Running CLI tests...");
        test_clear_local_interrupts_guard_borrow();
        test_clear_local_interrupts_guard_mut_borrow();
        test_clear_local_interrupts_guard_static_borrow();
        info!("CLI tests succeeded");
    }

    fn test_clear_local_interrupts_guard_mut_borrow() {
        assert!(are_interrupts_enabled());
        {
            let mut g: ClearLocalInterrupts<Guardee> =
                ClearLocalInterrupts::new(Guardee { data: 0 });
            assert!(are_interrupts_enabled());
            g.cli_mut().data += 1;
            assert!(are_interrupts_enabled());
            assert_eq!(g.cli().data, 1);
            assert!(are_interrupts_enabled());
        }
        assert!(are_interrupts_enabled());
    }

    fn test_clear_local_interrupts_guard_borrow() {
        assert!(are_interrupts_enabled());
        {
            let g: ClearLocalInterrupts<Guardee> = ClearLocalInterrupts::new(Guardee { data: 0 });
            assert!(are_interrupts_enabled());
            let borrowed = g.cli();
            assert!(are_interrupts_enabled());
            borrowed.do_work();
            assert!(!are_interrupts_enabled());
        }
        assert!(are_interrupts_enabled());
    }

    fn test_clear_local_interrupts_guard_static_borrow() {
        assert!(are_interrupts_enabled());
        {
            assert!(are_interrupts_enabled());
            STATIC_GUARDEE.cli().do_work();
            assert!(are_interrupts_enabled());
            assert_eq!(STATIC_GUARDEE.cli().data, 0);
            assert!(are_interrupts_enabled());
        }
        assert!(are_interrupts_enabled());
    }
}
<commit_msg>Cargo clippy<commit_after>use core::ops;
use vmx;
use cpu;
use core::sync::atomic::{AtomicUsize, AtomicBool, ATOMIC_BOOL_INIT, Ordering};

lazy_static! {
    static ref CLI_COUNT: cpu::PerCoreVariable<AtomicUsize> = Default::default();
}

pub fn are_interrupts_enabled() -> bool {
    (vmx::read_flags() & 0x200) != 0
}

#[cfg(not(test))]
pub fn cli() {
    unsafe {
        asm!("cli" : : :);
    }
}

#[cfg(test)]
pub fn cli() {}

#[cfg(not(test))]
pub fn sti() {
    unsafe {
        asm!("sti" : : :);
    }
}

#[cfg(test)]
pub fn sti() {}

#[derive(Default)]
pub struct ClearLocalInterrupts<T> {
    guarded: T,
}

pub struct ClearLocalInterruptsGuard<'a, T: 'a> {
    guarded: &'a T,
    acquired: AtomicBool,
}

pub struct ClearLocalInterruptsGuardMut<'a, T: 'a> {
    guarded: &'a mut T,
    acquired: AtomicBool,
}

impl<T> ClearLocalInterrupts<T> {
    pub fn new(guarded: T) -> Self {
        ClearLocalInterrupts { guarded: guarded }
    }

    pub fn cli_mut(&mut self) -> ClearLocalInterruptsGuardMut<T> {
        ClearLocalInterruptsGuardMut {
            guarded: &mut self.guarded,
            acquired: ATOMIC_BOOL_INIT,
        }
    }

    pub fn cli(&self) -> ClearLocalInterruptsGuard<T> {
        ClearLocalInterruptsGuard {
            guarded: &self.guarded,
            acquired: ATOMIC_BOOL_INIT,
        }
    }
}

impl<'a, T> ops::Deref for ClearLocalInterruptsGuard<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        if !self.acquired.compare_and_swap(false, true, Ordering::AcqRel) &&
            CLI_COUNT.get().fetch_add(1, Ordering::AcqRel) == 0 {
            cli();
        }
        self.guarded
    }
}

impl<'a, T> ops::Deref for ClearLocalInterruptsGuardMut<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        if !self.acquired.compare_and_swap(false, true, Ordering::AcqRel) &&
            CLI_COUNT.get().fetch_add(1, Ordering::AcqRel) == 0 {
            cli();
        }
        self.guarded
    }
}

impl<'a, T> ops::DerefMut for ClearLocalInterruptsGuardMut<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        if !self.acquired.compare_and_swap(false, true, Ordering::AcqRel) &&
            CLI_COUNT.get().fetch_add(1, Ordering::AcqRel) == 0 {
            cli();
        }
        self.guarded
    }
}

impl<'a, T> Drop for ClearLocalInterruptsGuard<'a, T> {
    fn drop(&mut self) {
        if CLI_COUNT.get().fetch_sub(1, Ordering::AcqRel) == 1 {
            sti();
        }
    }
}

impl<'a, T> Drop for ClearLocalInterruptsGuardMut<'a, T> {
    fn drop(&mut self) {
        if CLI_COUNT.get().fetch_sub(1, Ordering::AcqRel) == 1 {
            sti();
        }
    }
}

#[cfg(feature = "runtime_tests")]
pub mod runtime_tests {
    use super::are_interrupts_enabled;
    use super::ClearLocalInterrupts;

    struct Guardee {
        data: u16,
    }

    lazy_static! {
        static ref STATIC_GUARDEE: ClearLocalInterrupts<Guardee> =
            ClearLocalInterrupts::new(Guardee { data: 0 });
    }

    impl Guardee {
        fn do_work(&self) {}
    }

    pub fn run() {
        info!("Running CLI tests...");
        test_clear_local_interrupts_guard_borrow();
        test_clear_local_interrupts_guard_mut_borrow();
        test_clear_local_interrupts_guard_static_borrow();
        info!("CLI tests succeeded");
    }

    fn test_clear_local_interrupts_guard_mut_borrow() {
        assert!(are_interrupts_enabled());
        {
            let mut g: ClearLocalInterrupts<Guardee> =
                ClearLocalInterrupts::new(Guardee { data: 0 });
            assert!(are_interrupts_enabled());
            g.cli_mut().data += 1;
            assert!(are_interrupts_enabled());
            assert_eq!(g.cli().data, 1);
            assert!(are_interrupts_enabled());
        }
        assert!(are_interrupts_enabled());
    }

    fn test_clear_local_interrupts_guard_borrow() {
        assert!(are_interrupts_enabled());
        {
            let g: ClearLocalInterrupts<Guardee> = ClearLocalInterrupts::new(Guardee { data: 0 });
            assert!(are_interrupts_enabled());
            let borrowed = g.cli();
            assert!(are_interrupts_enabled());
            borrowed.do_work();
            assert!(!are_interrupts_enabled());
        }
        assert!(are_interrupts_enabled());
    }

    fn test_clear_local_interrupts_guard_static_borrow() {
        assert!(are_interrupts_enabled());
        {
            assert!(are_interrupts_enabled());
            STATIC_GUARDEE.cli().do_work();
            assert!(are_interrupts_enabled());
            assert_eq!(STATIC_GUARDEE.cli().data, 0);
            assert!(are_interrupts_enabled());
        }
        assert!(are_interrupts_enabled());
    }
}
<|endoftext|>


<commit_before>//! Essentials helper functions and types for application registration.
use actix_http::http::Method;
use actix_router::IntoPattern;
use futures::Future;

pub use actix_http::Response as HttpResponse;
pub use bytes::{Bytes, BytesMut};
pub use futures::channel::oneshot::Canceled;

use crate::error::BlockingError;
use crate::extract::FromRequest;
use crate::handler::Factory;
use crate::resource::Resource;
use crate::responder::Responder;
use crate::route::Route;
use crate::scope::Scope;
use crate::service::WebService;

pub use crate::config::ServiceConfig;
pub use crate::data::Data;
pub use crate::request::HttpRequest;
pub use crate::types::*;

/// Create resource for a specific path.
///
/// Resources may have variable path segments. For example, a
/// resource with the path `/a/{name}/c` would match all incoming
/// requests with paths such as `/a/b/c`, `/a/1/c`, or `/a/etc/c`.
///
/// A variable segment is specified in the form `{identifier}`,
/// where the identifier can be used later in a request handler to
/// access the matched value for that segment. This is done by
/// looking up the identifier in the `Params` object returned by
/// `HttpRequest.match_info()` method.
///
/// By default, each segment matches the regular expression `[^{}/]+`.
///
/// You can also specify a custom regex in the form `{identifier:regex}`:
///
/// For instance, to route `GET`-requests on any route matching
/// `/users/{userid}/{friend}` and store `userid` and `friend` in
/// the exposed `Params` object:
///
/// ```rust
/// # extern crate actix_web;
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/users/{userid}/{friend}")
///         .route(web::get().to(|| HttpResponse::Ok()))
///         .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
/// );
/// ```
pub fn resource<T: IntoPattern>(path: T) -> Resource {
    Resource::new(path)
}

/// Configure scope for common root path.
///
/// Scopes collect multiple paths under a common path prefix.
/// Scope path can contain variable path segments as resources.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::scope("/{project_id}")
///         .service(web::resource("/path1").to(|| HttpResponse::Ok()))
///         .service(web::resource("/path2").to(|| HttpResponse::Ok()))
///         .service(web::resource("/path3").to(|| HttpResponse::MethodNotAllowed()))
/// );
/// ```
///
/// In the above example, three routes get added:
///  * /{project_id}/path1
///  * /{project_id}/path2
///  * /{project_id}/path3
///
pub fn scope(path: &str) -> Scope {
    Scope::new(path)
}

/// Create *route* without configuration.
pub fn route() -> Route {
    Route::new()
}

/// Create *route* with `GET` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///        .route(web::get().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `GET` route gets added:
///  * /{project_id}
///
pub fn get() -> Route {
    method(Method::GET)
}

/// Create *route* with `POST` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::post().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `POST` route gets added:
///  * /{project_id}
///
pub fn post() -> Route {
    method(Method::POST)
}

/// Create *route* with `PUT` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::put().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `PUT` route gets added:
///  * /{project_id}
///
pub fn put() -> Route {
    method(Method::PUT)
}

/// Create *route* with `PATCH` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::patch().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `PATCH` route gets added:
///  * /{project_id}
///
pub fn patch() -> Route {
    method(Method::PATCH)
}

/// Create *route* with `DELETE` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::delete().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `DELETE` route gets added:
///  * /{project_id}
///
pub fn delete() -> Route {
    method(Method::DELETE)
}

/// Create *route* with `HEAD` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::head().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `HEAD` route gets added:
///  * /{project_id}
///
pub fn head() -> Route {
    method(Method::HEAD)
}

/// Create *route* and add method guard.
///
/// ```rust
/// use actix_web::{web, http, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::method(http::Method::GET).to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `GET` route gets added:
///  * /{project_id}
///
pub fn method(method: Method) -> Route {
    Route::new().method(method)
}

/// Create a new route and add handler.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse, Responder};
///
/// async fn index() -> impl Responder {
///    HttpResponse::Ok()
/// }
///
/// App::new().service(
///     web::resource("/").route(
///         web::to(index))
/// );
/// ```
pub fn to<F, I, R, U>(handler: F) -> Route
where
    F: Factory<I, R, U>,
    I: FromRequest + 'static,
    R: Future<Output = U> + 'static,
    U: Responder + 'static,
{
    Route::new().to(handler)
}

/// Create raw service for a specific path.
///
/// ```rust
/// use actix_web::{dev, web, guard, App, Error, HttpResponse};
///
/// async fn my_service(req: dev::ServiceRequest) -> Result<dev::ServiceResponse, Error> {
///     Ok(req.into_response(HttpResponse::Ok().finish()))
/// }
///
/// let app = App::new().service(
///     web::service("/users/*")
///         .guard(guard::Header("content-type", "text/plain"))
///         .finish(my_service)
/// );
/// ```
pub fn service<T: IntoPattern>(path: T) -> WebService {
    WebService::new(path)
}

/// Execute blocking function on a thread pool, returns future that resolves
/// to result of the function execution.
pub async fn block<F, I, E>(f: F) -> Result<I, BlockingError<E>>
where
    F: FnOnce() -> Result<I, E> + Send + 'static,
    I: Send + 'static,
    E: Send + std::fmt::Debug + 'static,
{
    actix_threadpool::run(f).await
}
<commit_msg>Create helper function for HTTP Trace Method<commit_after>//! Essentials helper functions and types for application registration.
use actix_http::http::Method;
use actix_router::IntoPattern;
use futures::Future;

pub use actix_http::Response as HttpResponse;
pub use bytes::{Bytes, BytesMut};
pub use futures::channel::oneshot::Canceled;

use crate::error::BlockingError;
use crate::extract::FromRequest;
use crate::handler::Factory;
use crate::resource::Resource;
use crate::responder::Responder;
use crate::route::Route;
use crate::scope::Scope;
use crate::service::WebService;

pub use crate::config::ServiceConfig;
pub use crate::data::Data;
pub use crate::request::HttpRequest;
pub use crate::types::*;

/// Create resource for a specific path.
///
/// Resources may have variable path segments. For example, a
/// resource with the path `/a/{name}/c` would match all incoming
/// requests with paths such as `/a/b/c`, `/a/1/c`, or `/a/etc/c`.
///
/// A variable segment is specified in the form `{identifier}`,
/// where the identifier can be used later in a request handler to
/// access the matched value for that segment. This is done by
/// looking up the identifier in the `Params` object returned by
/// `HttpRequest.match_info()` method.
///
/// By default, each segment matches the regular expression `[^{}/]+`.
///
/// You can also specify a custom regex in the form `{identifier:regex}`:
///
/// For instance, to route `GET`-requests on any route matching
/// `/users/{userid}/{friend}` and store `userid` and `friend` in
/// the exposed `Params` object:
///
/// ```rust
/// # extern crate actix_web;
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/users/{userid}/{friend}")
///         .route(web::get().to(|| HttpResponse::Ok()))
///         .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
/// );
/// ```
pub fn resource<T: IntoPattern>(path: T) -> Resource {
    Resource::new(path)
}

/// Configure scope for common root path.
///
/// Scopes collect multiple paths under a common path prefix.
/// Scope path can contain variable path segments as resources.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::scope("/{project_id}")
///         .service(web::resource("/path1").to(|| HttpResponse::Ok()))
///         .service(web::resource("/path2").to(|| HttpResponse::Ok()))
///         .service(web::resource("/path3").to(|| HttpResponse::MethodNotAllowed()))
/// );
/// ```
///
/// In the above example, three routes get added:
///  * /{project_id}/path1
///  * /{project_id}/path2
///  * /{project_id}/path3
///
pub fn scope(path: &str) -> Scope {
    Scope::new(path)
}

/// Create *route* without configuration.
pub fn route() -> Route {
    Route::new()
}

/// Create *route* with `GET` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///        .route(web::get().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `GET` route gets added:
///  * /{project_id}
///
pub fn get() -> Route {
    method(Method::GET)
}

/// Create *route* with `POST` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::post().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `POST` route gets added:
///  * /{project_id}
///
pub fn post() -> Route {
    method(Method::POST)
}

/// Create *route* with `PUT` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::put().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `PUT` route gets added:
///  * /{project_id}
///
pub fn put() -> Route {
    method(Method::PUT)
}

/// Create *route* with `PATCH` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::patch().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `PATCH` route gets added:
///  * /{project_id}
///
pub fn patch() -> Route {
    method(Method::PATCH)
}

/// Create *route* with `DELETE` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::delete().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `DELETE` route gets added:
///  * /{project_id}
///
pub fn delete() -> Route {
    method(Method::DELETE)
}

/// Create *route* with `HEAD` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::head().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `HEAD` route gets added:
///  * /{project_id}
///
pub fn head() -> Route {
    method(Method::HEAD)
}

/// Create *route* with `TRACE` method guard.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::trace().to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `HEAD` route gets added:
///  * /{project_id}
///
pub fn trace() -> Route {
    method(Method::TRACE)
}

/// Create *route* and add method guard.
///
/// ```rust
/// use actix_web::{web, http, App, HttpResponse};
///
/// let app = App::new().service(
///     web::resource("/{project_id}")
///         .route(web::method(http::Method::GET).to(|| HttpResponse::Ok()))
/// );
/// ```
///
/// In the above example, one `GET` route gets added:
///  * /{project_id}
///
pub fn method(method: Method) -> Route {
    Route::new().method(method)
}

/// Create a new route and add handler.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse, Responder};
///
/// async fn index() -> impl Responder {
///    HttpResponse::Ok()
/// }
///
/// App::new().service(
///     web::resource("/").route(
///         web::to(index))
/// );
/// ```
pub fn to<F, I, R, U>(handler: F) -> Route
where
    F: Factory<I, R, U>,
    I: FromRequest + 'static,
    R: Future<Output = U> + 'static,
    U: Responder + 'static,
{
    Route::new().to(handler)
}

/// Create raw service for a specific path.
///
/// ```rust
/// use actix_web::{dev, web, guard, App, Error, HttpResponse};
///
/// async fn my_service(req: dev::ServiceRequest) -> Result<dev::ServiceResponse, Error> {
///     Ok(req.into_response(HttpResponse::Ok().finish()))
/// }
///
/// let app = App::new().service(
///     web::service("/users/*")
///         .guard(guard::Header("content-type", "text/plain"))
///         .finish(my_service)
/// );
/// ```
pub fn service<T: IntoPattern>(path: T) -> WebService {
    WebService::new(path)
}

/// Execute blocking function on a thread pool, returns future that resolves
/// to result of the function execution.
pub async fn block<F, I, E>(f: F) -> Result<I, BlockingError<E>>
where
    F: FnOnce() -> Result<I, E> + Send + 'static,
    I: Send + 'static,
    E: Send + std::fmt::Debug + 'static,
{
    actix_threadpool::run(f).await
}
<|endoftext|>


<commit_before>use super::Columns;

use std::f64::consts::{PI, SQRT_2};
use std::ops::{Index, IndexMut, Range};

struct ColumnsMut<'a, T: 'a> {
    data: &'a mut [T],
    rowstride: usize,
    curr: usize,
}

impl<'a, T: 'a> ColumnsMut<'a, T> {
    #[inline(always)]
    fn from_slice(data: &'a mut [T], rowstride: usize) -> Self {
        ColumnsMut {
            data: data,
            rowstride: rowstride,
            curr: 0,
        }
    }
}

impl<'a, T: 'a> Iterator for ColumnsMut<'a, T> {
    type Item = ColumnMut<'a, T>;
    #[inline(always)]
    fn next(&mut self) -> Option<Self::Item> {
        if self.curr < self.rowstride {
           let data = unsafe { &mut *(&mut self.data[self.curr..] as *mut [T]) };
            self.curr += 1;
            Some(ColumnMut {
                data: data,
                rowstride: self.rowstride,
            })
        } else {
            None
        }
    }
}

struct ColumnMut<'a, T: 'a> {
    data: &'a mut [T],
    rowstride: usize,
}

impl<'a, T: 'a> Index<usize> for ColumnMut<'a, T> {
    type Output = T;
    #[inline(always)]
    fn index(&self, idx: usize) -> &T {
       &self.data[idx * self.rowstride]
    }
}

impl<'a, T: 'a> IndexMut<usize> for ColumnMut<'a, T> {
    #[inline(always)]
    fn index_mut(&mut self, idx: usize) -> &mut T {
       &mut self.data[idx * self.rowstride]
    }
}

pub fn dct_1d<I: Index<usize, Output=f64> + ?Sized, O: IndexMut<usize, Output=f64> + ?Sized>(input: &I, output: &mut O, len: usize) {
    for i in 0 .. len {
        let mut z = 0.0;

        for j in 0 .. len {
            z += input[j] * (
                PI * i as f64 * (2 * j + 1) as f64
                / (2 * len) as f64
            ).cos();
        }

        if i == 0 {
            z *= 1.0 / SQRT_2;
        }

        output[i] = z / 2.0;
    }
}

/// Perform a 2D DCT on a 1D-packed vector with a given rowstride.
///
/// E.g. a vector of length 9 with a rowstride of 3 will be processed as a 3x3 matrix.
///
/// Returns a vector of the same size packed in the same way.
pub fn dct_2d(packed_2d: &[f64], rowstride: usize) -> Vec<f64> {
    assert_eq!(packed_2d.len() % rowstride, 0);

    let mut scratch = Vec::with_capacity(packed_2d.len() * 2);
    unsafe { scratch.set_len(packed_2d.len() * 2); }

    {
        let (col_pass, row_pass) = scratch.split_at_mut(packed_2d.len());

        for (row_in, row_out) in packed_2d.chunks(rowstride)
                .zip(row_pass.chunks_mut(rowstride)) {
            dct_1d(row_in, row_out, rowstride);
        }

        for (col_in, mut col_out) in Columns::from_slice(row_pass, rowstride)
                .zip(ColumnsMut::from_slice(col_pass, rowstride)) {
            dct_1d(&col_in, &mut col_out, rowstride);
        }
    }

    scratch.truncate(packed_2d.len());
    scratch
}

/*
#[cfg(feature = "simd")]
mod dct_simd {
    use simdty::f64x2;

    use std::f64::consts::{PI, SQRT_2};

    macro_rules! valx2 ( ($val:expr) => ( ::simdty::f64x2($val, $val) ) );

    const PI: f64x2 = valx2!(PI);
    const ONE_DIV_SQRT_2: f64x2 = valx2!(1 / SQRT_2);
    const SQRT_2: f64x2 = valx2!(SQRT_2);

    pub dct_rows(vals: &[Vec<f64>]) -> Vec<Vec<f64>> {
        let mut out = Vec::with_capacity(vals.len());

        for pair in vals.iter().chunks(2) {
            if pair.len() == 2 {
                let vals = pair[0].iter().cloned().zip(pair[1].iter().cloned())
                    .map(f64x2)
                    .collect();

                dct_1dx2(vals);

        }
    }

    fn dct_1dx2(vec: Vec<f64x2>) -> Vec<f64x2> {
        let mut out = Vec::with_capacity(vec.len());

        for u in 0 .. vec.len() {
            let mut z = valx2!(0.0);

            for x in 0 .. vec.len() {
                z += vec[x] * cos_approx(
                    PI * valx2!(
                        u as f64 * (2 * x + 1) as f64
                            / (2 * vec.len()) as f64
                    )
                );
            }

            if u == 0 {
                z *= ONE_DIV_SQRT_2;
            }

            out.insert(u, z / valx2!(2.0));
        }

        out
    }

    fn cos_approx(x2: f64x2) -> f64x2 {
        #[inline(always)]
        fn powi(val: f64x2, pow: i32) -> f64x2 {
            unsafe { llvmint::powi_v2f64(val, pow) }
        }

        let x2 = powi(val, 2);
        let x4 = powi(val, 4);
        let x6 = powi(val, 6);
        let x8 = powi(val, 8);

        valx2!(1.0) - (x2 / valx2!(2.0)) + (x4 / valx2!(24.0))
            - (x6 / valx2!(720.0)) + (x8 / valx2!(40320.0))
    }
}
*/

<commit_msg>Remove unused import from dct.rs<commit_after>use super::Columns;

use std::f64::consts::{PI, SQRT_2};
use std::ops::{Index, IndexMut};

struct ColumnsMut<'a, T: 'a> {
    data: &'a mut [T],
    rowstride: usize,
    curr: usize,
}

impl<'a, T: 'a> ColumnsMut<'a, T> {
    #[inline(always)]
    fn from_slice(data: &'a mut [T], rowstride: usize) -> Self {
        ColumnsMut {
            data: data,
            rowstride: rowstride,
            curr: 0,
        }
    }
}

impl<'a, T: 'a> Iterator for ColumnsMut<'a, T> {
    type Item = ColumnMut<'a, T>;
    #[inline(always)]
    fn next(&mut self) -> Option<Self::Item> {
        if self.curr < self.rowstride {
           let data = unsafe { &mut *(&mut self.data[self.curr..] as *mut [T]) };
            self.curr += 1;
            Some(ColumnMut {
                data: data,
                rowstride: self.rowstride,
            })
        } else {
            None
        }
    }
}

struct ColumnMut<'a, T: 'a> {
    data: &'a mut [T],
    rowstride: usize,
}

impl<'a, T: 'a> Index<usize> for ColumnMut<'a, T> {
    type Output = T;
    #[inline(always)]
    fn index(&self, idx: usize) -> &T {
       &self.data[idx * self.rowstride]
    }
}

impl<'a, T: 'a> IndexMut<usize> for ColumnMut<'a, T> {
    #[inline(always)]
    fn index_mut(&mut self, idx: usize) -> &mut T {
       &mut self.data[idx * self.rowstride]
    }
}

pub fn dct_1d<I: Index<usize, Output=f64> + ?Sized, O: IndexMut<usize, Output=f64> + ?Sized>(input: &I, output: &mut O, len: usize) {
    for i in 0 .. len {
        let mut z = 0.0;

        for j in 0 .. len {
            z += input[j] * (
                PI * i as f64 * (2 * j + 1) as f64
                / (2 * len) as f64
            ).cos();
        }

        if i == 0 {
            z *= 1.0 / SQRT_2;
        }

        output[i] = z / 2.0;
    }
}

/// Perform a 2D DCT on a 1D-packed vector with a given rowstride.
///
/// E.g. a vector of length 9 with a rowstride of 3 will be processed as a 3x3 matrix.
///
/// Returns a vector of the same size packed in the same way.
pub fn dct_2d(packed_2d: &[f64], rowstride: usize) -> Vec<f64> {
    assert_eq!(packed_2d.len() % rowstride, 0);

    let mut scratch = Vec::with_capacity(packed_2d.len() * 2);
    unsafe { scratch.set_len(packed_2d.len() * 2); }

    {
        let (col_pass, row_pass) = scratch.split_at_mut(packed_2d.len());

        for (row_in, row_out) in packed_2d.chunks(rowstride)
                .zip(row_pass.chunks_mut(rowstride)) {
            dct_1d(row_in, row_out, rowstride);
        }

        for (col_in, mut col_out) in Columns::from_slice(row_pass, rowstride)
                .zip(ColumnsMut::from_slice(col_pass, rowstride)) {
            dct_1d(&col_in, &mut col_out, rowstride);
        }
    }

    scratch.truncate(packed_2d.len());
    scratch
}

/*
#[cfg(feature = "simd")]
mod dct_simd {
    use simdty::f64x2;

    use std::f64::consts::{PI, SQRT_2};

    macro_rules! valx2 ( ($val:expr) => ( ::simdty::f64x2($val, $val) ) );

    const PI: f64x2 = valx2!(PI);
    const ONE_DIV_SQRT_2: f64x2 = valx2!(1 / SQRT_2);
    const SQRT_2: f64x2 = valx2!(SQRT_2);

    pub dct_rows(vals: &[Vec<f64>]) -> Vec<Vec<f64>> {
        let mut out = Vec::with_capacity(vals.len());

        for pair in vals.iter().chunks(2) {
            if pair.len() == 2 {
                let vals = pair[0].iter().cloned().zip(pair[1].iter().cloned())
                    .map(f64x2)
                    .collect();

                dct_1dx2(vals);

        }
    }

    fn dct_1dx2(vec: Vec<f64x2>) -> Vec<f64x2> {
        let mut out = Vec::with_capacity(vec.len());

        for u in 0 .. vec.len() {
            let mut z = valx2!(0.0);

            for x in 0 .. vec.len() {
                z += vec[x] * cos_approx(
                    PI * valx2!(
                        u as f64 * (2 * x + 1) as f64
                            / (2 * vec.len()) as f64
                    )
                );
            }

            if u == 0 {
                z *= ONE_DIV_SQRT_2;
            }

            out.insert(u, z / valx2!(2.0));
        }

        out
    }

    fn cos_approx(x2: f64x2) -> f64x2 {
        #[inline(always)]
        fn powi(val: f64x2, pow: i32) -> f64x2 {
            unsafe { llvmint::powi_v2f64(val, pow) }
        }

        let x2 = powi(val, 2);
        let x4 = powi(val, 4);
        let x6 = powi(val, 6);
        let x8 = powi(val, 8);

        valx2!(1.0) - (x2 / valx2!(2.0)) + (x4 / valx2!(24.0))
            - (x6 / valx2!(720.0)) + (x8 / valx2!(40320.0))
    }
}
*/

<|endoftext|>


<commit_before>use super::ToTokens;

use proc_macro2::{TokenStream, TokenTree};

/// TokenStream extension trait with methods for appending tokens.
///
/// This trait is sealed and cannot be implemented outside of the `quote` crate.
pub trait TokenStreamExt: private::Sealed {
    fn append<U>(&mut self, token: U)
    where
        U: Into<TokenTree>;

    fn append_all<T, I>(&mut self, iter: I)
    where
        T: ToTokens,
        I: IntoIterator<Item = T>;

    fn append_separated<T, I, U>(&mut self, iter: I, op: U)
    where
        T: ToTokens,
        I: IntoIterator<Item = T>,
        U: ToTokens;

    fn append_terminated<T, I, U>(&mut self, iter: I, term: U)
    where
        T: ToTokens,
        I: IntoIterator<Item = T>,
        U: ToTokens;
}

impl TokenStreamExt for TokenStream {
    /// For use by `ToTokens` implementations.
    ///
    /// Appends the token specified to this list of tokens.
    fn append<U>(&mut self, token: U)
    where
        U: Into<TokenTree>,
    {
        self.extend(Some(token.into()));
    }

    /// For use by `ToTokens` implementations.
    ///
    /// ```
    /// # #[macro_use] extern crate quote;
    /// # extern crate proc_macro2;
    /// # use quote::{TokenStreamExt, ToTokens};
    /// # use proc_macro2::TokenStream;
    /// # fn main() {
    /// struct X;
    ///
    /// impl ToTokens for X {
    ///     fn to_tokens(&self, tokens: &mut TokenStream) {
    ///         tokens.append_all(&[true, false]);
    ///     }
    /// }
    ///
    /// let tokens = quote!(#X);
    /// assert_eq!(tokens.to_string(), "true false");
    /// # }
    /// ```
    fn append_all<T, I>(&mut self, iter: I)
    where
        T: ToTokens,
        I: IntoIterator<Item = T>,
    {
        for token in iter {
            token.to_tokens(self);
        }
    }

    /// For use by `ToTokens` implementations.
    ///
    /// Appends all of the items in the iterator `I`, separated by the tokens
    /// `U`.
    fn append_separated<T, I, U>(&mut self, iter: I, op: U)
    where
        T: ToTokens,
        I: IntoIterator<Item = T>,
        U: ToTokens,
    {
        for (i, token) in iter.into_iter().enumerate() {
            if i > 0 {
                op.to_tokens(self);
            }
            token.to_tokens(self);
        }
    }

    /// For use by `ToTokens` implementations.
    ///
    /// Appends all tokens in the iterator `I`, appending `U` after each
    /// element, including after the last element of the iterator.
    fn append_terminated<T, I, U>(&mut self, iter: I, term: U)
    where
        T: ToTokens,
        I: IntoIterator<Item = T>,
        U: ToTokens,
    {
        for token in iter {
            token.to_tokens(self);
            term.to_tokens(self);
        }
    }
}

mod private {
    use proc_macro2::TokenStream;

    pub trait Sealed {}

    impl Sealed for TokenStream {}
}
<commit_msg>Clearer impl to append a single token<commit_after>use super::ToTokens;

use std::iter;

use proc_macro2::{TokenStream, TokenTree};

/// TokenStream extension trait with methods for appending tokens.
///
/// This trait is sealed and cannot be implemented outside of the `quote` crate.
pub trait TokenStreamExt: private::Sealed {
    fn append<U>(&mut self, token: U)
    where
        U: Into<TokenTree>;

    fn append_all<T, I>(&mut self, iter: I)
    where
        T: ToTokens,
        I: IntoIterator<Item = T>;

    fn append_separated<T, I, U>(&mut self, iter: I, op: U)
    where
        T: ToTokens,
        I: IntoIterator<Item = T>,
        U: ToTokens;

    fn append_terminated<T, I, U>(&mut self, iter: I, term: U)
    where
        T: ToTokens,
        I: IntoIterator<Item = T>,
        U: ToTokens;
}

impl TokenStreamExt for TokenStream {
    /// For use by `ToTokens` implementations.
    ///
    /// Appends the token specified to this list of tokens.
    fn append<U>(&mut self, token: U)
    where
        U: Into<TokenTree>,
    {
        self.extend(iter::once(token.into()));
    }

    /// For use by `ToTokens` implementations.
    ///
    /// ```
    /// # #[macro_use] extern crate quote;
    /// # extern crate proc_macro2;
    /// # use quote::{TokenStreamExt, ToTokens};
    /// # use proc_macro2::TokenStream;
    /// # fn main() {
    /// struct X;
    ///
    /// impl ToTokens for X {
    ///     fn to_tokens(&self, tokens: &mut TokenStream) {
    ///         tokens.append_all(&[true, false]);
    ///     }
    /// }
    ///
    /// let tokens = quote!(#X);
    /// assert_eq!(tokens.to_string(), "true false");
    /// # }
    /// ```
    fn append_all<T, I>(&mut self, iter: I)
    where
        T: ToTokens,
        I: IntoIterator<Item = T>,
    {
        for token in iter {
            token.to_tokens(self);
        }
    }

    /// For use by `ToTokens` implementations.
    ///
    /// Appends all of the items in the iterator `I`, separated by the tokens
    /// `U`.
    fn append_separated<T, I, U>(&mut self, iter: I, op: U)
    where
        T: ToTokens,
        I: IntoIterator<Item = T>,
        U: ToTokens,
    {
        for (i, token) in iter.into_iter().enumerate() {
            if i > 0 {
                op.to_tokens(self);
            }
            token.to_tokens(self);
        }
    }

    /// For use by `ToTokens` implementations.
    ///
    /// Appends all tokens in the iterator `I`, appending `U` after each
    /// element, including after the last element of the iterator.
    fn append_terminated<T, I, U>(&mut self, iter: I, term: U)
    where
        T: ToTokens,
        I: IntoIterator<Item = T>,
        U: ToTokens,
    {
        for token in iter {
            token.to_tokens(self);
            term.to_tokens(self);
        }
    }
}

mod private {
    use proc_macro2::TokenStream;

    pub trait Sealed {}

    impl Sealed for TokenStream {}
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::sync::mpsc;
use std::sync::{Arc, RwLock};
use std::sync::atomic::{AtomicUsize, Ordering};

use mio::*;
use mio::tcp::*;

use client::WebSocketClient;
use interface::WebSocketEvent;

pub const SERVER_TOKEN: Token = Token(0);

#[derive(Clone)]
pub struct WebSocketServerState {
    clients: Arc<RwLock<HashMap<Token, WebSocketClient>>>,
    token_counter: Arc<AtomicUsize>
}

impl WebSocketServerState {
    pub fn new() -> WebSocketServerState {
        WebSocketServerState {
            token_counter: Arc::new(AtomicUsize::new(1)),
            clients: Arc::new(RwLock::new(HashMap::new()))
        }
    }

    fn new_client(&mut self, client_socket: TcpStream, tx: mpsc::Sender<WebSocketEvent>,
                  event_loop_tx: Sender<WebSocketEvent>) -> Token {
        let new_token = Token(self.token_counter.fetch_add(1, Ordering::SeqCst));

        if let Ok(ref mut clients) = self.clients.write() {
            clients.insert(new_token, WebSocketClient::new(client_socket, new_token, tx.clone(), event_loop_tx));
        }

        new_token
    }

    pub fn get_peers(&self) -> Option<Vec<Token>> {
        if let Ok(clients) = self.clients.read() {
            let tokens: Vec<Token> = clients.iter().map(|(tkn, _)| tkn.clone()).collect();
            Some(tokens)
        } else {
            None
        }
    }

    fn remove_client(&mut self, tkn: &Token) -> Option<WebSocketClient> {
        if let Ok(ref mut clients) = self.clients.write() {
            clients.remove(tkn)
        } else {
            None
        }
    }

    pub fn send_message(&mut self, msg: WebSocketEvent) {
        match msg {
            WebSocketEvent::TextMessage(tkn, _) |
            WebSocketEvent::BinaryMessage(tkn, _) |
            WebSocketEvent::Connect(tkn) |
            WebSocketEvent::Close(tkn) |
            WebSocketEvent::Ping(tkn, _) => {
                if let Ok(ref mut clients) = self.clients.write() {
                    let client = clients.get_mut(&tkn).unwrap();

                    client.send_message(msg);
                }
            },
            _ => {}
        }
    }
}

pub struct WebSocketServer {
    pub socket: TcpListener,
    state: WebSocketServerState,
    tx: mpsc::Sender<WebSocketEvent>
}

impl WebSocketServer {
    pub fn new(socket: TcpListener, shared_state: WebSocketServerState, tx: mpsc::Sender<WebSocketEvent>) -> WebSocketServer {
        WebSocketServer {
            socket: socket,
            state: shared_state,
            tx: tx
        }
    }
}

impl Handler for WebSocketServer {
    type Timeout = usize;
    type Message = WebSocketEvent;

    fn notify(&mut self, event_loop: &mut EventLoop<WebSocketServer>, msg: WebSocketEvent) {
        match msg {
            WebSocketEvent::Reregister(tkn) => {
                if let Ok(ref clients) = self.state.clients.read() {
                    let client = clients.get(&tkn).unwrap();
                    event_loop.reregister(&client.socket, tkn, client.interest,
                                          PollOpt::edge() | PollOpt::oneshot()).unwrap();
                }
            },
            _ => {}
        }
    }

    fn ready(&mut self, event_loop: &mut EventLoop<WebSocketServer>, token: Token, events: EventSet) {
        if events.is_readable() {
            match token {
                SERVER_TOKEN => {
                    let client_socket = match self.socket.accept() {
                        Ok(Some((sock, _))) => sock,
                        Ok(None) => unreachable!(),
                        Err(e) => {
                            println!("Accept error: {}", e);
                            return;
                        }
                    };

                    let new_token = self.state.new_client(client_socket, self.tx.clone(), event_loop.channel());

                    if let Ok(ref clients) = self.state.clients.read() {
                        event_loop.register(&clients[&new_token].socket,
                                            new_token, EventSet::readable(),
                                            PollOpt::edge() | PollOpt::oneshot()).unwrap();
                    }
                },
	        token => {
                    if let Ok(ref mut clients) = self.state.clients.write() {
                        let mut client = clients.get_mut(&token).unwrap();

                        client.read();

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

        if events.is_writable() {
            if let Ok(ref mut clients) = self.state.clients.write() {
                let mut client = clients.get_mut(&token).unwrap();

                client.write();

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

        if events.is_hup() {
            // Close connection
            let client = self.state.remove_client(&token).unwrap();

            client.socket.shutdown(Shutdown::Both);
            event_loop.deregister(&client.socket);

            println!("hang up connection");
        }
    }
}
<commit_msg>Simplify code with Iterator.cloned<commit_after>use std::collections::HashMap;
use std::sync::mpsc;
use std::sync::{Arc, RwLock};
use std::sync::atomic::{AtomicUsize, Ordering};

use mio::*;
use mio::tcp::*;

use client::WebSocketClient;
use interface::WebSocketEvent;

pub const SERVER_TOKEN: Token = Token(0);

#[derive(Clone)]
pub struct WebSocketServerState {
    clients: Arc<RwLock<HashMap<Token, WebSocketClient>>>,
    token_counter: Arc<AtomicUsize>
}

impl WebSocketServerState {
    pub fn new() -> WebSocketServerState {
        WebSocketServerState {
            token_counter: Arc::new(AtomicUsize::new(1)),
            clients: Arc::new(RwLock::new(HashMap::new()))
        }
    }

    fn new_client(&mut self, client_socket: TcpStream, tx: mpsc::Sender<WebSocketEvent>,
                  event_loop_tx: Sender<WebSocketEvent>) -> Token {
        let new_token = Token(self.token_counter.fetch_add(1, Ordering::SeqCst));

        if let Ok(ref mut clients) = self.clients.write() {
            clients.insert(new_token, WebSocketClient::new(client_socket, new_token, tx.clone(), event_loop_tx));
        }

        new_token
    }

    pub fn get_peers(&self) -> Option<Vec<Token>> {
        if let Ok(clients) = self.clients.read() {
            Some(clients.keys().cloned().collect::<Vec<_>>())
        } else {
            None
        }
    }

    fn remove_client(&mut self, tkn: &Token) -> Option<WebSocketClient> {
        if let Ok(ref mut clients) = self.clients.write() {
            clients.remove(tkn)
        } else {
            None
        }
    }

    pub fn send_message(&mut self, msg: WebSocketEvent) {
        match msg {
            WebSocketEvent::TextMessage(tkn, _) |
            WebSocketEvent::BinaryMessage(tkn, _) |
            WebSocketEvent::Connect(tkn) |
            WebSocketEvent::Close(tkn) |
            WebSocketEvent::Ping(tkn, _) => {
                if let Ok(ref mut clients) = self.clients.write() {
                    let client = clients.get_mut(&tkn).unwrap();

                    client.send_message(msg);
                }
            },
            _ => {}
        }
    }
}

pub struct WebSocketServer {
    pub socket: TcpListener,
    state: WebSocketServerState,
    tx: mpsc::Sender<WebSocketEvent>
}

impl WebSocketServer {
    pub fn new(socket: TcpListener, shared_state: WebSocketServerState, tx: mpsc::Sender<WebSocketEvent>) -> WebSocketServer {
        WebSocketServer {
            socket: socket,
            state: shared_state,
            tx: tx
        }
    }
}

impl Handler for WebSocketServer {
    type Timeout = usize;
    type Message = WebSocketEvent;

    fn notify(&mut self, event_loop: &mut EventLoop<WebSocketServer>, msg: WebSocketEvent) {
        match msg {
            WebSocketEvent::Reregister(tkn) => {
                if let Ok(ref clients) = self.state.clients.read() {
                    let client = clients.get(&tkn).unwrap();
                    event_loop.reregister(&client.socket, tkn, client.interest,
                                          PollOpt::edge() | PollOpt::oneshot()).unwrap();
                }
            },
            _ => {}
        }
    }

    fn ready(&mut self, event_loop: &mut EventLoop<WebSocketServer>, token: Token, events: EventSet) {
        if events.is_readable() {
            match token {
                SERVER_TOKEN => {
                    let client_socket = match self.socket.accept() {
                        Ok(Some((sock, _))) => sock,
                        Ok(None) => unreachable!(),
                        Err(e) => {
                            println!("Accept error: {}", e);
                            return;
                        }
                    };

                    let new_token = self.state.new_client(client_socket, self.tx.clone(), event_loop.channel());

                    if let Ok(ref clients) = self.state.clients.read() {
                        event_loop.register(&clients[&new_token].socket,
                                            new_token, EventSet::readable(),
                                            PollOpt::edge() | PollOpt::oneshot()).unwrap();
                    }
                },
	        token => {
                    if let Ok(ref mut clients) = self.state.clients.write() {
                        let mut client = clients.get_mut(&token).unwrap();

                        client.read();

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

        if events.is_writable() {
            if let Ok(ref mut clients) = self.state.clients.write() {
                let mut client = clients.get_mut(&token).unwrap();

                client.write();

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

        if events.is_hup() {
            // Close connection
            let client = self.state.remove_client(&token).unwrap();

            client.socket.shutdown(Shutdown::Both);
            event_loop.deregister(&client.socket);

            println!("hang up connection");
        }
    }
}
<|endoftext|>


<commit_before>#[warn(unused_must_use)]

// copied mostly from public domain https://github.com/zmack/rust-socks/blob/master/src/server.rs
extern crate byteorder;
extern crate webextension_protocol as protocol;

use std::thread;
use std::time::Duration;
use std::io::Write;
use std::net::{TcpStream, Shutdown};
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::net::lookup_host;
use std::io::{Error,ErrorKind};
use std::io;
use std::sync::mpsc::{Sender};
use std::convert::AsRef;
use helpers;

use std::io::Read;

use server::byteorder::{BigEndian, ReadBytesExt};

pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>
    where R: Read, W: Write
{
    let mut buf = [0; 8*1024];
    let mut written = 0;
    loop {
        let len = match reader.read(&mut buf) {
            Ok(0) => return Ok(written),
            Ok(len) => len,
            Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };
        writer.write_all(&buf[..len])?;
        written += len as u64;
    }
}

#[allow(dead_code)]
enum RocksError {
    Io(Error),
    Generic(String)
}

pub struct SocksServer {
    tcp_stream: TcpStream,
    sender: Sender<(Sender<String>, String)>,
}

impl SocksServer {

    #[allow(unused_must_use)]
    pub fn new(tcp_stream: TcpStream, sender: Sender<(Sender<String>, String)>) {
        let mut server = SocksServer {
            tcp_stream: tcp_stream,
            sender: sender,
        };
        server.handle_client();
    }

    #[allow(unused_must_use)]
    fn handle_client(&mut self) -> Result<(), RocksError> {
        loop {
            let version = match self.tcp_stream.read_u8() {
                Ok(v) => v ,
                _ => break,
            };
            if version == 5 {
                println_stderr!("wrong protocol version");
                let num_methods = self.tcp_stream.read_u8().unwrap();
                let mut methods = Vec::with_capacity(num_methods as usize);
                unsafe { methods.set_len(num_methods as usize) };
                self.tcp_stream.read_exact(&mut methods).unwrap();
                println_stderr!("num_methods is {:?}, methods is {:?}", num_methods, methods);
                if methods.contains(&2) {
                    // Authenticated
                    self.tcp_stream.write(&[5, 2]);
                    //self.authenticate().unwrap()
                } else {
                    // Unauthenticated
                    self.tcp_stream.write(&[5, 0]);
                }
                //
            } else {
                drop(&self.tcp_stream);
                println_stderr!("wrong protocol version");
                break
            }

            let v1 = self.tcp_stream.read_u8().unwrap();
            let c = self.tcp_stream.read_u8().unwrap();
            let res = self.tcp_stream.read_u8().unwrap();
            let addr_type = self.tcp_stream.read_u8().unwrap();

            println_stderr!("v1 is {:?}", v1);
            println_stderr!("c is {:?}", c);
            println_stderr!("res is {:?}", res);
            println_stderr!("Address type is {:?}", addr_type);
            let addr = self.get_remote_addr(addr_type).unwrap();

            println_stderr!("Address is {:?}", addr);

            let msg = helpers::js_message("getBlock".to_string(), "\"".to_string()+addr.to_string().as_str()+"\"");
            let response = helpers::send_sync(self.sender.clone(), msg);

            println_stderr!("jsengine response {}", response);

            match response.as_ref() {
                "false" => {
                },
                "true" => {
                    drop(&self.tcp_stream);
                    break;
                },
                _ => {},
            }

            println_stderr!("got a connection");
            let outbound = TcpStream::connect(addr).unwrap();
            outbound.set_read_timeout(Some(Duration::from_secs(5))).unwrap();

            self.tcp_stream.write(&[5, 0, 0, 1, 127, 0, 0, 1, 0, 0]).unwrap();
            println_stderr!("Wrote things");

            let mut client_reader = self.tcp_stream.try_clone().unwrap();
            let mut client_writer = self.tcp_stream.try_clone().unwrap();
            let mut socket_reader = outbound.try_clone().unwrap();
            let mut socket_writer = outbound.try_clone().unwrap();

            thread::spawn(move || {
                copy(&mut client_reader, &mut socket_writer);
                client_reader.shutdown(Shutdown::Read);
                socket_writer.shutdown(Shutdown::Write);
            });

            copy(&mut socket_reader, &mut client_writer);
            socket_reader.shutdown(Shutdown::Read);
            client_writer.shutdown(Shutdown::Write);
        }

        return Ok(())
    }

    #[allow(unused_must_use)]
    fn get_remote_addr(&mut self, addr_type: u8) -> Result<SocketAddr, String> {
        match addr_type {
            1 => {
                let mut ip_bytes = [0u8; 4];
                self.tcp_stream.read_exact(&mut ip_bytes);
                let ip = Ipv4Addr::from(ip_bytes);
                let port = self.tcp_stream.read_u16::<BigEndian>().unwrap();

                return Ok(SocketAddr::V4(SocketAddrV4::new(ip, port)));
            },
            3 => {
                let num_str = self.tcp_stream.read_u8().unwrap();
                let mut hostname_vec = Vec::with_capacity(num_str as usize);
                unsafe { hostname_vec.set_len(num_str as usize) };
                self.tcp_stream.read_exact(&mut hostname_vec).unwrap();
                let port = self.tcp_stream.read_u16::<BigEndian>().unwrap();

                let hostname = match String::from_utf8(hostname_vec) { Ok(s) => s, _ => "".to_string() };
                let address = self.resolve_addr_with_cache(&hostname);

                if address.is_none() {
                    return Err(From::from("Empty Address".to_string()))
                } else {
                    // println!("Resolution succeeded for {?} - {?}", hostname, addresses);
                    let mut address = address.unwrap();
                    address.set_port(port);
                    return Ok(address);
                }
            },
            _ => return Err(From::from("Invalid Address Type".to_string()))
        }
    }

    fn resolve_addr_with_cache(&self, hostname: &str) -> Option<SocketAddr> {
        match lookup_host(&hostname) {
            Ok(mut a) => { a.nth(0) },
            _ => { None }
        }
    }
}
<commit_msg>Printing http contents to stderr<commit_after>#[warn(unused_must_use)]

// copied mostly from public domain https://github.com/zmack/rust-socks/blob/master/src/server.rs
extern crate byteorder;
extern crate webextension_protocol as protocol;

use std::thread;
use std::time::Duration;
use std::io::Write;
use std::net::{TcpStream, Shutdown};
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::net::lookup_host;
use std::io::{Error,ErrorKind};
use std::io;
use std::sync::mpsc::{Sender};
use std::convert::AsRef;
use helpers;

use std::io::Read;

use server::byteorder::{BigEndian, ReadBytesExt};

pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>
    where R: Read, W: Write
{
    let mut buf = [0; 8*1024];
    let mut written = 0;
    loop {
        let len = match reader.read(&mut buf) {
            Ok(0) => return Ok(written),
            Ok(len) => len,
            Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };

        println_stderr!("READ {}", buf.iter().fold(String::new(), |acc, &num| acc + (num as char).to_string().as_str() ));
        writer.write_all(&buf[..len])?;
        written += len as u64;
    }
}

#[allow(dead_code)]
enum RocksError {
    Io(Error),
    Generic(String)
}

pub struct SocksServer {
    tcp_stream: TcpStream,
    sender: Sender<(Sender<String>, String)>,
}

impl SocksServer {

    #[allow(unused_must_use)]
    pub fn new(tcp_stream: TcpStream, sender: Sender<(Sender<String>, String)>) {
        let mut server = SocksServer {
            tcp_stream: tcp_stream,
            sender: sender,
        };
        server.handle_client();
    }

    #[allow(unused_must_use)]
    fn handle_client(&mut self) -> Result<(), RocksError> {
        loop {
            let version = match self.tcp_stream.read_u8() {
                Ok(v) => v ,
                _ => break,
            };
            if version == 5 {
                println_stderr!("wrong protocol version");
                let num_methods = self.tcp_stream.read_u8().unwrap();
                let mut methods = Vec::with_capacity(num_methods as usize);
                unsafe { methods.set_len(num_methods as usize) };
                self.tcp_stream.read_exact(&mut methods).unwrap();
                println_stderr!("num_methods is {:?}, methods is {:?}", num_methods, methods);
                if methods.contains(&2) {
                    // Authenticated
                    self.tcp_stream.write(&[5, 2]);
                    //self.authenticate().unwrap()
                } else {
                    // Unauthenticated
                    self.tcp_stream.write(&[5, 0]);
                }
                //
            } else {
                drop(&self.tcp_stream);
                println_stderr!("wrong protocol version");
                break
            }

            let v1 = self.tcp_stream.read_u8().unwrap();
            let c = self.tcp_stream.read_u8().unwrap();
            let res = self.tcp_stream.read_u8().unwrap();
            let addr_type = self.tcp_stream.read_u8().unwrap();

            println_stderr!("v1 is {:?}", v1);
            println_stderr!("c is {:?}", c);
            println_stderr!("res is {:?}", res);
            println_stderr!("Address type is {:?}", addr_type);
            let addr = self.get_remote_addr(addr_type).unwrap();

            println_stderr!("Address is {:?}", addr);

            let msg = helpers::js_message("getBlock".to_string(), "\"".to_string()+addr.to_string().as_str()+"\"");
            let response = helpers::send_sync(self.sender.clone(), msg);

            println_stderr!("jsengine response {}", response);

            match response.as_ref() {
                "false" => {
                },
                "true" => {
                    drop(&self.tcp_stream);
                    break;
                },
                _ => {},
            }

            println_stderr!("got a connection");
            let outbound = TcpStream::connect(addr).unwrap();
            outbound.set_read_timeout(Some(Duration::from_secs(5))).unwrap();

            self.tcp_stream.write(&[5, 0, 0, 1, 127, 0, 0, 1, 0, 0]).unwrap();
            println_stderr!("Wrote things");

            let mut client_reader = self.tcp_stream.try_clone().unwrap();
            let mut client_writer = self.tcp_stream.try_clone().unwrap();
            let mut socket_reader = outbound.try_clone().unwrap();
            let mut socket_writer = outbound.try_clone().unwrap();

            thread::spawn(move || {
                copy(&mut client_reader, &mut socket_writer);
                client_reader.shutdown(Shutdown::Read);
                socket_writer.shutdown(Shutdown::Write);
            });

            copy(&mut socket_reader, &mut client_writer);
            socket_reader.shutdown(Shutdown::Read);
            client_writer.shutdown(Shutdown::Write);
        }

        return Ok(())
    }

    #[allow(unused_must_use)]
    fn get_remote_addr(&mut self, addr_type: u8) -> Result<SocketAddr, String> {
        match addr_type {
            1 => {
                let mut ip_bytes = [0u8; 4];
                self.tcp_stream.read_exact(&mut ip_bytes);
                let ip = Ipv4Addr::from(ip_bytes);
                let port = self.tcp_stream.read_u16::<BigEndian>().unwrap();

                return Ok(SocketAddr::V4(SocketAddrV4::new(ip, port)));
            },
            3 => {
                let num_str = self.tcp_stream.read_u8().unwrap();
                let mut hostname_vec = Vec::with_capacity(num_str as usize);
                unsafe { hostname_vec.set_len(num_str as usize) };
                self.tcp_stream.read_exact(&mut hostname_vec).unwrap();
                let port = self.tcp_stream.read_u16::<BigEndian>().unwrap();

                let hostname = match String::from_utf8(hostname_vec) { Ok(s) => s, _ => "".to_string() };
                let address = self.resolve_addr_with_cache(&hostname);

                if address.is_none() {
                    return Err(From::from("Empty Address".to_string()))
                } else {
                    // println!("Resolution succeeded for {?} - {?}", hostname, addresses);
                    let mut address = address.unwrap();
                    address.set_port(port);
                    return Ok(address);
                }
            },
            _ => return Err(From::from("Invalid Address Type".to_string()))
        }
    }

    fn resolve_addr_with_cache(&self, hostname: &str) -> Option<SocketAddr> {
        match lookup_host(&hostname) {
            Ok(mut a) => { a.nth(0) },
            _ => { None }
        }
    }
}
<|endoftext|>


<commit_before>//!  Decoding of GIF Images
//!
//!  GIF (Graphics Interchange Format) is an image format that supports lossless compression.
//!
//!  # Related Links
//!  * <http://www.w3.org/Graphics/GIF/spec-gif89a.txt> - The GIF Specification
//!
//! # Examples
//! ```rust,no_run
//! use image::gif::{Decoder, Encoder};
//! use image::{ImageDecoder, AnimationDecoder};
//! use std::fs::File;
//! # fn main() -> std::io::Result<()> {
//! // Decode a gif into frames
//! let file_in = File::open("foo.gif")?;
//! let mut decoder = Decoder::new(file_in).unwrap();
//! let frames = decoder.into_frames();
//! let frames = frames.collect_frames().expect("error decoding gif");
//!
//! // Encode frames into a gif and save to a file
//! let mut file_out = File::open("out.gif")?;
//! let mut encoder = Encoder::new(file_out);
//! encoder.encode_frames(frames.into_iter());
//! # Ok(())
//! # }
//! ```
#![cfg_attr(feature = "cargo-clippy", allow(while_let_loop))]

extern crate gif;
extern crate num_rational;

use std::clone::Clone;
use std::io::{self, Cursor, Read, Write};
use std::marker::PhantomData;
use std::mem;

use self::gif::{ColorOutput, SetParameter};
pub use self::gif::{DisposalMethod, Frame};

use animation;
use buffer::{ImageBuffer, Pixel};
use color;
use color::Rgba;
use image::{AnimationDecoder, ImageDecoder, ImageError, ImageResult};
use num_rational::Ratio;

/// GIF decoder
pub struct Decoder<R: Read> {
    reader: gif::Reader<R>,
}

impl<R: Read> Decoder<R> {
    /// Creates a new decoder that decodes the input steam ```r```
    pub fn new(r: R) -> ImageResult<Decoder<R>> {
        let mut decoder = gif::Decoder::new(r);
        decoder.set(ColorOutput::RGBA);

        Ok(Decoder {
            reader: decoder.read_info()?,
        })
    }
}

/// Wrapper struct around a `Cursor<Vec<u8>>`
pub struct GifReader<R>(Cursor<Vec<u8>>, PhantomData<R>);
impl<R> Read for GifReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        if self.0.position() == 0 && buf.is_empty() {
            mem::swap(buf, self.0.get_mut());
            Ok(buf.len())
        } else {
            self.0.read_to_end(buf)
        }
    }
}

impl<'a, R: 'a + Read> ImageDecoder<'a> for Decoder<R> {
    type Reader = GifReader<R>;

    fn dimensions(&self) -> (u64, u64) {
        (self.reader.width() as u64, self.reader.height() as u64)
    }

    fn colortype(&self) -> color::ColorType {
        color::ColorType::RGBA(8)
    }

    fn into_reader(self) -> ImageResult<Self::Reader> {
        Ok(GifReader(Cursor::new(self.read_image()?), PhantomData))
    }

    fn read_image(mut self) -> ImageResult<Vec<u8>> {
        if self.reader.next_frame_info()?.is_some() {
            let mut buf = vec![0; self.reader.buffer_size()];
            self.reader.read_into_buffer(&mut buf)?;
            Ok(buf)
        } else {
            Err(ImageError::ImageEnd)
        }
    }
}

struct GifFrameIterator<R: Read> {
    reader: gif::Reader<R>,

    width: u32,
    height: u32,

    background_img: ImageBuffer<Rgba<u8>, Vec<u8>>,
    non_disposed_frame: ImageBuffer<Rgba<u8>, Vec<u8>>,

    left: u32,
    top: u32,
    delay: Ratio<u16>,
    dispose: DisposalMethod,
}

impl<R: Read> GifFrameIterator<R> {
    fn new(decoder: Decoder<R>) -> GifFrameIterator<R> {
        let (width, height) = decoder.dimensions();

        // TODO: Avoid this cast
        let (width, height) = (width as u32, height as u32);

        // set the background color to be either the bg_color defined in the gif
        // or a transparent pixel.
        let background_color_option = decoder.reader.bg_color();
        let mut background_color = vec![0; 4];
        let background_pixel = {
            let global_palette = decoder.reader.global_palette();
            match background_color_option {
                Some(index) => {
                    // find the color by looking in the global palette
                    match global_palette {
                        // take the color from the palette that is at the index defined
                        // by background_color_option
                        Some(slice) => {
                            background_color.clone_from_slice(&slice[index..(index + 4)]);
                            Rgba::from_slice(&background_color)
                        }
                        // if there is no global palette, assign the background color to be
                        // transparent
                        None => Rgba::from_slice(&[0, 0, 0, 0]),
                    }
                }
                // return a transparent background color
                None => Rgba::from_slice(&[0, 0, 0, 0]),
            }
        };

        // create the background image to use later
        let background_img = ImageBuffer::from_pixel(width, height, *background_pixel);

        // the background image is the first non disposed frame
        let non_disposed_frame = background_img.clone();

        GifFrameIterator {
            reader: decoder.reader,
            width,
            height,
            background_img,
            non_disposed_frame,
            left: 0,
            top: 0,
            delay: Ratio::new(0, 1),
            dispose: DisposalMethod::Any
        }
    }
}

impl<R: Read> Iterator for GifFrameIterator<R> {
    type Item = ImageResult<animation::Frame>;

    fn next(&mut self) -> Option<ImageResult<animation::Frame>> {
        // begin looping over each frame
        match self.reader.next_frame_info() {
            Ok(frame_info) => {
                if let Some(frame) = frame_info {
                    self.left = u32::from(frame.left);
                    self.top = u32::from(frame.top);

                    // frame.delay is in units of 10ms so frame.delay*10 is in ms
                    self.delay = Ratio::new(frame.delay * 10, 1);
                    self.dispose = frame.dispose;
                } else {
                    // no more frames
                    return None;
                }
            },
            Err(err) => return Some(Err(err.into())),
        }

        let mut vec = vec![0; self.reader.buffer_size()];
        if let Err(err) = self.reader.fill_buffer(&mut vec) {
            return Some(Err(err.into()));
        }

        // create the image buffer from the raw frame
        let mut image_buffer = match ImageBuffer::from_raw(self.width, self.height, vec) {
            Some(buffer) => buffer,
            None => return Some(Err(ImageError::UnsupportedError(
                "Unknown error occured while reading gif frame".into()
            ))),
        };

        // loop over all pixels, checking if any pixels from the non disposed
        // frame need to be used
        for (x, y, pixel) in image_buffer.enumerate_pixels_mut() {
            let previous_img_buffer = &self.non_disposed_frame;
            let adjusted_pixel: &mut Rgba<u8> = pixel;
            let previous_pixel: &Rgba<u8> = previous_img_buffer.get_pixel(x, y);

            let pixel_alpha = adjusted_pixel.channels()[3];

            // If a pixel is not visible then we show the non disposed frame pixel instead
            if pixel_alpha == 0 {
                adjusted_pixel.blend(previous_pixel);
            }
        }

        let frame = animation::Frame::from_parts(
            image_buffer.clone(), self.left, self.top, self.delay
        );

        match self.dispose {
            DisposalMethod::Any => {
                // do nothing
                // (completely replace this frame with the next)
            }
            DisposalMethod::Keep => {
                // do not dispose
                // (keep pixels from this frame)
                self.non_disposed_frame = image_buffer;
            }
            DisposalMethod::Background => {
                // restore to background color
                // (background shows through transparent pixels in the next frame)
                self.non_disposed_frame = self.background_img.clone();
            }
            DisposalMethod::Previous => {
                // restore to previous
                // (dispose frames leaving the last none disposal frame)
            }
        };

        Some(Ok(frame))
    }
}

impl<'a, R: Read + 'a> AnimationDecoder<'a> for Decoder<R> {
    fn into_frames(self) -> animation::Frames<'a> {
        animation::Frames::new(Box::new(GifFrameIterator::new(self)))
    }
}

/// GIF encoder.
pub struct Encoder<W: Write> {
    w: Option<W>,
    gif_encoder: Option<gif::Encoder<W>>,
}

impl<W: Write> Encoder<W> {
    /// Creates a new GIF encoder.
    pub fn new(w: W) -> Encoder<W> {
        Encoder {
            w: Some(w),
            gif_encoder: None,
        }
    }
    /// Encodes a frame.
    pub fn encode(&mut self, frame: &Frame) -> ImageResult<()> {
        let result;
        if let Some(ref mut encoder) = self.gif_encoder {
            result = encoder.write_frame(frame).map_err(|err| err.into());
        } else {
            let writer = self.w.take().unwrap();
            let mut encoder = gif::Encoder::new(writer, frame.width, frame.height, &[])?;
            result = encoder.write_frame(&frame).map_err(|err| err.into());
            self.gif_encoder = Some(encoder);
        }
        result
    }

    /// Encodes Frames.
    /// Consider using `try_encode_frames` instead to encode an `animation::Frames` like iterator.
    pub fn encode_frames<F>(&mut self, frames: F) -> ImageResult<()>
    where
        F: IntoIterator<Item = animation::Frame>
    {
        for img_frame in frames {
            self.encode_single_frame(img_frame)?;
        }
        Ok(())
    }

    /// Try to encode a collection of `ImageResult<animation::Frame>` objects.
    /// Use this function to encode an `animation::Frames` like iterator.
    /// Whenever an `Err` item is encountered, that value is returned without further actions.
    pub fn try_encode_frames<F>(&mut self, frames: F) -> ImageResult<()>
    where
        F: IntoIterator<Item = ImageResult<animation::Frame>>
    {
        for img_frame in frames {
            self.encode_single_frame(img_frame?)?;
        }
        Ok(())
    }

    fn encode_single_frame(&mut self, img_frame: animation::Frame) -> ImageResult<()> {
        // get the delay before converting img_frame
        let frame_delay = img_frame.delay().to_integer();
        // convert img_frame into RgbaImage
        let rbga_frame = img_frame.into_buffer();

        // Create the gif::Frame from the animation::Frame
        let mut frame = Frame::from_rgba(rbga_frame.width() as u16, rbga_frame.height() as u16, &mut rbga_frame.into_raw());
        frame.delay = frame_delay;

        // encode the gif::Frame
        self.encode(&frame)
    }
}

impl From<gif::DecodingError> for ImageError {
    fn from(err: gif::DecodingError) -> ImageError {
        use self::gif::DecodingError::*;
        match err {
            Format(desc) | Internal(desc) => ImageError::FormatError(desc.into()),
            Io(io_err) => ImageError::IoError(io_err),
        }
    }
}
<commit_msg>Stop storing temporary variables in struct<commit_after>//!  Decoding of GIF Images
//!
//!  GIF (Graphics Interchange Format) is an image format that supports lossless compression.
//!
//!  # Related Links
//!  * <http://www.w3.org/Graphics/GIF/spec-gif89a.txt> - The GIF Specification
//!
//! # Examples
//! ```rust,no_run
//! use image::gif::{Decoder, Encoder};
//! use image::{ImageDecoder, AnimationDecoder};
//! use std::fs::File;
//! # fn main() -> std::io::Result<()> {
//! // Decode a gif into frames
//! let file_in = File::open("foo.gif")?;
//! let mut decoder = Decoder::new(file_in).unwrap();
//! let frames = decoder.into_frames();
//! let frames = frames.collect_frames().expect("error decoding gif");
//!
//! // Encode frames into a gif and save to a file
//! let mut file_out = File::open("out.gif")?;
//! let mut encoder = Encoder::new(file_out);
//! encoder.encode_frames(frames.into_iter());
//! # Ok(())
//! # }
//! ```
#![cfg_attr(feature = "cargo-clippy", allow(while_let_loop))]

extern crate gif;
extern crate num_rational;

use std::clone::Clone;
use std::io::{self, Cursor, Read, Write};
use std::marker::PhantomData;
use std::mem;

use self::gif::{ColorOutput, SetParameter};
pub use self::gif::{DisposalMethod, Frame};

use animation;
use buffer::{ImageBuffer, Pixel};
use color;
use color::Rgba;
use image::{AnimationDecoder, ImageDecoder, ImageError, ImageResult};
use num_rational::Ratio;

/// GIF decoder
pub struct Decoder<R: Read> {
    reader: gif::Reader<R>,
}

impl<R: Read> Decoder<R> {
    /// Creates a new decoder that decodes the input steam ```r```
    pub fn new(r: R) -> ImageResult<Decoder<R>> {
        let mut decoder = gif::Decoder::new(r);
        decoder.set(ColorOutput::RGBA);

        Ok(Decoder {
            reader: decoder.read_info()?,
        })
    }
}

/// Wrapper struct around a `Cursor<Vec<u8>>`
pub struct GifReader<R>(Cursor<Vec<u8>>, PhantomData<R>);
impl<R> Read for GifReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        if self.0.position() == 0 && buf.is_empty() {
            mem::swap(buf, self.0.get_mut());
            Ok(buf.len())
        } else {
            self.0.read_to_end(buf)
        }
    }
}

impl<'a, R: 'a + Read> ImageDecoder<'a> for Decoder<R> {
    type Reader = GifReader<R>;

    fn dimensions(&self) -> (u64, u64) {
        (self.reader.width() as u64, self.reader.height() as u64)
    }

    fn colortype(&self) -> color::ColorType {
        color::ColorType::RGBA(8)
    }

    fn into_reader(self) -> ImageResult<Self::Reader> {
        Ok(GifReader(Cursor::new(self.read_image()?), PhantomData))
    }

    fn read_image(mut self) -> ImageResult<Vec<u8>> {
        if self.reader.next_frame_info()?.is_some() {
            let mut buf = vec![0; self.reader.buffer_size()];
            self.reader.read_into_buffer(&mut buf)?;
            Ok(buf)
        } else {
            Err(ImageError::ImageEnd)
        }
    }
}

struct GifFrameIterator<R: Read> {
    reader: gif::Reader<R>,

    width: u32,
    height: u32,

    background_img: ImageBuffer<Rgba<u8>, Vec<u8>>,
    non_disposed_frame: ImageBuffer<Rgba<u8>, Vec<u8>>,
}

impl<R: Read> GifFrameIterator<R> {
    fn new(decoder: Decoder<R>) -> GifFrameIterator<R> {
        let (width, height) = decoder.dimensions();

        // TODO: Avoid this cast
        let (width, height) = (width as u32, height as u32);

        // set the background color to be either the bg_color defined in the gif
        // or a transparent pixel.
        let background_color_option = decoder.reader.bg_color();
        let mut background_color = vec![0; 4];
        let background_pixel = {
            let global_palette = decoder.reader.global_palette();
            match background_color_option {
                Some(index) => {
                    // find the color by looking in the global palette
                    match global_palette {
                        // take the color from the palette that is at the index defined
                        // by background_color_option
                        Some(slice) => {
                            background_color.clone_from_slice(&slice[index..(index + 4)]);
                            Rgba::from_slice(&background_color)
                        }
                        // if there is no global palette, assign the background color to be
                        // transparent
                        None => Rgba::from_slice(&[0, 0, 0, 0]),
                    }
                }
                // return a transparent background color
                None => Rgba::from_slice(&[0, 0, 0, 0]),
            }
        };

        // create the background image to use later
        let background_img = ImageBuffer::from_pixel(width, height, *background_pixel);

        // the background image is the first non disposed frame
        let non_disposed_frame = background_img.clone();

        GifFrameIterator {
            reader: decoder.reader,
            width,
            height,
            background_img,
            non_disposed_frame,
        }
    }
}

impl<R: Read> Iterator for GifFrameIterator<R> {
    type Item = ImageResult<animation::Frame>;

    fn next(&mut self) -> Option<ImageResult<animation::Frame>> {
        // begin looping over each frame
        let (left, top, delay, dispose);

        match self.reader.next_frame_info() {
            Ok(frame_info) => {
                if let Some(frame) = frame_info {
                    left = u32::from(frame.left);
                    top = u32::from(frame.top);

                    // frame.delay is in units of 10ms so frame.delay*10 is in ms
                    delay = Ratio::new(frame.delay * 10, 1);
                    dispose = frame.dispose;
                } else {
                    // no more frames
                    return None;
                }
            },
            Err(err) => return Some(Err(err.into())),
        }

        let mut vec = vec![0; self.reader.buffer_size()];
        if let Err(err) = self.reader.fill_buffer(&mut vec) {
            return Some(Err(err.into()));
        }

        // create the image buffer from the raw frame
        let mut image_buffer = match ImageBuffer::from_raw(self.width, self.height, vec) {
            Some(buffer) => buffer,
            None => return Some(Err(ImageError::UnsupportedError(
                "Unknown error occured while reading gif frame".into()
            ))),
        };

        // loop over all pixels, checking if any pixels from the non disposed
        // frame need to be used
        for (x, y, pixel) in image_buffer.enumerate_pixels_mut() {
            let previous_img_buffer = &self.non_disposed_frame;
            let adjusted_pixel: &mut Rgba<u8> = pixel;
            let previous_pixel: &Rgba<u8> = previous_img_buffer.get_pixel(x, y);

            let pixel_alpha = adjusted_pixel.channels()[3];

            // If a pixel is not visible then we show the non disposed frame pixel instead
            if pixel_alpha == 0 {
                adjusted_pixel.blend(previous_pixel);
            }
        }

        let frame = animation::Frame::from_parts(
            image_buffer.clone(), left, top, delay
        );

        match dispose {
            DisposalMethod::Any => {
                // do nothing
                // (completely replace this frame with the next)
            }
            DisposalMethod::Keep => {
                // do not dispose
                // (keep pixels from this frame)
                self.non_disposed_frame = image_buffer;
            }
            DisposalMethod::Background => {
                // restore to background color
                // (background shows through transparent pixels in the next frame)
                self.non_disposed_frame = self.background_img.clone();
            }
            DisposalMethod::Previous => {
                // restore to previous
                // (dispose frames leaving the last none disposal frame)
            }
        };

        Some(Ok(frame))
    }
}

impl<'a, R: Read + 'a> AnimationDecoder<'a> for Decoder<R> {
    fn into_frames(self) -> animation::Frames<'a> {
        animation::Frames::new(Box::new(GifFrameIterator::new(self)))
    }
}

/// GIF encoder.
pub struct Encoder<W: Write> {
    w: Option<W>,
    gif_encoder: Option<gif::Encoder<W>>,
}

impl<W: Write> Encoder<W> {
    /// Creates a new GIF encoder.
    pub fn new(w: W) -> Encoder<W> {
        Encoder {
            w: Some(w),
            gif_encoder: None,
        }
    }
    /// Encodes a frame.
    pub fn encode(&mut self, frame: &Frame) -> ImageResult<()> {
        let result;
        if let Some(ref mut encoder) = self.gif_encoder {
            result = encoder.write_frame(frame).map_err(|err| err.into());
        } else {
            let writer = self.w.take().unwrap();
            let mut encoder = gif::Encoder::new(writer, frame.width, frame.height, &[])?;
            result = encoder.write_frame(&frame).map_err(|err| err.into());
            self.gif_encoder = Some(encoder);
        }
        result
    }

    /// Encodes Frames.
    /// Consider using `try_encode_frames` instead to encode an `animation::Frames` like iterator.
    pub fn encode_frames<F>(&mut self, frames: F) -> ImageResult<()>
    where
        F: IntoIterator<Item = animation::Frame>
    {
        for img_frame in frames {
            self.encode_single_frame(img_frame)?;
        }
        Ok(())
    }

    /// Try to encode a collection of `ImageResult<animation::Frame>` objects.
    /// Use this function to encode an `animation::Frames` like iterator.
    /// Whenever an `Err` item is encountered, that value is returned without further actions.
    pub fn try_encode_frames<F>(&mut self, frames: F) -> ImageResult<()>
    where
        F: IntoIterator<Item = ImageResult<animation::Frame>>
    {
        for img_frame in frames {
            self.encode_single_frame(img_frame?)?;
        }
        Ok(())
    }

    fn encode_single_frame(&mut self, img_frame: animation::Frame) -> ImageResult<()> {
        // get the delay before converting img_frame
        let frame_delay = img_frame.delay().to_integer();
        // convert img_frame into RgbaImage
        let rbga_frame = img_frame.into_buffer();

        // Create the gif::Frame from the animation::Frame
        let mut frame = Frame::from_rgba(rbga_frame.width() as u16, rbga_frame.height() as u16, &mut rbga_frame.into_raw());
        frame.delay = frame_delay;

        // encode the gif::Frame
        self.encode(&frame)
    }
}

impl From<gif::DecodingError> for ImageError {
    fn from(err: gif::DecodingError) -> ImageError {
        use self::gif::DecodingError::*;
        match err {
            Format(desc) | Internal(desc) => ImageError::FormatError(desc.into()),
            Io(io_err) => ImageError::IoError(io_err),
        }
    }
}
<|endoftext|>


<commit_before>//! Defines the messages passed between client and server.

use block_position::BlockPosition;
use entity::EntityId;
use lod::LODIndex;
use nalgebra::{Vec2, Vec3, Pnt3};
use nanomsg::{Endpoint, Socket, Protocol};
use process_events::{process_channel, process_socket};
use rustc_serialize::{Encodable, Decodable, json};
use std::fmt::Debug;
use std::old_io::timer;
use std::sync::mpsc::{channel, Sender, Receiver};
use std::time::duration::Duration;
use std::thread::Thread;
use terrain_block::TerrainBlock;
use vertex::ColoredVertex;

#[derive(Debug, Clone)]
#[derive(RustcDecodable, RustcEncodable)]
/// Messages the client sends to the server.
pub enum ClientToServer {
  /// Notify the server that the client exists, and provide a "return address".
  Init(String),
  /// Add a vector the player's acceleration.
  Walk(Vec3<f32>),
  /// Rotate the player by some amount.
  RotatePlayer(Vec2<f32>),
  /// [Try to] start a jump for the player.
  StartJump,
  /// [Try to] stop a jump for the player.
  StopJump,
  /// Ask the server to send a block of terrain.
  RequestBlock(BlockPosition, LODIndex),
}

#[derive(Debug, Clone)]
#[derive(RustcDecodable, RustcEncodable)]
/// Messages the server sends to the client.
pub enum ServerToClient {
  /// Update the player's position.
  UpdatePlayer(Pnt3<f32>),

  /// Tell the client to add a new mob with the given mesh.
  AddMob(EntityId, Vec<ColoredVertex>),
  /// Update the client's view of a mob with a given mesh.
  UpdateMob(EntityId, Vec<ColoredVertex>),

  /// The sun as a [0, 1) portion of its cycle.
  UpdateSun(f32),

  /// Provide a block of terrain to a client.
  AddBlock(BlockPosition, TerrainBlock, LODIndex),
}

/// Spawn a new thread to send messages to a socket and wait for acks.
pub fn spark_socket_sender<T>(url: String) -> (Sender<T>, Endpoint)
  where T: Send + Encodable + Debug
{
  let mut socket = Socket::new(Protocol::Push).unwrap();
  let endpoint = socket.connect(url.as_slice()).unwrap();

  let (send, recv) = channel();

  Thread::spawn(move || {
    loop {
      process_channel(
        &recv,
        |request| {
          let request = json::encode(&request).unwrap();
          if let Err(e) = socket.write_all(request.as_bytes()) {
            panic!("Error sending message: {:?}", e);
          }
          true
        }
      );

      println!("thread done!");

      timer::sleep(Duration::milliseconds(0));
    }
  });

  (send, endpoint)
}

/// Spawn a new thread to read messages from a socket and ack.
pub fn spark_socket_receiver<T>(url: String) -> (Receiver<T>, Endpoint)
  where T: Send + Decodable
{
  let mut socket = Socket::new(Protocol::Pull).unwrap();
  let endpoint = socket.bind(url.as_slice()).unwrap();

  let (send, recv) = channel();

  Thread::spawn(move || {
    loop {
      process_socket(
        &mut socket,
        |t| {
          send.send(t).unwrap();
          true
        },
      );

      timer::sleep(Duration::milliseconds(0));
    }
  });

  (recv, endpoint)
}
<commit_msg>Remove debug println.<commit_after>//! Defines the messages passed between client and server.

use block_position::BlockPosition;
use entity::EntityId;
use lod::LODIndex;
use nalgebra::{Vec2, Vec3, Pnt3};
use nanomsg::{Endpoint, Socket, Protocol};
use process_events::{process_channel, process_socket};
use rustc_serialize::{Encodable, Decodable, json};
use std::fmt::Debug;
use std::old_io::timer;
use std::sync::mpsc::{channel, Sender, Receiver};
use std::time::duration::Duration;
use std::thread::Thread;
use terrain_block::TerrainBlock;
use vertex::ColoredVertex;

#[derive(Debug, Clone)]
#[derive(RustcDecodable, RustcEncodable)]
/// Messages the client sends to the server.
pub enum ClientToServer {
  /// Notify the server that the client exists, and provide a "return address".
  Init(String),
  /// Add a vector the player's acceleration.
  Walk(Vec3<f32>),
  /// Rotate the player by some amount.
  RotatePlayer(Vec2<f32>),
  /// [Try to] start a jump for the player.
  StartJump,
  /// [Try to] stop a jump for the player.
  StopJump,
  /// Ask the server to send a block of terrain.
  RequestBlock(BlockPosition, LODIndex),
}

#[derive(Debug, Clone)]
#[derive(RustcDecodable, RustcEncodable)]
/// Messages the server sends to the client.
pub enum ServerToClient {
  /// Update the player's position.
  UpdatePlayer(Pnt3<f32>),

  /// Tell the client to add a new mob with the given mesh.
  AddMob(EntityId, Vec<ColoredVertex>),
  /// Update the client's view of a mob with a given mesh.
  UpdateMob(EntityId, Vec<ColoredVertex>),

  /// The sun as a [0, 1) portion of its cycle.
  UpdateSun(f32),

  /// Provide a block of terrain to a client.
  AddBlock(BlockPosition, TerrainBlock, LODIndex),
}

/// Spawn a new thread to send messages to a socket and wait for acks.
pub fn spark_socket_sender<T>(url: String) -> (Sender<T>, Endpoint)
  where T: Send + Encodable + Debug
{
  let mut socket = Socket::new(Protocol::Push).unwrap();
  let endpoint = socket.connect(url.as_slice()).unwrap();

  let (send, recv) = channel();

  Thread::spawn(move || {
    loop {
      process_channel(
        &recv,
        |request| {
          let request = json::encode(&request).unwrap();
          if let Err(e) = socket.write_all(request.as_bytes()) {
            panic!("Error sending message: {:?}", e);
          }
          true
        }
      );

      timer::sleep(Duration::milliseconds(0));
    }
  });

  (send, endpoint)
}

/// Spawn a new thread to read messages from a socket and ack.
pub fn spark_socket_receiver<T>(url: String) -> (Receiver<T>, Endpoint)
  where T: Send + Decodable
{
  let mut socket = Socket::new(Protocol::Pull).unwrap();
  let endpoint = socket.bind(url.as_slice()).unwrap();

  let (send, recv) = channel();

  Thread::spawn(move || {
    loop {
      process_socket(
        &mut socket,
        |t| {
          send.send(t).unwrap();
          true
        },
      );

      timer::sleep(Duration::milliseconds(0));
    }
  });

  (recv, endpoint)
}
<|endoftext|>


<commit_before>//! termion is a pure Rust library for reading, manipulating, and handling terminals.
//!
//! This crate is not stable, yet. However, if you do want stability, you should specify the
//! revision (commit hash) in your `Cargo.toml`, this way builds are complete reproducible, and won't
//! break.
#![warn(missing_docs)]

#[cfg(not(target_os = "redox"))]
extern crate libc;

#[cfg(not(target_os = "redox"))]
mod termios;

mod control;
pub use control::TermWrite;

mod async;
pub use async::{AsyncReader, async_stdin};

mod input;
pub use input::{TermRead, Key};
#[cfg(feature = "nightly")]
pub use input::Keys;

mod raw;
pub use raw::{IntoRawMode, RawTerminal};

mod size;
pub use size::terminal_size;

mod color;
pub use color::Color;

mod style;
pub use style::Style;
<commit_msg>Fix build with 'nightly' feature<commit_after>//! termion is a pure Rust library for reading, manipulating, and handling terminals.
//!
//! This crate is not stable, yet. However, if you do want stability, you should specify the
//! revision (commit hash) in your `Cargo.toml`, this way builds are complete reproducible, and won't
//! break.
#![warn(missing_docs)]

#![cfg_attr(feature = "nightly", feature(io))]

#[cfg(not(target_os = "redox"))]
extern crate libc;

#[cfg(not(target_os = "redox"))]
mod termios;

mod control;
pub use control::TermWrite;

mod async;
pub use async::{AsyncReader, async_stdin};

mod input;
pub use input::{TermRead, Key};
#[cfg(feature = "nightly")]
pub use input::Keys;

mod raw;
pub use raw::{IntoRawMode, RawTerminal};

mod size;
pub use size::terminal_size;

mod color;
pub use color::Color;

mod style;
pub use style::Style;
<|endoftext|>