<commit_before>#[macro_use]
extern crate enum_map;

use enum_map::{EnumMap, IntoIter};

use std::cell::RefCell;
use std::collections::HashSet;

#[derive(Copy, Clone, Debug, EnumMap, PartialEq)]
enum Example {
    A,
    B,
    C,
}

#[test]
fn test_bool() {
    let mut map = enum_map! { false => 24, true => 42 };
    assert_eq!(map[false], 24);
    assert_eq!(map[true], 42);
    map[false] += 1;
    assert_eq!(map[false], 25);
    for (key, item) in &mut map {
        if !key {
            *item += 1;
        }
    }
    assert_eq!(map[false], 26);
    assert_eq!(map[true], 42);
}

#[test]
fn test_option_bool() {
    let mut map = enum_map! { None => 1, Some(false) => 2, Some(true) => 3};
    assert_eq!(map[None], 1);
    assert_eq!(map[Some(false)], 2);
    assert_eq!(map[Some(true)], 3);
    map[None] = 4;
    map[Some(false)] = 5;
    map[Some(true)] = 6;
    assert_eq!(map[None], 4);
    assert_eq!(map[Some(false)], 5);
    assert_eq!(map[Some(true)], 6);
    assert_eq!(map.as_slice(), [4, 5, 6]);
    let expected = [(None, 4), (Some(false), 5), (Some(true), 6)];
    assert_eq!(map.into_iter().collect::<Vec<_>>(), expected);
}

#[test]
fn test_clone() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(map.clone(), map);
}

#[test]
fn test_debug() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(format!("{:?}", map), "{false: 3, true: 5}");
}

#[test]
fn test_hash() {
    let map = enum_map! { false => 3, true => 5 };
    let mut set = HashSet::new();
    set.insert(map);
    assert!(set.contains(&map));
}

#[test]
fn discriminants() {
    #[derive(Debug, EnumMap, PartialEq)]
    enum Discriminants {
        A = 2000,
        B = 3000,
        C = 1000,
    }
    let mut map = EnumMap::new();
    map[Discriminants::A] = 3;
    map[Discriminants::B] = 2;
    map[Discriminants::C] = 1;
    let mut pairs = map.iter();
    assert_eq!(pairs.next(), Some((Discriminants::A, &3)));
    assert_eq!(pairs.next(), Some((Discriminants::B, &2)));
    assert_eq!(pairs.next(), Some((Discriminants::C, &1)));
    assert_eq!(pairs.next(), None);
}

#[test]
fn extend() {
    let mut map = enum_map! { _ => 0 };
    map.extend(vec![(Example::A, 3)]);
    map.extend(vec![(&Example::B, &4)]);
    assert_eq!(
        map,
        enum_map! { Example:: A => 3, Example:: B => 4, Example::C => 0 }
    );
}

#[test]
fn huge_enum() {
    #[derive(EnumMap)]
    enum Example {
        A,
        B,
        C,
        D,
        E,
        F,
        G,
        H,
        I,
        J,
        K,
        L,
        M,
        N,
        O,
        P,
        Q,
        R,
        S,
        T,
        U,
        V,
        W,
        X,
        Y,
        Z,
        Aa,
        Bb,
        Cc,
        Dd,
        Ee,
        Ff,
        Gg,
        Hh,
        Ii,
        Jj,
        Kk,
        Ll,
        Mm,
        Nn,
        Oo,
        Pp,
        Qq,
        Rr,
        Ss,
        Tt,
        Uu,
        Vv,
        Ww,
        Xx,
        Yy,
        Zz,
    }

    let map = enum_map! { _ => 2 };
    assert_eq!(map[Example::Xx], 2);
}

#[test]
fn iterator_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter()
            .len(),
        3
    );
}

#[test]
fn iter_mut_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter_mut()
            .len(),
        3
    );
}

#[test]
fn iterator_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter()
            .next_back(),
        Some((Example::C, &3))
    );
}

#[test]
fn iter_mut_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter()
            .next_back(),
        Some((Example::C, &mut 3))
    );
}

#[test]
fn into_iter() {
    let mut iter = enum_map! { true => 5, false => 7 }.into_iter();
    assert_eq!(iter.next(), Some((false, 7)));
    assert_eq!(iter.next(), Some((true, 5)));
    assert_eq!(iter.next(), None);
    assert_eq!(iter.next(), None);
}

struct DropReporter<'a> {
    into: &'a RefCell<Vec<usize>>,
    value: usize,
}

impl<'a> Drop for DropReporter<'a> {
    fn drop(&mut self) {
        self.into.borrow_mut().push(self.value);
    }
}

#[test]
fn into_iter_drop() {
    let dropped = RefCell::new(Vec::new());
    let mut a: IntoIter<Example, _> = enum_map! {
        k => DropReporter {
            into: &dropped,
            value: k as usize,
        },
    }.into_iter();
    assert_eq!(a.next().unwrap().0, Example::A);
    assert_eq!(*dropped.borrow(), &[0]);
    drop(a);
    assert_eq!(*dropped.borrow(), &[0, 1, 2]);
}

#[test]
fn test_u8() {
    let mut map = enum_map! { b'a' => 4, _ => 0 };
    map[b'c'] = 3;
    assert_eq!(map[b'a'], 4);
    assert_eq!(map[b'b'], 0);
    assert_eq!(map[b'c'], 3);
}

#[derive(EnumMap)]
enum Void {}

#[test]
fn empty_map() {
    let void: EnumMap<Void, Void> = enum_map!{};
    assert!(void.is_empty());
}

#[test]
#[should_panic]
fn empty_value() {
    let _void: EnumMap<bool, Void> = enum_map! { _ => unreachable!() };
}
<commit_msg>Forgot to use iter_mut in iter_mut test<commit_after>#[macro_use]
extern crate enum_map;

use enum_map::{EnumMap, IntoIter};

use std::cell::RefCell;
use std::collections::HashSet;

#[derive(Copy, Clone, Debug, EnumMap, PartialEq)]
enum Example {
    A,
    B,
    C,
}

#[test]
fn test_bool() {
    let mut map = enum_map! { false => 24, true => 42 };
    assert_eq!(map[false], 24);
    assert_eq!(map[true], 42);
    map[false] += 1;
    assert_eq!(map[false], 25);
    for (key, item) in &mut map {
        if !key {
            *item += 1;
        }
    }
    assert_eq!(map[false], 26);
    assert_eq!(map[true], 42);
}

#[test]
fn test_option_bool() {
    let mut map = enum_map! { None => 1, Some(false) => 2, Some(true) => 3};
    assert_eq!(map[None], 1);
    assert_eq!(map[Some(false)], 2);
    assert_eq!(map[Some(true)], 3);
    map[None] = 4;
    map[Some(false)] = 5;
    map[Some(true)] = 6;
    assert_eq!(map[None], 4);
    assert_eq!(map[Some(false)], 5);
    assert_eq!(map[Some(true)], 6);
    assert_eq!(map.as_slice(), [4, 5, 6]);
    let expected = [(None, 4), (Some(false), 5), (Some(true), 6)];
    assert_eq!(map.into_iter().collect::<Vec<_>>(), expected);
}

#[test]
fn test_clone() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(map.clone(), map);
}

#[test]
fn test_debug() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(format!("{:?}", map), "{false: 3, true: 5}");
}

#[test]
fn test_hash() {
    let map = enum_map! { false => 3, true => 5 };
    let mut set = HashSet::new();
    set.insert(map);
    assert!(set.contains(&map));
}

#[test]
fn discriminants() {
    #[derive(Debug, EnumMap, PartialEq)]
    enum Discriminants {
        A = 2000,
        B = 3000,
        C = 1000,
    }
    let mut map = EnumMap::new();
    map[Discriminants::A] = 3;
    map[Discriminants::B] = 2;
    map[Discriminants::C] = 1;
    let mut pairs = map.iter();
    assert_eq!(pairs.next(), Some((Discriminants::A, &3)));
    assert_eq!(pairs.next(), Some((Discriminants::B, &2)));
    assert_eq!(pairs.next(), Some((Discriminants::C, &1)));
    assert_eq!(pairs.next(), None);
}

#[test]
fn extend() {
    let mut map = enum_map! { _ => 0 };
    map.extend(vec![(Example::A, 3)]);
    map.extend(vec![(&Example::B, &4)]);
    assert_eq!(
        map,
        enum_map! { Example:: A => 3, Example:: B => 4, Example::C => 0 }
    );
}

#[test]
fn huge_enum() {
    #[derive(EnumMap)]
    enum Example {
        A,
        B,
        C,
        D,
        E,
        F,
        G,
        H,
        I,
        J,
        K,
        L,
        M,
        N,
        O,
        P,
        Q,
        R,
        S,
        T,
        U,
        V,
        W,
        X,
        Y,
        Z,
        Aa,
        Bb,
        Cc,
        Dd,
        Ee,
        Ff,
        Gg,
        Hh,
        Ii,
        Jj,
        Kk,
        Ll,
        Mm,
        Nn,
        Oo,
        Pp,
        Qq,
        Rr,
        Ss,
        Tt,
        Uu,
        Vv,
        Ww,
        Xx,
        Yy,
        Zz,
    }

    let map = enum_map! { _ => 2 };
    assert_eq!(map[Example::Xx], 2);
}

#[test]
fn iterator_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter()
            .len(),
        3
    );
}

#[test]
fn iter_mut_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter_mut()
            .len(),
        3
    );
}

#[test]
fn iterator_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter()
            .next_back(),
        Some((Example::C, &3))
    );
}

#[test]
fn iter_mut_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter_mut()
            .next_back(),
        Some((Example::C, &mut 3))
    );
}

#[test]
fn into_iter() {
    let mut iter = enum_map! { true => 5, false => 7 }.into_iter();
    assert_eq!(iter.next(), Some((false, 7)));
    assert_eq!(iter.next(), Some((true, 5)));
    assert_eq!(iter.next(), None);
    assert_eq!(iter.next(), None);
}

struct DropReporter<'a> {
    into: &'a RefCell<Vec<usize>>,
    value: usize,
}

impl<'a> Drop for DropReporter<'a> {
    fn drop(&mut self) {
        self.into.borrow_mut().push(self.value);
    }
}

#[test]
fn into_iter_drop() {
    let dropped = RefCell::new(Vec::new());
    let mut a: IntoIter<Example, _> = enum_map! {
        k => DropReporter {
            into: &dropped,
            value: k as usize,
        },
    }.into_iter();
    assert_eq!(a.next().unwrap().0, Example::A);
    assert_eq!(*dropped.borrow(), &[0]);
    drop(a);
    assert_eq!(*dropped.borrow(), &[0, 1, 2]);
}

#[test]
fn test_u8() {
    let mut map = enum_map! { b'a' => 4, _ => 0 };
    map[b'c'] = 3;
    assert_eq!(map[b'a'], 4);
    assert_eq!(map[b'b'], 0);
    assert_eq!(map[b'c'], 3);
}

#[derive(EnumMap)]
enum Void {}

#[test]
fn empty_map() {
    let void: EnumMap<Void, Void> = enum_map!{};
    assert!(void.is_empty());
}

#[test]
#[should_panic]
fn empty_value() {
    let _void: EnumMap<bool, Void> = enum_map! { _ => unreachable!() };
}
<|endoftext|>


<commit_before>use compositor::{self, Action, Server, Shell, View};
use std::time::Duration;
use compositor::seat::Seat;
use wlroots::types::Cursor;
use wlroots::{CompositorHandle, CursorHandle, HandleResult, KeyboardHandle, Origin, PointerHandle,
              PointerHandler, XdgV6ShellState::*, pointer_events::*, WLR_BUTTON_RELEASED};

#[derive(Debug, Default)]
pub struct Pointer;

impl PointerHandler for Pointer {

    fn on_motion_absolute(&mut self, compositor: CompositorHandle, _: PointerHandle, event: &AbsoluteMotionEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.data.downcast_mut().unwrap();
            let Server { ref mut cursor,
                         ref mut seat,
                         ref mut views,
                         .. } = *server;
            with_handles!([(cursor: {&mut *cursor})] => {
                let (x, y) = event.pos();
                cursor.warp_absolute(event.device(), x, y);
            }).expect("Cursor was destroyed");
            // TODO dry me up
            match seat.action {
                Some(Action::Moving { start }) => {
                    if let Some(mut view) = view_at_pointer(views, cursor) {
                        let meta_held_down = seat.meta;
                        if meta_held_down {
                            move_view(seat, cursor, &mut view, start).expect("Could not move view");
                        }
                    }
                }
                _ => { /* TODO */ }
            }
        }).unwrap();
    }

    fn on_motion(&mut self, compositor: CompositorHandle, _: PointerHandle, event: &MotionEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.into();
            let Server { ref mut cursor,
                         ref mut seat,
                         ref mut views,
                         .. } = *server;
            with_handles!([(cursor: {&mut *cursor})] => {
                let (x, y) = event.delta();
                cursor.move_to(event.device(), x, y);
            }).expect("Cursor was destroyed");
            // TODO dry me up
            match seat.action {
                Some(Action::Moving { start }) => {
                    if let Some(mut view) = view_at_pointer(views, cursor) {
                        let meta_held_down = seat.meta;
                        if meta_held_down {
                            move_view(seat, cursor, &mut view, start).expect("Could not move view");
                        }
                    }
                }
                _ => { /* TODO */ }
            }
        }).unwrap();
    }

    fn on_button(&mut self, compositor: CompositorHandle, _: PointerHandle, event: &ButtonEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.into();
            let Server { ref mut cursor,
                         ref mut views,
                         ref mut seat,
                         ref mut keyboards,
                         .. } = *server;
            if event.state() == WLR_BUTTON_RELEASED {
                seat.action = None;
                send_pointer_button(seat, event).expect("Could not send pointer button");
                return
            }
            if let Some(view) = view_at_pointer(views, cursor) {
                focus_under_pointer(seat, &mut **keyboards, { &mut *view }).expect("Could not focus \
                                                                                view");
                let meta_held_down = seat.meta;
                if meta_held_down && event.button() == BTN_LEFT {
                    move_view(seat, cursor, view, None).expect("Could not move view");
                }
                send_pointer_button(seat, event).expect("Could not send pointer button");
            } else {
                focus_under_pointer(seat, &mut **keyboards, None).expect("Could not focus view");
            }
        }).unwrap()
    }
}

fn view_at_pointer<'view>(views: &'view mut [View],
                          cursor: &mut CursorHandle)
                          -> Option<&'view mut View> {
    for view in views {
        match view.shell.clone() {
            Shell::XdgV6(ref mut shell) => {
                let (mut sx, mut sy) = (0.0, 0.0);
                let seen = with_handles!([(shell: {&mut *shell}),
                                         (cursor: {&mut *cursor})] => {
                    let (lx, ly) = cursor.coords();
                    let Origin {x: shell_x, y: shell_y} = view.origin;
                    let (view_sx, view_sy) = (lx - shell_x as f64, ly - shell_y as f64);
                    shell.surface_at(view_sx, view_sy, &mut sx, &mut sy).is_some()
                }).ok()?;
                if seen {
                    return Some(view)
                }
            }
        }
    }
    None
}

/// Focus the view under the pointer.
fn focus_under_pointer<'view, V>(seat: &mut compositor::Seat,
                                 keyboards: &mut [KeyboardHandle],
                                 view: V)
                                 -> HandleResult<()>
    where V: Into<Option<&'view mut View>>
{
    // TODO Use those surface level coordinates to send events and shit
    match view.into() {
        None => {
            if let Some(mut focused_view) = seat.focused.take() {
                match focused_view.shell {
                    Shell::XdgV6(ref mut shell) => {
                        with_handles!([(shell: {shell})] => {
                            match shell.state() {
                                Some(&mut TopLevel(ref mut toplevel)) => {
                                    toplevel.set_activated(false)
                                },
                                _ => unimplemented!()
                            }
                        })?;
                    }
                }
            }
            with_handles!([(seat: {&mut seat.seat})] => {
                seat.keyboard_clear_focus()
            })
        }
        Some(view) => {
            seat.focused = Some(view.clone());
            for keyboard in { &mut *keyboards } {
                match &mut view.shell {
                    &mut Shell::XdgV6(ref mut shell) => {
                        with_handles!([(seat: {&mut seat.seat}),
                                      (shell: {&mut *shell}),
                                      (surface: {shell.surface()}),
                                      (keyboard: {keyboard})] => {
                    match shell.state() {
                        Some(&mut TopLevel(ref mut toplevel)) => {
                            // TODO Don't send this for each keyboard!
                            toplevel.set_activated(true);
                        },
                        _ => unimplemented!()
                    }
                    seat.keyboard_notify_enter(surface,
                                               &mut keyboard.keycodes(),
                                               &mut keyboard.get_modifier_masks())
                })?;
                    }
                }
            }
            Ok(())
        }
    }
}

/// Start moving a view if you haven't already by passing `start: None`.
///
/// Otherwise, update the view position relative to where the move started,
/// which is provided by Action::Moving.
fn move_view<O>(seat: &mut compositor::Seat,
                cursor: &mut CursorHandle,
                view: &mut View,
                start: O)
                -> HandleResult<()>
    where O: Into<Option<Origin>>
{
    let Origin { x: shell_x,
                 y: shell_y } = view.origin;
    with_handles!([(cursor: {cursor})] => {
        let (lx, ly) = cursor.coords();
        match start.into() {
            None => {
                let (view_sx, view_sy) = (lx - shell_x as f64, ly - shell_y as f64);
                let start = Origin::new(view_sx as _, view_sy as _);
                seat.action = Some(Action::Moving{start});
            }
            Some(start) => {
                let pos = Origin::new(lx as i32 - start.x, ly as i32 - start.y);
                view.origin = pos;
            }
        };
    })
}

fn send_pointer_button(seat: &mut compositor::Seat, event: &ButtonEvent) -> HandleResult<()> {
    with_handles!([(seat: {&mut seat.seat})] => {
        seat.pointer_notify_button(Duration::from_millis(event.time_msec() as _),
                                   event.button(),
                                   event.state() as u32);
    })
}
<commit_msg>cursor update position function<commit_after>use compositor::{self, Action, Server, Shell, View};
use std::time::Duration;
use compositor::seat::Seat;
use wlroots::types::Cursor;
use wlroots::{CompositorHandle, HandleResult, KeyboardHandle, Origin, PointerHandle,
              PointerHandler, XdgV6ShellState::*, pointer_events::*, WLR_BUTTON_RELEASED};

#[derive(Debug, Default)]
pub struct Pointer;

impl PointerHandler for Pointer {

    fn on_motion_absolute(&mut self, compositor: CompositorHandle, _: PointerHandle, event: &AbsoluteMotionEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.data.downcast_mut().unwrap();
            let Server { ref mut cursor,
                         ref mut seat,
                         ref mut views,
                         .. } = *server;
            with_handles!([(cursor: {&mut *cursor})] => {
                let (x, y) = event.pos();
                cursor.warp_absolute(event.device(), x, y);
                update_cursor_position(cursor, seat, views);
            }).expect("Cursor was destroyed");
        }).unwrap();
    }

    fn on_motion(&mut self, compositor: CompositorHandle, _: PointerHandle, event: &MotionEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.into();
            let Server { ref mut cursor,
                         ref mut seat,
                         ref mut views,
                         .. } = *server;
            with_handles!([(cursor: {&mut *cursor})] => {
                let (x, y) = event.delta();
                cursor.move_to(event.device(), x, y);
                update_cursor_position(cursor, seat, views);
            }).expect("Cursor was destroyed");
        }).unwrap();
    }

    fn on_button(&mut self, compositor: CompositorHandle, _: PointerHandle, event: &ButtonEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.into();
            let Server { ref mut cursor,
                         ref mut views,
                         ref mut seat,
                         ref mut keyboards,
                         .. } = *server;
            with_handles!([(cursor: {&mut *cursor})] => {
                if event.state() == WLR_BUTTON_RELEASED {
                    seat.action = None;
                    send_pointer_button(seat, event).expect("Could not send pointer button");
                    return
                }
                if let Some(view) = view_at_pointer(views, cursor) {
                    focus_under_pointer(seat, &mut **keyboards, { &mut *view }).expect("Could not focus \
                                                                                view");
                    let meta_held_down = seat.meta;
                    if meta_held_down && event.button() == BTN_LEFT {
                        move_view(seat, cursor, view, None);
                    }
                    send_pointer_button(seat, event).expect("Could not send pointer button");
                } else {
                    focus_under_pointer(seat, &mut **keyboards, None).expect("Could not focus view");
                }
            }).unwrap()
        }).unwrap()
    }
}

/// After the cursor has been warped, do all the things needed to change the cursor from the old
/// position to the new position.
fn update_cursor_position(cursor: &mut Cursor, seat: &mut Seat, views: &mut [View]) {
    match seat.action {
        Some(Action::Moving { start }) => {
            if let Some(mut view) = view_at_pointer(views, cursor) {
                let meta_held_down = seat.meta;
                if meta_held_down {
                    move_view(seat, cursor, &mut view, start);
                }
            }
        }
        _ => { /* TODO */ }
    }
}

fn view_at_pointer<'view>(views: &'view mut [View],
                          cursor: &mut Cursor)
                          -> Option<&'view mut View> {
    for view in views {
        match view.shell.clone() {
            Shell::XdgV6(ref mut shell) => {
                let (mut sx, mut sy) = (0.0, 0.0);
                let seen = with_handles!([(shell: {&mut *shell})] => {
                    let (lx, ly) = cursor.coords();
                    let Origin {x: shell_x, y: shell_y} = view.origin;
                    let (view_sx, view_sy) = (lx - shell_x as f64, ly - shell_y as f64);
                    shell.surface_at(view_sx, view_sy, &mut sx, &mut sy).is_some()
                }).ok()?;
                if seen {
                    return Some(view)
                }
            }
        }
    }
    None
}

/// Focus the view under the pointer.
fn focus_under_pointer<'view, V>(seat: &mut compositor::Seat,
                                 keyboards: &mut [KeyboardHandle],
                                 view: V)
                                 -> HandleResult<()>
    where V: Into<Option<&'view mut View>>
{
    // TODO Use those surface level coordinates to send events and shit
    match view.into() {
        None => {
            if let Some(mut focused_view) = seat.focused.take() {
                match focused_view.shell {
                    Shell::XdgV6(ref mut shell) => {
                        with_handles!([(shell: {shell})] => {
                            match shell.state() {
                                Some(&mut TopLevel(ref mut toplevel)) => {
                                    toplevel.set_activated(false)
                                },
                                _ => unimplemented!()
                            }
                        })?;
                    }
                }
            }
            with_handles!([(seat: {&mut seat.seat})] => {
                seat.keyboard_clear_focus()
            })
        }
        Some(view) => {
            seat.focused = Some(view.clone());
            for keyboard in { &mut *keyboards } {
                match &mut view.shell {
                    &mut Shell::XdgV6(ref mut shell) => {
                        with_handles!([(seat: {&mut seat.seat}),
                                      (shell: {&mut *shell}),
                                      (surface: {shell.surface()}),
                                      (keyboard: {keyboard})] => {
                    match shell.state() {
                        Some(&mut TopLevel(ref mut toplevel)) => {
                            // TODO Don't send this for each keyboard!
                            toplevel.set_activated(true);
                        },
                        _ => unimplemented!()
                    }
                    seat.keyboard_notify_enter(surface,
                                               &mut keyboard.keycodes(),
                                               &mut keyboard.get_modifier_masks())
                })?;
                    }
                }
            }
            Ok(())
        }
    }
}

/// Start moving a view if you haven't already by passing `start: None`.
///
/// Otherwise, update the view position relative to where the move started,
/// which is provided by Action::Moving.
fn move_view<O>(seat: &mut compositor::Seat,
                cursor: &mut Cursor,
                view: &mut View,
                start: O)
    where O: Into<Option<Origin>>
{
    let Origin { x: shell_x,
    y: shell_y } = view.origin;
    let (lx, ly) = cursor.coords();
    match start.into() {
        None => {
            let (view_sx, view_sy) = (lx - shell_x as f64, ly - shell_y as f64);
            let start = Origin::new(view_sx as _, view_sy as _);
            seat.action = Some(Action::Moving{start});
        }
        Some(start) => {
            let pos = Origin::new(lx as i32 - start.x, ly as i32 - start.y);
            view.origin = pos;
        }
    };
}

fn send_pointer_button(seat: &mut compositor::Seat, event: &ButtonEvent) -> HandleResult<()> {
    with_handles!([(seat: {&mut seat.seat})] => {
        seat.pointer_notify_button(Duration::from_millis(event.time_msec() as _),
                                   event.button(),
                                   event.state() as u32);
    })
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate getopts;
extern crate rocket;
extern crate serde_json;
#[macro_use] extern crate rocket_contrib;

extern crate pombase;

use std::sync::Mutex;
use std::process;
use std::env;

use getopts::Options;

use rocket_contrib::{Json, Value};

use pombase::api::query::Query;
use pombase::api::result::Result;
use pombase::api::query_exec::QueryExec;
use pombase::api::server_data::ServerData;

#[post("/query", data="<q>", format = "application/json")]
fn query_post(q: Json<Query>, state: rocket::State<Mutex<QueryExec>>) -> Option<Json<Result>> {
    let query_exec = state.lock().expect("failed to lock");
    Some(Json(query_exec.exec(&q.into_inner())))
}

#[get ("/reload")]
fn reload(state: rocket::State<Mutex<QueryExec>>) {
    let mut query_exec = state.lock().expect("failed to lock");
    print!("reloading ...\n");
    query_exec.reload();
}

#[get ("/ping")]
fn ping() -> Option<String> {
    Some("OK".into())
}

#[error(404)]
fn not_found() -> Json<Value> {
    Json(json!({
        "status": "error",
        "reason": "Resource was not found."
    }))
}

const PKG_NAME: &str = env!("CARGO_PKG_NAME");
const VERSION: &str = env!("CARGO_PKG_VERSION");

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

fn main() {
    print!("{} v{}\n", PKG_NAME, VERSION);

    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();

    opts.optflag("h", "help", "print this help message");
    opts.optopt("c", "config-file", "Configuration file name", "CONFIG");
    opts.optopt("m", "search-maps", "Search data", "MAPS_JSON_FILE");
    opts.optopt("s", "gene-subsets", "Gene subset data", "SUBSETS_JSON_FILE");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!("Invalid options\n{}", f)
    };

    let program = args[0].clone();

    if matches.opt_present("help") {
        print_usage(&program, opts);
        process::exit(0);
    }

    if !matches.opt_present("config-file") {
        print!("no -c|--config-file option\n");
        print_usage(&program, opts);
        process::exit(1);
    }
    if !matches.opt_present("search-maps") {
        print!("no --search-maps|-m option\n");
        print_usage(&program, opts);
        process::exit(1);
    }
    if !matches.opt_present("gene-subsets") {
        print!("no --gene-subsets|-s option\n");
        print_usage(&program, opts);
        process::exit(1);
    }

    let search_maps_filename = matches.opt_str("m").unwrap();
    let gene_subsets_filename = matches.opt_str("s").unwrap();
    println!("Reading data files ...");

    let config_file_name = matches.opt_str("c").unwrap();
    let server_data = ServerData::new(&config_file_name, &search_maps_filename,
                                      &gene_subsets_filename);
    let query_exec = QueryExec::new(server_data);

    println!("Starting server ...");
    rocket::ignite()
        .mount("/", routes![query_post, reload, ping])
        .catch(errors![not_found])
        .manage(Mutex::new(query_exec))
        .launch();
}
<commit_msg>Add the version to the response from /ping<commit_after>#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate getopts;
extern crate rocket;
extern crate serde_json;
#[macro_use] extern crate rocket_contrib;

extern crate pombase;

use std::sync::Mutex;
use std::process;
use std::env;

use getopts::Options;

use rocket_contrib::{Json, Value};

use pombase::api::query::Query;
use pombase::api::result::Result;
use pombase::api::query_exec::QueryExec;
use pombase::api::server_data::ServerData;

const PKG_NAME: &str = env!("CARGO_PKG_NAME");
const VERSION: &str = env!("CARGO_PKG_VERSION");

#[post("/query", data="<q>", format = "application/json")]
fn query_post(q: Json<Query>, state: rocket::State<Mutex<QueryExec>>) -> Option<Json<Result>> {
    let query_exec = state.lock().expect("failed to lock");
    Some(Json(query_exec.exec(&q.into_inner())))
}

#[get ("/reload")]
fn reload(state: rocket::State<Mutex<QueryExec>>) {
    let mut query_exec = state.lock().expect("failed to lock");
    print!("reloading ...\n");
    query_exec.reload();
}

#[get ("/ping")]
fn ping() -> Option<String> {
    Some(String::from("OK") + " " + PKG_NAME + " " + VERSION)
}

#[error(404)]
fn not_found() -> Json<Value> {
    Json(json!({
        "status": "error",
        "reason": "Resource was not found."
    }))
}

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

fn main() {
    print!("{} v{}\n", PKG_NAME, VERSION);

    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();

    opts.optflag("h", "help", "print this help message");
    opts.optopt("c", "config-file", "Configuration file name", "CONFIG");
    opts.optopt("m", "search-maps", "Search data", "MAPS_JSON_FILE");
    opts.optopt("s", "gene-subsets", "Gene subset data", "SUBSETS_JSON_FILE");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!("Invalid options\n{}", f)
    };

    let program = args[0].clone();

    if matches.opt_present("help") {
        print_usage(&program, opts);
        process::exit(0);
    }

    if !matches.opt_present("config-file") {
        print!("no -c|--config-file option\n");
        print_usage(&program, opts);
        process::exit(1);
    }
    if !matches.opt_present("search-maps") {
        print!("no --search-maps|-m option\n");
        print_usage(&program, opts);
        process::exit(1);
    }
    if !matches.opt_present("gene-subsets") {
        print!("no --gene-subsets|-s option\n");
        print_usage(&program, opts);
        process::exit(1);
    }

    let search_maps_filename = matches.opt_str("m").unwrap();
    let gene_subsets_filename = matches.opt_str("s").unwrap();
    println!("Reading data files ...");

    let config_file_name = matches.opt_str("c").unwrap();
    let server_data = ServerData::new(&config_file_name, &search_maps_filename,
                                      &gene_subsets_filename);
    let query_exec = QueryExec::new(server_data);

    println!("Starting server ...");
    rocket::ignite()
        .mount("/", routes![query_post, reload, ping])
        .catch(errors![not_found])
        .manage(Mutex::new(query_exec))
        .launch();
}
<|endoftext|>


<commit_before>use super::error::{Error, Result};
use super::generate::parse_grammar::GrammarJSON;
use std::ffi::{OsStr, OsString};
use std::fs;
use std::path::Path;
use std::process::Command;

pub fn get_grammar_name(src_dir: &Path) -> Result<String> {
    let grammar_json_path = src_dir.join("grammar.json");
    let grammar_json = fs::read_to_string(&grammar_json_path).map_err(Error::wrap(|| {
        format!("Failed to read grammar file {:?}", grammar_json_path)
    }))?;
    let grammar: GrammarJSON = serde_json::from_str(&grammar_json).map_err(Error::wrap(|| {
        format!("Failed to parse grammar file {:?}", grammar_json_path)
    }))?;
    Ok(grammar.name)
}

pub fn compile_language_to_wasm(language_dir: &Path, force_docker: bool) -> Result<()> {
    let src_dir = language_dir.join("src");
    let grammar_name = get_grammar_name(&src_dir)?;
    let output_filename = format!("tree-sitter-{}.wasm", grammar_name);

    let mut command;
    if !force_docker && Command::new("emcc").output().is_ok() {
        command = Command::new("emcc");
        command.current_dir(&language_dir);
    } else if Command::new("docker").output().is_ok() {
        command = Command::new("docker");
        command.args(&["run", "--rm"]);

        // Mount the parser directory as a volume
        let mut volume_string;
        if let (Some(parent), Some(filename)) = (language_dir.parent(), language_dir.file_name()) {
            volume_string = OsString::from(parent);
            volume_string.push(":/src:Z");
            command.arg("--workdir");
            command.arg(&Path::new("/src").join(filename));
        } else {
            volume_string = OsString::from(language_dir);
            volume_string.push(":/src:Z");
            command.args(&["--workdir", "/src"]);
        }

        command.args(&[OsStr::new("--volume"), &volume_string]);

        // Get the current user id so that files created in the docker container will have
        // the same owner.
        if cfg!(unix) {
            let user_id_output = Command::new("id")
                .arg("-u")
                .output()
                .map_err(Error::wrap(|| "Failed to get get current user id"))?;
            let user_id = String::from_utf8_lossy(&user_id_output.stdout);
            let user_id = user_id.trim();
            command.args(&["--user", user_id]);
        }

        // Run `emcc` in a container using the `emscripten-slim` image
        command.args(&["trzeci/emscripten-slim", "emcc"]);
    } else {
        return Error::err(
            "You must have either emcc or docker on your PATH to run this command".to_string(),
        );
    }

    command.args(&[
        "-o",
        &output_filename,
        "-Os",
        "-s",
        "WASM=1",
        "-s",
        "SIDE_MODULE=1",
        "-s",
        "TOTAL_MEMORY=33554432",
        "-s",
        "NODEJS_CATCH_EXIT=0",
        "-s",
        &format!("EXPORTED_FUNCTIONS=[\"_tree_sitter_{}\"]", grammar_name),
        "-fno-exceptions",
        "-I",
        "src",
    ]);

    let parser_c_path = src_dir.join("parser.c");
    let scanner_c_path = src_dir.join("scanner.c");
    let scanner_cc_path = src_dir.join("scanner.cc");
    let scanner_cpp_path = src_dir.join("scanner.cpp");

    if scanner_cc_path.exists() {
        command.arg("-xc++").arg(&scanner_cc_path);
    } else if scanner_cpp_path.exists() {
        command.arg("-xc++").arg(&scanner_cpp_path);
    } else if scanner_c_path.exists() {
        command.arg(&scanner_c_path);
    }

    command.arg(&parser_c_path);

    let output = command
        .output()
        .map_err(Error::wrap(|| "Failed to run emcc command"))?;
    if !output.status.success() {
        return Err(Error::from(format!(
            "emcc command failed - {}",
            String::from_utf8_lossy(&output.stderr)
        )));
    }

    // Move the created `.wasm` file into the current working directory.
    fs::rename(&language_dir.join(&output_filename), &output_filename).map_err(Error::wrap(
        || format!("Couldn't find output file {:?}", output_filename),
    ))?;

    Ok(())
}
<commit_msg>Fix build-wasm command<commit_after>use super::error::{Error, Result};
use super::generate::parse_grammar::GrammarJSON;
use std::ffi::{OsStr, OsString};
use std::fs;
use std::path::Path;
use std::process::Command;

pub fn get_grammar_name(src_dir: &Path) -> Result<String> {
    let grammar_json_path = src_dir.join("grammar.json");
    let grammar_json = fs::read_to_string(&grammar_json_path).map_err(Error::wrap(|| {
        format!("Failed to read grammar file {:?}", grammar_json_path)
    }))?;
    let grammar: GrammarJSON = serde_json::from_str(&grammar_json).map_err(Error::wrap(|| {
        format!("Failed to parse grammar file {:?}", grammar_json_path)
    }))?;
    Ok(grammar.name)
}

pub fn compile_language_to_wasm(language_dir: &Path, force_docker: bool) -> Result<()> {
    let src_dir = language_dir.join("src");
    let grammar_name = get_grammar_name(&src_dir)?;
    let output_filename = format!("tree-sitter-{}.wasm", grammar_name);

    let mut command;
    if !force_docker && Command::new("emcc").output().is_ok() {
        command = Command::new("emcc");
        command.current_dir(&language_dir);
    } else if Command::new("docker").output().is_ok() {
        command = Command::new("docker");
        command.args(&["run", "--rm"]);

        // Mount the parser directory as a volume
        let mut volume_string;
        if let (Some(parent), Some(filename)) = (language_dir.parent(), language_dir.file_name()) {
            volume_string = OsString::from(parent);
            volume_string.push(":/src:Z");
            command.arg("--workdir");
            command.arg(&Path::new("/src").join(filename));
        } else {
            volume_string = OsString::from(language_dir);
            volume_string.push(":/src:Z");
            command.args(&["--workdir", "/src"]);
        }

        command.args(&[OsStr::new("--volume"), &volume_string]);

        // Get the current user id so that files created in the docker container will have
        // the same owner.
        if cfg!(unix) {
            let user_id_output = Command::new("id")
                .arg("-u")
                .output()
                .map_err(Error::wrap(|| "Failed to get get current user id"))?;
            let user_id = String::from_utf8_lossy(&user_id_output.stdout);
            let user_id = user_id.trim();
            command.args(&["--user", user_id]);
        }

        // Run `emcc` in a container using the `emscripten-slim` image
        command.args(&["trzeci/emscripten-slim", "emcc"]);
    } else {
        return Error::err(
            "You must have either emcc or docker on your PATH to run this command".to_string(),
        );
    }

    command.args(&[
        "-o",
        &output_filename,
        "-Os",
        "-s",
        "WASM=1",
        "-s",
        "SIDE_MODULE=1",
        "-s",
        "TOTAL_MEMORY=33554432",
        "-s",
        "NODEJS_CATCH_EXIT=0",
        "-s",
        &format!("EXPORTED_FUNCTIONS=[\"_tree_sitter_{}\"]", grammar_name),
        "-fno-exceptions",
        "-I",
        "src",
    ]);

    let src = Path::new("src");
    let parser_c_path = src.join("parser.c");
    let scanner_c_path = src.join("scanner.c");
    let scanner_cc_path = src.join("scanner.cc");
    let scanner_cpp_path = src.join("scanner.cpp");

    if scanner_cc_path.exists() {
        command.arg("-xc++").arg(&scanner_cc_path);
    } else if scanner_cpp_path.exists() {
        command.arg("-xc++").arg(&scanner_cpp_path);
    } else if scanner_c_path.exists() {
        command.arg(&scanner_c_path);
    }

    command.arg(&parser_c_path);

    let output = command
        .output()
        .map_err(Error::wrap(|| "Failed to run emcc command"))?;
    if !output.status.success() {
        return Err(Error::from(format!(
            "emcc command failed - {}",
            String::from_utf8_lossy(&output.stderr)
        )));
    }

    // Move the created `.wasm` file into the current working directory.
    fs::rename(&language_dir.join(&output_filename), &output_filename).map_err(Error::wrap(
        || format!("Couldn't find output file {:?}", output_filename),
    ))?;

    Ok(())
}
<|endoftext|>


<commit_before>//! UDP relay proxy server

use std::{
    io::{self, Cursor},
    net::{IpAddr, Ipv4Addr, SocketAddr},
    sync::Arc,
    time::Duration,
};

use bytes::BytesMut;
use futures::{self, future, stream::FuturesUnordered, FutureExt, StreamExt};
use log::{debug, error, info, trace};
use lru_time_cache::{Entry, LruCache};
use tokio::{
    self,
    net::udp::{RecvHalf, SendHalf},
    sync::{mpsc, oneshot, Mutex},
    time,
};

use crate::{
    config::ServerConfig,
    context::{Context, SharedContext},
    relay::{dns_resolver::resolve_bind_addr, socks5::Address, utils::try_timeout},
};

use super::{
    crypto_io::{decrypt_payload, encrypt_payload},
    utils::create_socket,
    DEFAULT_TIMEOUT,
    MAXIMUM_UDP_PAYLOAD_SIZE,
};

struct UdpAssociationWatcher(oneshot::Sender<()>);

// Represent a UDP association
#[derive(Clone)]
struct UdpAssociation {
    // local -> remote Queue
    // Drops tx, will close local -> remote task
    tx: mpsc::Sender<Vec<u8>>,

    // local <- remote task life watcher
    watcher: Arc<UdpAssociationWatcher>,
}

impl UdpAssociation {
    /// Create an association with addr
    async fn associate(
        context: SharedContext,
        svr_cfg: Arc<ServerConfig>,
        src_addr: SocketAddr,
        mut response_tx: mpsc::Sender<(SocketAddr, BytesMut)>,
    ) -> io::Result<UdpAssociation> {
        debug!("created UDP Association for {}", src_addr);

        // Create a socket for receiving packets
        let local_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0);
        let remote_udp = create_socket(&local_addr).await?;

        // Create a channel for sending packets to remote
        // FIXME: Channel size 1024?
        let (tx, mut rx) = mpsc::channel::<Vec<u8>>(1024);

        // Create a watcher for local <- remote task
        let (watcher_tx, watcher_rx) = oneshot::channel::<()>();

        let close_flag = Arc::new(UdpAssociationWatcher(watcher_tx));

        // Splits socket into sender and receiver
        let (mut receiver, mut sender) = remote_udp.split();

        let timeout = context.config().udp_timeout.unwrap_or(DEFAULT_TIMEOUT);

        // local -> remote
        let c_svr_cfg = svr_cfg.clone();
        tokio::spawn(async move {
            while let Some(pkt) = rx.recv().await {
                // pkt is already a raw packet, so just send it
                if let Err(err) =
                    UdpAssociation::relay_l2r(&*context, src_addr, &mut sender, &pkt[..], timeout, &*c_svr_cfg).await
                {
                    error!("failed to relay packet, {} -> ..., error: {}", src_addr, err);

                    // FIXME: Ignore? Or how to deal with it?
                }
            }

            debug!("UDP ASSOCIATE {} -> .. finished", src_addr);
        });

        // local <- remote
        tokio::spawn(async move {
            let transfer_fut = async move {
                loop {
                    // Read and send back to source
                    match UdpAssociation::relay_r2l(src_addr, &mut receiver, &mut response_tx, &*svr_cfg).await {
                        Ok(..) => {}
                        Err(err) => {
                            error!("failed to receive packet, {} <- .., error: {}", src_addr, err);

                            // FIXME: Don't break, or if you can find a way to drop the UdpAssociation
                            // break;
                        }
                    }
                }
            };

            // Resolved only if watcher_rx resolved
            let _ = future::select(transfer_fut.boxed(), watcher_rx.boxed()).await;

            debug!("UDP ASSOCIATE {} <- .. finished", src_addr);
        });

        Ok(UdpAssociation {
            tx,
            watcher: close_flag,
        })
    }

    /// Relay packets from local to remote
    async fn relay_l2r(
        context: &Context,
        src: SocketAddr,
        remote_udp: &mut SendHalf,
        pkt: &[u8],
        timeout: Duration,
        svr_cfg: &ServerConfig,
    ) -> io::Result<()> {
        // First of all, decrypt payload CLIENT -> SERVER
        let decrypted_pkt = match decrypt_payload(svr_cfg.method(), svr_cfg.key(), pkt) {
            Ok(Some(pkt)) => pkt,
            Ok(None) => {
                error!("failed to decrypt pkt in UDP relay, packet too short");
                let err = io::Error::new(io::ErrorKind::InvalidData, "packet too short");
                return Err(err);
            }
            Err(err) => {
                error!("failed to decrypt pkt in UDP relay: {}", err);
                let err = io::Error::new(io::ErrorKind::InvalidData, "decrypt failed");
                return Err(err);
            }
        };

        // CLIENT -> SERVER protocol: ADDRESS + PAYLOAD
        let mut cur = Cursor::new(decrypted_pkt);

        let addr = Address::read_from(&mut cur).await?;

        // Take out internal buffer for optimizing one byte copy
        let header_len = cur.position() as usize;
        let decrypted_pkt = cur.into_inner();
        let body = &decrypted_pkt[header_len..];

        let send_len = match addr {
            Address::SocketAddress(ref remote_addr) => {
                debug!(
                    "UDP ASSOCIATE {} -> {} ({}), payload length {} bytes",
                    src,
                    addr,
                    remote_addr,
                    body.len()
                );
                try_timeout(remote_udp.send_to(body, remote_addr), Some(timeout)).await?
            }
            Address::DomainNameAddress(ref dname, port) => lookup_then!(context, dname, port, false, |remote_addr| {
                match try_timeout(remote_udp.send_to(body, &remote_addr), Some(timeout)).await {
                    Ok(l) => {
                        debug!(
                            "UDP ASSOCIATE {} -> {} ({}), payload length {} bytes",
                            src,
                            addr,
                            remote_addr,
                            body.len()
                        );
                        Ok(l)
                    }
                    Err(err) => {
                        error!(
                            "UDP ASSOCIATE {} -> {} ({}), payload length {} bytes",
                            src,
                            addr,
                            remote_addr,
                            body.len()
                        );
                        Err(err)
                    }
                }
            })
            .map(|(_, l)| l)?,
        };

        assert_eq!(body.len(), send_len);

        Ok(())
    }

    /// Relay packets from remote to local
    async fn relay_r2l(
        src_addr: SocketAddr,
        remote_udp: &mut RecvHalf,
        response_tx: &mut mpsc::Sender<(SocketAddr, BytesMut)>,
        svr_cfg: &ServerConfig,
    ) -> io::Result<()> {
        // Waiting for response from server SERVER -> CLIENT
        // Packet length is limited by MAXIMUM_UDP_PAYLOAD_SIZE, excess bytes will be discarded.
        let mut remote_buf = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];
        let (remote_recv_len, remote_addr) = remote_udp.recv_from(&mut remote_buf).await?;

        debug!(
            "UDP ASSOCIATE {} <- {}, payload length {} bytes",
            src_addr, remote_addr, remote_recv_len
        );

        // FIXME: The Address should be the Address that client sent
        let addr = Address::SocketAddress(remote_addr);

        // CLIENT <- SERVER protocol: ADDRESS + PAYLOAD
        let mut send_buf = Vec::new();
        addr.write_to_buf(&mut send_buf);
        send_buf.extend_from_slice(&remote_buf[..remote_recv_len]);

        let mut encrypt_buf = BytesMut::new();
        encrypt_payload(svr_cfg.method(), svr_cfg.key(), &send_buf, &mut encrypt_buf)?;

        // Send back to src_addr
        if let Err(err) = response_tx.send((src_addr, encrypt_buf)).await {
            error!("failed to send packet into response channel, error: {}", err);

            // FIXME: What to do? Ignore?
        }

        Ok(())
    }

    // Send packet to remote
    //
    // Return `Err` if receiver have been closed
    async fn send(&mut self, pkt: Vec<u8>) {
        if let Err(..) = self.tx.send(pkt).await {
            // SHOULDn't HAPPEN
            unreachable!("UDP Association local -> remote Queue closed unexpectly");
        }
    }
}

async fn listen(context: SharedContext, svr_cfg: Arc<ServerConfig>) -> io::Result<()> {
    let listen_addr = resolve_bind_addr(&*context, svr_cfg.addr()).await?;

    let listener = create_socket(&listen_addr).await?;
    let local_addr = listener.local_addr().expect("Could not determine port bound to");
    info!("ShadowSocks UDP listening on {}", local_addr);

    let (mut r, mut w) = listener.split();

    // NOTE: Associations are only eliminated by expire time
    // So it may exhaust all available file descriptors
    let timeout = context.config().udp_timeout.unwrap_or(DEFAULT_TIMEOUT);
    let assoc_map = Arc::new(Mutex::new(LruCache::with_expiry_duration(timeout)));
    let assoc_map_cloned = assoc_map.clone();

    // FIXME: Channel size 1024?
    let (tx, mut rx) = mpsc::channel::<(SocketAddr, BytesMut)>(1024);
    tokio::spawn(async move {
        let assoc_map = assoc_map_cloned;

        while let Some((src, pkt)) = rx.recv().await {
            let cache_key = src.to_string();
            {
                let mut amap = assoc_map.lock().await;

                // Check or update expire time
                if amap.get(&cache_key).is_none() {
                    debug!(
                        "UDP association {} <-> ... is already expired, throwing away packet {} bytes",
                        src,
                        pkt.len()
                    );
                    continue;
                }
            }

            if let Err(err) = w.send_to(&pkt, &src).await {
                error!("UDP packet send failed, err: {:?}", err);
                break;
            }
        }

        // FIXME: How to stop the outer listener Future?
    });

    let mut pkt_buf = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];

    loop {
        let (recv_len, src) = match time::timeout(timeout, r.recv_from(&mut pkt_buf)).await {
            Ok(r) => r?,
            Err(..) => {
                // Cleanup expired association
                // Do not consume this iterator, it will updates expire time of items that traversed
                let mut assoc_map = assoc_map.lock().await;
                let _ = assoc_map.iter();
                continue;
            }
        };

        // Packet length is limited by MAXIMUM_UDP_PAYLOAD_SIZE, excess bytes will be discarded.
        let pkt = &pkt_buf[..recv_len];

        trace!("received UDP packet from {}, length {} bytes", src, recv_len);

        if recv_len == 0 {
            // For windows, it will generate a ICMP Port Unreachable Message
            // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recvfrom
            // Which will result in recv_from return 0.
            //
            // It cannot be solved here, because `WSAGetLastError` is already set.
            //
            // See `relay::udprelay::utils::create_socket` for more detail.
            continue;
        }

        // Check or (re)create an association
        let mut assoc = {
            // Locks the whole association map
            let mut assoc_map = assoc_map.lock().await;

            // Get or create an association
            let assoc = match assoc_map.entry(src.to_string()) {
                Entry::Occupied(oc) => oc.into_mut(),
                Entry::Vacant(vc) => vc.insert(
                    UdpAssociation::associate(context.clone(), svr_cfg.clone(), src, tx.clone())
                        .await
                        .expect("Failed to create udp association"),
                ),
            };

            // Clone the handle and release the lock.
            // Make sure we keep the critical section small
            assoc.clone()
        };

        // Send to local -> remote task
        assoc.send(pkt.to_vec()).await;
    }
}

/// Starts a UDP relay server
pub async fn run(context: SharedContext) -> io::Result<()> {
    let vec_fut = FuturesUnordered::new();

    for svr in &context.config().server {
        let svr_cfg = Arc::new(svr.clone());

        let svr_fut = listen(context.clone(), svr_cfg);
        vec_fut.push(svr_fut);
    }

    match vec_fut.into_future().await.0 {
        Some(res) => {
            error!("one of UDP servers exited unexpectly, result: {:?}", res);
            let err = io::Error::new(io::ErrorKind::Other, "server exited unexpectly");
            Err(err)
        }
        None => unreachable!(),
    }
}
<commit_msg>UDP server should filter addresses by forbidden_ip<commit_after>//! UDP relay proxy server

use std::{
    io::{self, Cursor},
    net::{IpAddr, Ipv4Addr, SocketAddr},
    sync::Arc,
    time::Duration,
};

use bytes::BytesMut;
use futures::{self, future, stream::FuturesUnordered, FutureExt, StreamExt};
use log::{debug, error, info, trace};
use lru_time_cache::{Entry, LruCache};
use tokio::{
    self,
    net::udp::{RecvHalf, SendHalf},
    sync::{mpsc, oneshot, Mutex},
    time,
};

use crate::{
    config::ServerConfig,
    context::{Context, SharedContext},
    relay::{dns_resolver::resolve_bind_addr, socks5::Address, utils::try_timeout},
};

use super::{
    crypto_io::{decrypt_payload, encrypt_payload},
    utils::create_socket,
    DEFAULT_TIMEOUT,
    MAXIMUM_UDP_PAYLOAD_SIZE,
};

struct UdpAssociationWatcher(oneshot::Sender<()>);

// Represent a UDP association
#[derive(Clone)]
struct UdpAssociation {
    // local -> remote Queue
    // Drops tx, will close local -> remote task
    tx: mpsc::Sender<Vec<u8>>,

    // local <- remote task life watcher
    watcher: Arc<UdpAssociationWatcher>,
}

impl UdpAssociation {
    /// Create an association with addr
    async fn associate(
        context: SharedContext,
        svr_cfg: Arc<ServerConfig>,
        src_addr: SocketAddr,
        mut response_tx: mpsc::Sender<(SocketAddr, BytesMut)>,
    ) -> io::Result<UdpAssociation> {
        debug!("created UDP Association for {}", src_addr);

        // Create a socket for receiving packets
        let local_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0);
        let remote_udp = create_socket(&local_addr).await?;

        // Create a channel for sending packets to remote
        // FIXME: Channel size 1024?
        let (tx, mut rx) = mpsc::channel::<Vec<u8>>(1024);

        // Create a watcher for local <- remote task
        let (watcher_tx, watcher_rx) = oneshot::channel::<()>();

        let close_flag = Arc::new(UdpAssociationWatcher(watcher_tx));

        // Splits socket into sender and receiver
        let (mut receiver, mut sender) = remote_udp.split();

        let timeout = context.config().udp_timeout.unwrap_or(DEFAULT_TIMEOUT);

        // local -> remote
        let c_svr_cfg = svr_cfg.clone();
        tokio::spawn(async move {
            while let Some(pkt) = rx.recv().await {
                // pkt is already a raw packet, so just send it
                if let Err(err) =
                    UdpAssociation::relay_l2r(&*context, src_addr, &mut sender, &pkt[..], timeout, &*c_svr_cfg).await
                {
                    error!("failed to relay packet, {} -> ..., error: {}", src_addr, err);

                    // FIXME: Ignore? Or how to deal with it?
                }
            }

            debug!("UDP ASSOCIATE {} -> .. finished", src_addr);
        });

        // local <- remote
        tokio::spawn(async move {
            let transfer_fut = async move {
                loop {
                    // Read and send back to source
                    match UdpAssociation::relay_r2l(src_addr, &mut receiver, &mut response_tx, &*svr_cfg).await {
                        Ok(..) => {}
                        Err(err) => {
                            error!("failed to receive packet, {} <- .., error: {}", src_addr, err);

                            // FIXME: Don't break, or if you can find a way to drop the UdpAssociation
                            // break;
                        }
                    }
                }
            };

            // Resolved only if watcher_rx resolved
            let _ = future::select(transfer_fut.boxed(), watcher_rx.boxed()).await;

            debug!("UDP ASSOCIATE {} <- .. finished", src_addr);
        });

        Ok(UdpAssociation {
            tx,
            watcher: close_flag,
        })
    }

    /// Relay packets from local to remote
    async fn relay_l2r(
        context: &Context,
        src: SocketAddr,
        remote_udp: &mut SendHalf,
        pkt: &[u8],
        timeout: Duration,
        svr_cfg: &ServerConfig,
    ) -> io::Result<()> {
        // First of all, decrypt payload CLIENT -> SERVER
        let decrypted_pkt = match decrypt_payload(svr_cfg.method(), svr_cfg.key(), pkt) {
            Ok(Some(pkt)) => pkt,
            Ok(None) => {
                error!("failed to decrypt pkt in UDP relay, packet too short");
                let err = io::Error::new(io::ErrorKind::InvalidData, "packet too short");
                return Err(err);
            }
            Err(err) => {
                error!("failed to decrypt pkt in UDP relay: {}", err);
                let err = io::Error::new(io::ErrorKind::InvalidData, "decrypt failed");
                return Err(err);
            }
        };

        // CLIENT -> SERVER protocol: ADDRESS + PAYLOAD
        let mut cur = Cursor::new(decrypted_pkt);

        let addr = Address::read_from(&mut cur).await?;

        // Take out internal buffer for optimizing one byte copy
        let header_len = cur.position() as usize;
        let decrypted_pkt = cur.into_inner();
        let body = &decrypted_pkt[header_len..];

        let send_len = match addr {
            Address::SocketAddress(ref remote_addr) => {
                debug!(
                    "UDP ASSOCIATE {} -> {} ({}), payload length {} bytes",
                    src,
                    addr,
                    remote_addr,
                    body.len()
                );
                try_timeout(remote_udp.send_to(body, remote_addr), Some(timeout)).await?
            }
            Address::DomainNameAddress(ref dname, port) => lookup_then!(context, dname, port, true, |remote_addr| {
                match try_timeout(remote_udp.send_to(body, &remote_addr), Some(timeout)).await {
                    Ok(l) => {
                        debug!(
                            "UDP ASSOCIATE {} -> {} ({}), payload length {} bytes",
                            src,
                            addr,
                            remote_addr,
                            body.len()
                        );
                        Ok(l)
                    }
                    Err(err) => {
                        error!(
                            "UDP ASSOCIATE {} -> {} ({}), payload length {} bytes",
                            src,
                            addr,
                            remote_addr,
                            body.len()
                        );
                        Err(err)
                    }
                }
            })
            .map(|(_, l)| l)?,
        };

        assert_eq!(body.len(), send_len);

        Ok(())
    }

    /// Relay packets from remote to local
    async fn relay_r2l(
        src_addr: SocketAddr,
        remote_udp: &mut RecvHalf,
        response_tx: &mut mpsc::Sender<(SocketAddr, BytesMut)>,
        svr_cfg: &ServerConfig,
    ) -> io::Result<()> {
        // Waiting for response from server SERVER -> CLIENT
        // Packet length is limited by MAXIMUM_UDP_PAYLOAD_SIZE, excess bytes will be discarded.
        let mut remote_buf = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];
        let (remote_recv_len, remote_addr) = remote_udp.recv_from(&mut remote_buf).await?;

        debug!(
            "UDP ASSOCIATE {} <- {}, payload length {} bytes",
            src_addr, remote_addr, remote_recv_len
        );

        // FIXME: The Address should be the Address that client sent
        let addr = Address::SocketAddress(remote_addr);

        // CLIENT <- SERVER protocol: ADDRESS + PAYLOAD
        let mut send_buf = Vec::new();
        addr.write_to_buf(&mut send_buf);
        send_buf.extend_from_slice(&remote_buf[..remote_recv_len]);

        let mut encrypt_buf = BytesMut::new();
        encrypt_payload(svr_cfg.method(), svr_cfg.key(), &send_buf, &mut encrypt_buf)?;

        // Send back to src_addr
        if let Err(err) = response_tx.send((src_addr, encrypt_buf)).await {
            error!("failed to send packet into response channel, error: {}", err);

            // FIXME: What to do? Ignore?
        }

        Ok(())
    }

    // Send packet to remote
    //
    // Return `Err` if receiver have been closed
    async fn send(&mut self, pkt: Vec<u8>) {
        if let Err(..) = self.tx.send(pkt).await {
            // SHOULDn't HAPPEN
            unreachable!("UDP Association local -> remote Queue closed unexpectly");
        }
    }
}

async fn listen(context: SharedContext, svr_cfg: Arc<ServerConfig>) -> io::Result<()> {
    let listen_addr = resolve_bind_addr(&*context, svr_cfg.addr()).await?;

    let listener = create_socket(&listen_addr).await?;
    let local_addr = listener.local_addr().expect("Could not determine port bound to");
    info!("ShadowSocks UDP listening on {}", local_addr);

    let (mut r, mut w) = listener.split();

    // NOTE: Associations are only eliminated by expire time
    // So it may exhaust all available file descriptors
    let timeout = context.config().udp_timeout.unwrap_or(DEFAULT_TIMEOUT);
    let assoc_map = Arc::new(Mutex::new(LruCache::with_expiry_duration(timeout)));
    let assoc_map_cloned = assoc_map.clone();

    // FIXME: Channel size 1024?
    let (tx, mut rx) = mpsc::channel::<(SocketAddr, BytesMut)>(1024);
    tokio::spawn(async move {
        let assoc_map = assoc_map_cloned;

        while let Some((src, pkt)) = rx.recv().await {
            let cache_key = src.to_string();
            {
                let mut amap = assoc_map.lock().await;

                // Check or update expire time
                if amap.get(&cache_key).is_none() {
                    debug!(
                        "UDP association {} <-> ... is already expired, throwing away packet {} bytes",
                        src,
                        pkt.len()
                    );
                    continue;
                }
            }

            if let Err(err) = w.send_to(&pkt, &src).await {
                error!("UDP packet send failed, err: {:?}", err);
                break;
            }
        }

        // FIXME: How to stop the outer listener Future?
    });

    let mut pkt_buf = [0u8; MAXIMUM_UDP_PAYLOAD_SIZE];

    loop {
        let (recv_len, src) = match time::timeout(timeout, r.recv_from(&mut pkt_buf)).await {
            Ok(r) => r?,
            Err(..) => {
                // Cleanup expired association
                // Do not consume this iterator, it will updates expire time of items that traversed
                let mut assoc_map = assoc_map.lock().await;
                let _ = assoc_map.iter();
                continue;
            }
        };

        // Packet length is limited by MAXIMUM_UDP_PAYLOAD_SIZE, excess bytes will be discarded.
        let pkt = &pkt_buf[..recv_len];

        trace!("received UDP packet from {}, length {} bytes", src, recv_len);

        if recv_len == 0 {
            // For windows, it will generate a ICMP Port Unreachable Message
            // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recvfrom
            // Which will result in recv_from return 0.
            //
            // It cannot be solved here, because `WSAGetLastError` is already set.
            //
            // See `relay::udprelay::utils::create_socket` for more detail.
            continue;
        }

        // Check or (re)create an association
        let mut assoc = {
            // Locks the whole association map
            let mut assoc_map = assoc_map.lock().await;

            // Get or create an association
            let assoc = match assoc_map.entry(src.to_string()) {
                Entry::Occupied(oc) => oc.into_mut(),
                Entry::Vacant(vc) => vc.insert(
                    UdpAssociation::associate(context.clone(), svr_cfg.clone(), src, tx.clone())
                        .await
                        .expect("Failed to create udp association"),
                ),
            };

            // Clone the handle and release the lock.
            // Make sure we keep the critical section small
            assoc.clone()
        };

        // Send to local -> remote task
        assoc.send(pkt.to_vec()).await;
    }
}

/// Starts a UDP relay server
pub async fn run(context: SharedContext) -> io::Result<()> {
    let vec_fut = FuturesUnordered::new();

    for svr in &context.config().server {
        let svr_cfg = Arc::new(svr.clone());

        let svr_fut = listen(context.clone(), svr_cfg);
        vec_fut.push(svr_fut);
    }

    match vec_fut.into_future().await.0 {
        Some(res) => {
            error!("one of UDP servers exited unexpectly, result: {:?}", res);
            let err = io::Error::new(io::ErrorKind::Other, "server exited unexpectly");
            Err(err)
        }
        None => unreachable!(),
    }
}
<|endoftext|>


<commit_before>// Hound -- A WAV encoding and decoding library in Rust
// Copyright (C) 2015 Ruud van Asseldonk
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License only.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// This example shows how to play a wav file using the cpal crate.

extern crate hound;
extern crate cpal;

use std::env;
use std::thread;

fn main() {
    // Make a WavReader that reads the file provided as program argument.
    let fname = env::args().nth(1).expect("no file given");
    let mut reader = hound::WavReader::open(fname).unwrap();
    let spec = reader.spec();

    // A voice in cpal is used for playback.
    let mut voice = cpal::Voice::new();

    let mut append_data = |voice: &mut cpal::Voice| {
        let mut samples = reader.samples::<i16>();
        let samples_left = samples.size_hint().0; // TODO: add method to reader?

        if samples_left == 0 { return false; }

        let mut buffer: cpal::Buffer<u16> =
            voice.append_data(spec.channels,
                              cpal::SamplesRate(spec.sample_rate),
                              samples_left);
        // Fill the cpal buffer with data from the wav file.
        for (dest, src) in buffer.iter_mut().zip(&mut samples) {
            // TODO: There is a bug in cpal that handles signed samples in the
            // wrong manner, so we cast it to `u16` for now.
            *dest = src.unwrap() as u16;
        }

        // Probably not done, loop again.
        true
    };

    // The voice must have some data before playing for the first time.
    append_data(&mut voice);
    voice.play();

    // Then we keep providing new data until the end of the audio.
    while append_data(&mut voice) { }

    // TODO: Cpal has no function (yet) to wait for playback to complete, so
    // sleep manually.
    thread::sleep_ms(1000);
}
<commit_msg>resolve TODO<commit_after>// Hound -- A WAV encoding and decoding library in Rust
// Copyright (C) 2015 Ruud van Asseldonk
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License only.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// This example shows how to play a wav file using the cpal crate.

extern crate hound;
extern crate cpal;

use std::env;
use std::thread;

fn main() {
    // Make a WavReader that reads the file provided as program argument.
    let fname = env::args().nth(1).expect("no file given");
    let mut reader = hound::WavReader::open(fname).unwrap();
    let spec = reader.spec();

    // A voice in cpal is used for playback.
    let mut voice = cpal::Voice::new();

    let mut append_data = |voice: &mut cpal::Voice| {
        let mut samples = reader.samples::<i16>();
        let samples_left = samples.size_hint().0;

        if samples_left == 0 { return false; }

        let mut buffer: cpal::Buffer<u16> =
            voice.append_data(spec.channels,
                              cpal::SamplesRate(spec.sample_rate),
                              samples_left);
        // Fill the cpal buffer with data from the wav file.
        for (dest, src) in buffer.iter_mut().zip(&mut samples) {
            // TODO: There is a bug in cpal that handles signed samples in the
            // wrong manner, so we cast it to `u16` for now.
            *dest = src.unwrap() as u16;
        }

        // Probably not done, loop again.
        true
    };

    // The voice must have some data before playing for the first time.
    append_data(&mut voice);
    voice.play();

    // Then we keep providing new data until the end of the audio.
    while append_data(&mut voice) { }

    // TODO: Cpal has no function (yet) to wait for playback to complete, so
    // sleep manually.
    thread::sleep_ms(1000);
}
<|endoftext|>


<commit_before>extern crate piston_window;
extern crate vecmath;
extern crate camera_controllers;
#[macro_use]
extern crate gfx;
extern crate gfx_device_gl;
extern crate sdl2_window;
extern crate piston_meta;

use std::fs::File;
use std::io::Read;
use sdl2_window::Sdl2Window;
use piston_window::*;
use camera_controllers::{
    FirstPersonSettings,
    FirstPerson,
    CameraPerspective,
    model_view_projection
};
use gfx::traits::*;
use piston_meta::*;

//----------------------------------------
// Cube associated data

gfx_vertex!( Vertex {
    a_pos@ a_pos: [f32; 3],
});

impl Vertex {
    fn new(pos: [f32; 3]) -> Vertex {
        Vertex {
            a_pos: pos,
        }
    }
}

gfx_parameters!( Params {
    u_model_view_proj@ u_model_view_proj: [[f32; 4]; 4],
});

//----------------------------------------

fn main() {
    let mut events: PistonWindow<Sdl2Window> =
        WindowSettings::new("piston: cube", [640, 480])
        .exit_on_esc(true)
        .samples(4)
        .into();
    events.set_capture_cursor(true);

    let ref mut factory = events.factory.borrow().clone();

    // Read OpenGEX meta rules.
    let mut file_h = File::open("assets/opengex-syntax.txt").unwrap();
    let mut source = String::new();
    file_h.read_to_string(&mut source).unwrap();
    let rules = stderr_unwrap(&source, syntax(&source));

    // Read cube.ogex.
    let mut file_h = File::open("assets/cube.ogex").unwrap();
    let mut source = String::new();
    file_h.read_to_string(&mut source).unwrap();
    let data = stderr_unwrap(&source, parse(&rules, &source));

    let v3 = |mut s: &mut Search| Ok([
        try!(s.f64("x")) as f32,
        try!(s.f64("y")) as f32,
        try!(s.f64("z")) as f32
    ]);

    let s = Search::new(&data);
    let vertex_data: Vec<Vertex> = stderr_unwrap(&source, s.for_bool("position", true,
        |ref mut s| {
            let mut vs = Vec::with_capacity(24);
            for _ in 0 .. 24 {
                vs.push(Vertex::new(try!(v3(s))));
            }
            Ok(vs)
        }));

    let mesh = factory.create_mesh(&vertex_data);

    let index_data: Vec<u8> = stderr_unwrap(&source, s.for_node("IndexArray",
        |ref mut s| {
            let mut is = Vec::with_capacity(36);
            for _ in 0 .. 12 {
                is.push(try!(s.f64("a")) as u8);
                is.push(try!(s.f64("b")) as u8);
                is.push(try!(s.f64("c")) as u8);
            }
            Ok(is)
        }));

    let slice = index_data.to_slice(factory, gfx::PrimitiveType::TriangleList);

    let program = {
        let vertex = gfx::ShaderSource {
            glsl_120: Some(include_bytes!("../assets/cube_colored_120.glslv")),
            glsl_150: Some(include_bytes!("../assets/cube_colored_150.glslv")),
            .. gfx::ShaderSource::empty()
        };
        let fragment = gfx::ShaderSource {
            glsl_120: Some(include_bytes!("../assets/cube_colored_120.glslf")),
            glsl_150: Some(include_bytes!("../assets/cube_colored_150.glslf")),
            .. gfx::ShaderSource::empty()
        };
        factory.link_program_source(vertex, fragment).unwrap()
    };

    let mut data = Params {
        u_model_view_proj: vecmath::mat4_id(),
        _r: std::marker::PhantomData,
    };

    let get_projection = |w: &PistonWindow<Sdl2Window>| {
        let draw_size = w.window.borrow().draw_size();
        CameraPerspective {
            fov: 90.0, near_clip: 0.1, far_clip: 1000.0,
            aspect_ratio: (draw_size.width as f32) / (draw_size.height as f32)
        }.projection()
    };

    let model = vecmath::mat4_id();
    let mut projection = get_projection(&events);
    let mut first_person = FirstPerson::new(
        [0.5, 0.5, 4.0],
        FirstPersonSettings::keyboard_wasd()
    );
    let state = gfx::DrawState::new().depth(gfx::state::Comparison::LessEqual, true);

    for e in events {
        first_person.event(&e);

        e.draw_3d(|stream| {
            let args = e.render_args().unwrap();
            stream.clear(
                gfx::ClearData {
                    color: [0.3, 0.3, 0.3, 1.0],
                    depth: 1.0,
                    stencil: 0,
                }
            );
            data.u_model_view_proj = model_view_projection(
                model,
                first_person.camera(args.ext_dt).orthogonal(),
                projection
            );
            stream.draw(&(&mesh, slice.clone(), &program, &data, &state)).unwrap();
        });

        if let Some(_) = e.resize_args() {
            projection = get_projection(&e);
        }
    }
}
<commit_msg>Renamed `v3` to `read_vertex`<commit_after>extern crate piston_window;
extern crate vecmath;
extern crate camera_controllers;
#[macro_use]
extern crate gfx;
extern crate gfx_device_gl;
extern crate sdl2_window;
extern crate piston_meta;

use std::fs::File;
use std::io::Read;
use sdl2_window::Sdl2Window;
use piston_window::*;
use camera_controllers::{
    FirstPersonSettings,
    FirstPerson,
    CameraPerspective,
    model_view_projection
};
use gfx::traits::*;
use piston_meta::*;

//----------------------------------------
// Cube associated data

gfx_vertex!( Vertex {
    a_pos@ a_pos: [f32; 3],
});

impl Vertex {
    fn new(pos: [f32; 3]) -> Vertex {
        Vertex {
            a_pos: pos,
        }
    }
}

gfx_parameters!( Params {
    u_model_view_proj@ u_model_view_proj: [[f32; 4]; 4],
});

//----------------------------------------

fn main() {
    let mut events: PistonWindow<Sdl2Window> =
        WindowSettings::new("piston: cube", [640, 480])
        .exit_on_esc(true)
        .samples(4)
        .into();
    events.set_capture_cursor(true);

    let ref mut factory = events.factory.borrow().clone();

    // Read OpenGEX meta rules.
    let mut file_h = File::open("assets/opengex-syntax.txt").unwrap();
    let mut source = String::new();
    file_h.read_to_string(&mut source).unwrap();
    let rules = stderr_unwrap(&source, syntax(&source));

    // Read cube.ogex.
    let mut file_h = File::open("assets/cube.ogex").unwrap();
    let mut source = String::new();
    file_h.read_to_string(&mut source).unwrap();
    let data = stderr_unwrap(&source, parse(&rules, &source));

    let read_vertex = |mut s: &mut Search| Ok(Vertex::new([
        try!(s.f64("x")) as f32,
        try!(s.f64("y")) as f32,
        try!(s.f64("z")) as f32
    ]));

    let s = Search::new(&data);
    let vertex_data: Vec<Vertex> = stderr_unwrap(&source, s.for_bool("position", true,
        |ref mut s| {
            let mut vs = Vec::with_capacity(24);
            for _ in 0 .. 24 {
                vs.push(try!(read_vertex(s)));
            }
            Ok(vs)
        }));

    let mesh = factory.create_mesh(&vertex_data);

    let index_data: Vec<u8> = stderr_unwrap(&source, s.for_node("IndexArray",
        |ref mut s| {
            let mut is = Vec::with_capacity(36);
            for _ in 0 .. 12 {
                is.push(try!(s.f64("a")) as u8);
                is.push(try!(s.f64("b")) as u8);
                is.push(try!(s.f64("c")) as u8);
            }
            Ok(is)
        }));

    let slice = index_data.to_slice(factory, gfx::PrimitiveType::TriangleList);

    let program = {
        let vertex = gfx::ShaderSource {
            glsl_120: Some(include_bytes!("../assets/cube_colored_120.glslv")),
            glsl_150: Some(include_bytes!("../assets/cube_colored_150.glslv")),
            .. gfx::ShaderSource::empty()
        };
        let fragment = gfx::ShaderSource {
            glsl_120: Some(include_bytes!("../assets/cube_colored_120.glslf")),
            glsl_150: Some(include_bytes!("../assets/cube_colored_150.glslf")),
            .. gfx::ShaderSource::empty()
        };
        factory.link_program_source(vertex, fragment).unwrap()
    };

    let mut data = Params {
        u_model_view_proj: vecmath::mat4_id(),
        _r: std::marker::PhantomData,
    };

    let get_projection = |w: &PistonWindow<Sdl2Window>| {
        let draw_size = w.window.borrow().draw_size();
        CameraPerspective {
            fov: 90.0, near_clip: 0.1, far_clip: 1000.0,
            aspect_ratio: (draw_size.width as f32) / (draw_size.height as f32)
        }.projection()
    };

    let model = vecmath::mat4_id();
    let mut projection = get_projection(&events);
    let mut first_person = FirstPerson::new(
        [0.5, 0.5, 4.0],
        FirstPersonSettings::keyboard_wasd()
    );
    let state = gfx::DrawState::new().depth(gfx::state::Comparison::LessEqual, true);

    for e in events {
        first_person.event(&e);

        e.draw_3d(|stream| {
            let args = e.render_args().unwrap();
            stream.clear(
                gfx::ClearData {
                    color: [0.3, 0.3, 0.3, 1.0],
                    depth: 1.0,
                    stencil: 0,
                }
            );
            data.u_model_view_proj = model_view_projection(
                model,
                first_person.camera(args.ext_dt).orthogonal(),
                projection
            );
            stream.draw(&(&mesh, slice.clone(), &program, &data, &state)).unwrap();
        });

        if let Some(_) = e.resize_args() {
            projection = get_projection(&e);
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Echo server with a bounded buffer pool.

extern crate gj;
use std::net::ToSocketAddrs;
use std::cell::RefCell;
use std::rc::Rc;
use gj::io::{AsyncRead, AsyncWrite};

struct BufferPool {
    buffers: Vec<Vec<u8>>,
    fulfiller: Option<Box<gj::PromiseFulfiller<Vec<u8>, ()>>>,
}

impl BufferPool {
    pub fn new(num_buffers: usize) -> BufferPool {
        BufferPool { buffers: vec![vec![0; 1024]; num_buffers], fulfiller: None }
    }

    pub fn pop(&mut self) -> gj::Promise<Vec<u8>, ()> {
        match self.buffers.pop() {
            Some(buf) => gj::Promise::fulfilled(buf),
            None => {
                if self.fulfiller.is_some() {
                    gj::Promise::rejected(())
                } else {
                    let (promise, fulfiller) = gj::new_promise_and_fulfiller();
                    self.fulfiller = Some(fulfiller);
                    promise
                }
            }
        }
    }

    pub fn push(&mut self, buf: Vec<u8>) {
        match self.fulfiller.take() {
            Some(fulfiller) => fulfiller.fulfill(buf),
            None => self.buffers.push(buf),
        }
    }
}

struct Reaper {
    buffer_pool: Rc<RefCell<BufferPool>>,
}

impl gj::TaskReaper<ThreadedState, gj::io::Error<ThreadedState>> for Reaper {
    fn task_succeeded(&mut self, (_, buf): ThreadedState) {
        self.buffer_pool.borrow_mut().push(buf);
    }
    fn task_failed(&mut self, error: gj::io::Error<ThreadedState>) {
        self.buffer_pool.borrow_mut().push(error.state.1);
        println!("Task failed: {}", error.error);
    }
}

type ThreadedState = (::gj::io::tcp::Stream, Vec<u8>);

fn echo<S,B>(stream: S, buf: B) -> gj::Promise<(S, B), gj::io::Error<(S, B)>>
    where S: AsyncRead + AsyncWrite, B: ::std::ops::DerefMut<Target=[u8]> + 'static
{
    stream.try_read(buf, 1).then(move |(stream, buf, n)| {
        if n == 0 {
            // EOF
            Ok(gj::Promise::fulfilled((stream, buf)))
        } else {
            Ok(stream.write(gj::io::Slice::new(buf, n)).then_else(move |r| match r {
                Ok((stream, slice)) => Ok(echo(stream, slice.buf)),
                Err(gj::io::Error {state: (stream, slice), error}) =>
                    Err(gj::io::Error::new((stream, slice.buf), error)),
            }))
        }
    })
}

fn accept_loop(receiver: gj::io::tcp::Listener,
               mut task_set: gj::TaskSet<ThreadedState, gj::io::Error<ThreadedState>>,
               buffer_pool: Rc<RefCell<BufferPool>>)
               -> gj::Promise<(), ::std::io::Error>
{
    let buf_promise = buffer_pool.borrow_mut().pop().map_err(|()| {
        ::std::io::Error::new(::std::io::ErrorKind::Other, "No available buffers")});
    buf_promise.then(move |buf| {
        Ok(receiver.accept().lift().then(move |(receiver, stream)| {
            task_set.add(echo(stream, buf));
            Ok(accept_loop(receiver, task_set, buffer_pool))
        }))
    })
}

pub fn main() {
    let args: Vec<String> = ::std::env::args().collect();
    if args.len() != 2 {
        println!("usage: {} HOST:PORT", args[0]);
        return;
    }
    let buffer_pool = Rc::new(RefCell::new(BufferPool::new(64)));

    gj::EventLoop::top_level(move |wait_scope| {
        let addr = try!(args[1].to_socket_addrs()).next().expect("could not parse address");
        let listener = try!(::gj::io::tcp::Listener::bind(addr));
        let reaper = Box::new(Reaper { buffer_pool: buffer_pool.clone() });
        accept_loop(listener, gj::TaskSet::new(reaper), buffer_pool).lift().wait(wait_scope)
    }).unwrap();
}
<commit_msg>receiver -> listener<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Echo server with a bounded buffer pool.

extern crate gj;
use std::net::ToSocketAddrs;
use std::cell::RefCell;
use std::rc::Rc;
use gj::io::{AsyncRead, AsyncWrite};

struct BufferPool {
    buffers: Vec<Vec<u8>>,
    fulfiller: Option<Box<gj::PromiseFulfiller<Vec<u8>, ()>>>,
}

impl BufferPool {
    pub fn new(num_buffers: usize) -> BufferPool {
        BufferPool { buffers: vec![vec![0; 1024]; num_buffers], fulfiller: None }
    }

    pub fn pop(&mut self) -> gj::Promise<Vec<u8>, ()> {
        match self.buffers.pop() {
            Some(buf) => gj::Promise::fulfilled(buf),
            None => {
                if self.fulfiller.is_some() {
                    gj::Promise::rejected(())
                } else {
                    let (promise, fulfiller) = gj::new_promise_and_fulfiller();
                    self.fulfiller = Some(fulfiller);
                    promise
                }
            }
        }
    }

    pub fn push(&mut self, buf: Vec<u8>) {
        match self.fulfiller.take() {
            Some(fulfiller) => fulfiller.fulfill(buf),
            None => self.buffers.push(buf),
        }
    }
}

struct Reaper {
    buffer_pool: Rc<RefCell<BufferPool>>,
}

impl gj::TaskReaper<ThreadedState, gj::io::Error<ThreadedState>> for Reaper {
    fn task_succeeded(&mut self, (_, buf): ThreadedState) {
        self.buffer_pool.borrow_mut().push(buf);
    }
    fn task_failed(&mut self, error: gj::io::Error<ThreadedState>) {
        self.buffer_pool.borrow_mut().push(error.state.1);
        println!("Task failed: {}", error.error);
    }
}

type ThreadedState = (::gj::io::tcp::Stream, Vec<u8>);

fn echo<S,B>(stream: S, buf: B) -> gj::Promise<(S, B), gj::io::Error<(S, B)>>
    where S: AsyncRead + AsyncWrite, B: ::std::ops::DerefMut<Target=[u8]> + 'static
{
    stream.try_read(buf, 1).then(move |(stream, buf, n)| {
        if n == 0 {
            // EOF
            Ok(gj::Promise::fulfilled((stream, buf)))
        } else {
            Ok(stream.write(gj::io::Slice::new(buf, n)).then_else(move |r| match r {
                Ok((stream, slice)) => Ok(echo(stream, slice.buf)),
                Err(gj::io::Error {state: (stream, slice), error}) =>
                    Err(gj::io::Error::new((stream, slice.buf), error)),
            }))
        }
    })
}

fn accept_loop(listener: gj::io::tcp::Listener,
               mut task_set: gj::TaskSet<ThreadedState, gj::io::Error<ThreadedState>>,
               buffer_pool: Rc<RefCell<BufferPool>>)
               -> gj::Promise<(), ::std::io::Error>
{
    let buf_promise = buffer_pool.borrow_mut().pop().map_err(|()| {
        ::std::io::Error::new(::std::io::ErrorKind::Other, "No available buffers")});
    buf_promise.then(move |buf| {
        Ok(listener.accept().lift().then(move |(listener, stream)| {
            task_set.add(echo(stream, buf));
            Ok(accept_loop(listener, task_set, buffer_pool))
        }))
    })
}

pub fn main() {
    let args: Vec<String> = ::std::env::args().collect();
    if args.len() != 2 {
        println!("usage: {} HOST:PORT", args[0]);
        return;
    }
    let buffer_pool = Rc::new(RefCell::new(BufferPool::new(64)));

    gj::EventLoop::top_level(move |wait_scope| {
        let addr = try!(args[1].to_socket_addrs()).next().expect("could not parse address");
        let listener = try!(gj::io::tcp::Listener::bind(addr));
        let reaper = Box::new(Reaper { buffer_pool: buffer_pool.clone() });
        accept_loop(listener, gj::TaskSet::new(reaper), buffer_pool).lift().wait(wait_scope)
    }).unwrap();
}
<|endoftext|>


<commit_before>extern crate ruroonga;

use ruroonga as groonga;

fn main() {
    // initialize libgroonga and automatically finalize
    let libgroonga = groonga::LibGroonga::new();
    // For more safety
    let is_success = match libgroonga {
        Ok(_) => true,
        Err(e) => {
            println!("{}", e);
            false
        }
    };

    assert_eq!(true, is_success);
    let ctx = groonga::Context::new().unwrap();
    let mut db = groonga::Database::new(ctx.clone());
    let dbpath = "test.db";
    let _ = db.uses(dbpath);
    let grn_command = "table_create Users TABLE_HASH_KEY ShortText";
    let mut command = groonga::Command::new(ctx.clone());
    let _ = command.execute(grn_command.clone());
    let dump = "dump";
    let result = command.execute(dump.clone());
    println!("result: {}", result);
    println!("Hello in Ruroonga with Groonga: {}", groonga::Command::groonga_version());
}
<commit_msg>example: Simplify<commit_after>extern crate ruroonga;

use ruroonga as groonga;

fn main() {
    // initialize libgroonga and automatically finalize
    let libgroonga = groonga::LibGroonga::new();
    assert_eq!(true, libgroonga.is_ok());
    let ctx = groonga::Context::new().unwrap();
    let mut db = groonga::Database::new(ctx.clone());
    let dbpath = "test.db";
    let _ = db.uses(dbpath);
    let grn_command = "table_create Users TABLE_HASH_KEY ShortText";
    let mut command = groonga::Command::new(ctx.clone());
    let _ = command.execute(grn_command.clone());
    let dump = "dump";
    let result = command.execute(dump.clone());
    println!("result: {}", result);
    println!("Hello in Ruroonga with Groonga: {}", groonga::Command::groonga_version());
}
<|endoftext|>


<commit_before>extern crate hound;

use std::env;

fn main() {
    let fname = env::args().nth(1).expect("no file given");
    let mut reader = hound::WavReader::open(&fname).unwrap();
    let samples: Vec<i16> = reader.samples().map(|s| s.unwrap()).collect();
    let (sig, unsig, n) = samples.iter().fold((0_f64, 0_f64, 0_u32), |(sig, unsig, n), &s| {
        let sample = s;
        let sig = sig + sample as f64;
        let unsig = unsig + (sample as u16) as f64;
        (sig, unsig, n + 1)
    });
    let ms = sig / n as f64;
    let mu = unsig / n as f64;
    println!("mean signed:   {}\nmean unsigned: {}", ms, mu);

    let (dsig, dunsig, n) = samples.iter().fold((0_f64, 0_f64, 0_u32), |(dsig, dunsig, n), &s| {
        let sample = s;
        let ds = sample as f64 - ms;
        let du = (sample as u16) as f64 - mu;
        (dsig + ds * ds, dunsig + du * du, n + 1)
    });
    let ds = dsig / n as f64;
    let du = dunsig / n as f64;
    println!("rms signed:    {}\nrms unsigned:  {}", ds.sqrt(), du.sqrt());
}
<commit_msg>refactor mean example<commit_after>extern crate hound;

use std::env;

fn main() {
    let fname = env::args().nth(1).expect("no file given");
    let mut reader = hound::WavReader::open(&fname).unwrap();
    let samples: Vec<i16> = reader.samples().map(|s| s.unwrap()).collect();

    let (ts, tu, n) = samples.iter().fold((0.0, 0.0, 0.0), |(ts, tu, n), &s| {
        let signed = s as f64;
        let unsigned = (s as u16) as f64;
        (ts + signed, tu + unsigned, n + 1.0)
    });
    let ms = ts / n;
    let mu = tu / n;
    println!("mean signed:   {} (should be 0, deviation is {})", ms, ms.abs());
    println!("mean unsigned: {} (should be 2^16 - 1, deviation is {})", mu, (mu - 32767.0).abs());

    let (ts, tu) = samples.iter().fold((0.0, 0.0), |(ts, tu), &s| {
        let ds = s as f64 - ms;
        let du = (s as u16) as f64 - mu;
        (ts + ds * ds, tu + du * du)
    });
    let rmss = (ts / n).sqrt();
    let rmsu = (tu / n).sqrt();
    println!("rms signed:    {}", rmss);
    println!("rms unsigned:  {}", rmsu);
}
<|endoftext|>