<commit_before>// http://dev.w3.org/csswg/css3-syntax/#tokenization
//
// The output of the tokenization step is a series of zero or more
// of the following tokens:
// ident, function, at-keyword, hash, string, bad-string, url, bad-url,
// delim, number, percentage, dimension, unicode-range, whitespace, comment,
// cdo, cdc, colon, semicolon, [, ], (, ), {, }.
//
// ident, function, at-keyword, hash, string, and url tokens
// have a value composed of zero or more characters.
// Delim tokens have a value composed of a single character.
// Number, percentage, and dimension tokens have a representation
// composed of 1 or more character, a numeric value,
// and a type flag set to either "integer" or "number".
// The type flag defaults to "integer" if not otherwise set.
// Dimension tokens additionally have a unit
// composed of one or more characters.
// Unicode-range tokens have a range of characters.

use cssparser;

#[deriving_eq]
enum NumericValue {
    Integer(int),
    // The spec calls this "number".
    // Use "float" instead to reduce term overloading with "number token".
    Float(float),
}
// TODO: add a NumberValue.as_float() method.

#[deriving_eq]
enum Token {
    Ident(~str),
    Function(~str),
    AtKeyword(~str),
    Hash(~str),
    String(~str),
    BadString,
    URL(~str),
    BadURL,
    Delim(char),
    Number(NumericValue, ~str),  // value, representation
    Percentage(NumericValue, ~str),  // value, representation
    Dimension(NumericValue, ~str, ~str),  // value, representation, unit
    UnicodeRange(char, char),  // start, end. XXX what about empty ranges?
    WhiteSpace,
    Comment,
    CDO,  // <!--
    CDC,  // -->
    Colon,  // ,
    Semicolon,  // ;
    OpenBraket, // [
    OpenParen, // (
    OpenBrace, // {
    CloseBraket, // ]
    CloseParen, // )
    CloseBrace, // }
}

struct State {
    input: ~str,
    length: uint,
    mut position: uint,
    mut errors: ~[~str]
}

fn is_eof(state: &State) -> bool {
    state.position >= state.length
}

fn current_char(state: &State) -> char {
    str::char_at(state.input, state.position)
}

fn consume_char(state: &State) -> char {
    let range = str::char_range_at(state.input, state.position);
    state.position = range.next;
    range.ch
}

// 3.3.9. Comment state
fn consume_comment(state: &State) -> Token {
    state.position += 1;  // consume the * in /*
    match str::find_str_from(state.input, "*/", state.position) {
        Some(end_position) => state.position = end_position + 2,
        None => {
            state.errors.push(~"EOF in comment");
            state.position = state.input.len();
        }
    }
    Comment
}

// http://dev.w3.org/csswg/css3-syntax/#tokenization
fn tokenize(input: &str//, transform_function_whitespace: bool,
//            quirks_mode: bool
            ) -> {tokens: ~[Token], parse_errors: ~[~str]} {
    let input = cssparser::preprocess(input);
    let state = &State {
        input: input, length: input.len(),
        position: 0, errors: ~[] };
    let mut tokens: ~[Token] = ~[];

    // 3.3.4. Data state
    while !is_eof(state) {
        tokens.push(match consume_char(state) {
            '/' if !is_eof(state) && current_char(state) == '*'
                => consume_comment(state),
            ',' => Colon,
            ';' => Semicolon,
            '[' => OpenBraket,
            '(' => OpenParen,
            '{' => OpenBrace,
            ']' => CloseBraket,
            ')' => CloseParen,
            '}' => CloseBrace,
            c => Delim(c),
        })
    }

    // Work around `error: moving out of mutable field`
    // TODO: find a cleaner way.
    let mut errors: ~[~str] = ~[];
    errors <-> state.errors;
    {tokens: tokens, parse_errors: errors}
}

#[test]
fn test_tokenizer() {
    fn assert_tokens(input: &str, expected_tokens: &[Token],
                     expected_errors: &[~str]) {
        let result = tokenize(input//, false, false
        );
        let tokens: &[Token] = result.tokens;
        let parse_errors: &[~str] = result.parse_errors;
        if tokens != expected_tokens {
            fail fmt!("%? != %?", tokens, expected_tokens);
        }
        if parse_errors != expected_errors {
            fail fmt!("%? != %?", tokens, expected_errors);
        }
    }
    assert_tokens("", [], []);
    assert_tokens("?/", [Delim('?'), Delim('/')], []);
    assert_tokens("?/* Li/*psum… */", [Delim('?'), Comment], []);
    assert_tokens("?/* Li/*psum… *//", [Delim('?'), Comment, Delim('/')], []);
    assert_tokens("?/* Lipsum", [Delim('?'), Comment], [~"EOF in comment"]);
    assert_tokens("?/*", [Delim('?'), Comment], [~"EOF in comment"]);
    assert_tokens("[?}{)",
        [OpenBraket, Delim('?'), CloseBrace, OpenBrace, CloseParen], []);
}
<commit_msg>Add whitespace and quoted strings.<commit_after>// http://dev.w3.org/csswg/css3-syntax/#tokenization
//
// The output of the tokenization step is a series of zero or more
// of the following tokens:
// ident, function, at-keyword, hash, string, bad-string, url, bad-url,
// delim, number, percentage, dimension, unicode-range, whitespace, comment,
// cdo, cdc, colon, semicolon, [, ], (, ), {, }.
//
// ident, function, at-keyword, hash, string, and url tokens
// have a value composed of zero or more characters.
// Delim tokens have a value composed of a single character.
// Number, percentage, and dimension tokens have a representation
// composed of 1 or more character, a numeric value,
// and a type flag set to either "integer" or "number".
// The type flag defaults to "integer" if not otherwise set.
// Dimension tokens additionally have a unit
// composed of one or more characters.
// Unicode-range tokens have a range of characters.

use cssparser;

const MAX_UNICODE: uint = 0x10FFFF;

#[deriving_eq]
enum NumericValue {
    Integer(int),
    // The spec calls this "number".
    // Use "float" instead to reduce term overloading with "number token".
    Float(float),
}
// TODO: add a NumberValue.as_float() method.

#[deriving_eq]
enum Token {
    Ident(~str),
    Function(~str),
    AtKeyword(~str),
    Hash(~str),
    String(~str),
    BadString,
    URL(~str),
    BadURL,
    Delim(char),
    Number(NumericValue, ~str),  // value, representation
    Percentage(NumericValue, ~str),  // value, representation
    Dimension(NumericValue, ~str, ~str),  // value, representation, unit
    UnicodeRange(char, char),  // start, end. XXX what about empty ranges?
    WhiteSpace,
    Comment,
    CDO,  // <!--
    CDC,  // -->
    Colon,  // ,
    Semicolon,  // ;
    OpenBraket, // [
    OpenParen, // (
    OpenBrace, // {
    CloseBraket, // ]
    CloseParen, // )
    CloseBrace, // }
}

struct State {
    input: ~str,
    length: uint,
    mut position: uint,
    mut errors: ~[~str]
}

fn is_eof(state: &State) -> bool {
    state.position >= state.length
}

fn current_char(state: &State) -> char {
    str::char_at(state.input, state.position)
}

fn consume_char(state: &State) -> char {
    let range = str::char_range_at(state.input, state.position);
    state.position = range.next;
    range.ch
}

fn consume_whitespace(state: &State) -> Token {
    while !is_eof(state) {
        match current_char(state) {
            '\t' | '\n' | '\x0C' | ' ' => state.position += 1,
            _ => break,
        }
    }
    WhiteSpace
}

fn char_from_hex(hex: &[char]) -> char {
    let mut value = 0u;
    for hex.each |cc| {
        let c = *cc;
        value = value * 16 + c as uint - match c {
            '0'..'9' => '0' as uint,
            'A'..'F' => 'A' as uint - 10,
            'a'..'f' => 'a' as uint - 10,
            _ => fail
        }
    }
    if value == 0 || value > MAX_UNICODE {
        '\uFFFD'  // Replacement character
    } else {
        value as char
    }
}

// 3.3.27. Consume an escaped character
// Assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed
// and that the next input character has already been verified
// to not be a newline or EOF.
fn consume_escape(state: &State) -> char {
    let c = consume_char(state);
    match c {
        '0'..'9' | 'A'..'F' | 'a'..'f' => {
            let mut hex = ~[c];
            while hex.len() < 6 && !is_eof(state) {
                let c = current_char(state);
                match c {
                    '0'..'9' | 'A'..'F' | 'a'..'f' => {
                        hex.push(c); state.position += 1 },
                    _ => break
                }
            }
            if !is_eof(state) {
                match current_char(state) {
                    '\t' | '\n' | '\x0C' | ' ' => state.position += 1,
                    _ => ()
                }
            }
            char_from_hex(hex)
        },
        c => c
    }
}

// 3.3.5. Double-quote-string state
// 3.3.6. Single-quote-string state
fn consume_quoted_string(state: &State, single_quote: bool) -> Token {
    let mut string: ~str = ~"";
    loop {
        if is_eof(state) {
            state.errors.push(~"EOF in quoted string");
            return String(string);
        }
        match consume_char(state) {
            '"' if !single_quote => return String(string),
            '\'' if single_quote => return String(string),
            '\n' | '\x0C' => {
                state.errors.push(~"Newline in quoted string");
                return BadString
            },
            '\\' => {
                if is_eof(state) {
                    state.errors.push(~"EOF in a quoted string");
                    return BadString
                }
                match current_char(state) {
                    // Consume quoted newline
                    '\n' | '\x0C' => state.position += 1,
                    _ =>  str::push_char(&mut string, consume_escape(state))
                }
            }
            c => str::push_char(&mut string, c),
        }
    }
}

// 3.3.9. Comment state
fn consume_comment(state: &State) -> Token {
    state.position += 1;  // consume the * in /*
    match str::find_str_from(state.input, "*/", state.position) {
        Some(end_position) => state.position = end_position + 2,
        None => {
            state.errors.push(~"EOF in comment");
            state.position = state.input.len();
        }
    }
    Comment
}

// http://dev.w3.org/csswg/css3-syntax/#tokenization
fn tokenize(input: &str//, transform_function_whitespace: bool,
//            quirks_mode: bool
            ) -> {tokens: ~[Token], parse_errors: ~[~str]} {
    let input = cssparser::preprocess(input);
    let state = &State {
        input: input, length: input.len(),
        position: 0, errors: ~[] };
    let mut tokens: ~[Token] = ~[];

    // 3.3.4. Data state
    while !is_eof(state) {
        tokens.push(match consume_char(state) {
            '\t' | '\n' | '\x0C' | ' ' => consume_whitespace(state),
            '"' => consume_quoted_string(state, false),
            '\'' => consume_quoted_string(state, true),
            '/' if !is_eof(state) && current_char(state) == '*'
                => consume_comment(state),
            ',' => Colon,
            ';' => Semicolon,
            '[' => OpenBraket,
            '(' => OpenParen,
            '{' => OpenBrace,
            ']' => CloseBraket,
            ')' => CloseParen,
            '}' => CloseBrace,
            c => Delim(c),
        })
    }

    // Work around `error: moving out of mutable field`
    // TODO: find a cleaner way.
    let mut errors: ~[~str] = ~[];
    errors <-> state.errors;
    {tokens: tokens, parse_errors: errors}
}

#[test]
fn test_tokenizer() {
    fn assert_tokens(input: &str, expected_tokens: &[Token],
                     expected_errors: &[~str]) {
        let result = tokenize(input//, false, false
        );
        let tokens: &[Token] = result.tokens;
        let parse_errors: &[~str] = result.parse_errors;
        if tokens != expected_tokens {
            fail fmt!("%? != %?", tokens, expected_tokens);
        }
        if parse_errors != expected_errors {
            fail fmt!("%? != %?", parse_errors, expected_errors);
        }
    }
    assert_tokens("", [], []);
    assert_tokens("?/", [Delim('?'), Delim('/')], []);
    assert_tokens("?/* Li/*psum… */", [Delim('?'), Comment], []);
    assert_tokens("?/* Li/*psum… *//", [Delim('?'), Comment, Delim('/')], []);
    assert_tokens("?/* Lipsum", [Delim('?'), Comment], [~"EOF in comment"]);
    assert_tokens("?/*", [Delim('?'), Comment], [~"EOF in comment"]);
    assert_tokens("[?}{)",
        [OpenBraket, Delim('?'), CloseBrace, OpenBrace, CloseParen], []);
    assert_tokens("(\n \t'Lore\\6d \"ipsu\\6D'",
        [OpenParen, WhiteSpace, String(~"Lorem\"ipsum")], []);
    assert_tokens("\"0\\0000000\"", [String(~"0\uFFFD0")], []);
    assert_tokens("\"0\\000000 0\"", [String(~"0\uFFFD0")], []);
    assert_tokens("'z\n'a", [BadString, String(~"a")],
        [~"Newline in quoted string", ~"EOF in quoted string"]);
}
<|endoftext|>


<commit_before>// Copyright (C) 2018, 2019, 2020 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::{Error, Result};
use async_std::{
    io::BufReader,
    os::unix::net::{UnixListener, UnixStream},
    prelude::*,
};
use log::warn;
use std::{env, fs, path::Path, pin::Pin};

const SDK_TRIGGER_FILENAME: &str =
    "/usr/share/updatehub/state-change-callbacks.d/10-updatehub-sdk-statechange-trigger";
const SOCKET_PATH: &str = "/run/updatehub-statechange.sock";

type CallbackFn = dyn Fn(Handler) -> Pin<Box<dyn Future<Output = Result<()>>>>;

#[derive(Default)]
pub struct StateChangeListener {
    download_callbacks: Vec<Box<CallbackFn>>,
    install_callbacks: Vec<Box<CallbackFn>>,
    reboot_callbacks: Vec<Box<CallbackFn>>,
    error_callbacks: Vec<Box<CallbackFn>>,
}

#[derive(Debug)]
pub enum State {
    Download,
    Install,
    Reboot,
    Error,
}

pub struct Handler {
    stream: UnixStream,
}

impl Handler {
    // Cancels the current action on the agent.
    pub async fn cancel(&mut self) -> Result<()> {
        self.stream.write_all(b"cancel").await.map_err(Error::Io)
    }

    // Tell the agent to proceed with the transition.
    pub async fn proceed(&self) -> Result<()> {
        // No message need to be sent to the connection in order to the
        // agent to proceed handling the current state.
        Ok(())
    }
}

impl StateChangeListener {
    #[inline]
    pub fn new() -> Self {
        StateChangeListener {
            download_callbacks: Vec::new(),
            install_callbacks: Vec::new(),
            reboot_callbacks: Vec::new(),
            error_callbacks: Vec::new(),
        }
    }

    pub fn on_state<F, Fut>(&mut self, state: State, f: F)
    where
        F: Fn(Handler) -> Fut + 'static,
        Fut: Future<Output = Result<()>> + 'static,
    {
        match state {
            State::Download => self.download_callbacks.push(Box::new(move |d| Box::pin(f(d)))),
            State::Install => self.install_callbacks.push(Box::new(move |d| Box::pin(f(d)))),
            State::Reboot => self.reboot_callbacks.push(Box::new(move |d| Box::pin(f(d)))),
            State::Error => self.error_callbacks.push(Box::new(move |d| Box::pin(f(d)))),
        }
    }

    pub async fn listen(&self) -> Result<()> {
        let sdk_trigger = Path::new(SDK_TRIGGER_FILENAME);
        if !sdk_trigger.exists() {
            warn!("WARNING: updatehub-sdk-statechange-trigger not found on {:?}", sdk_trigger);
        }

        let socket_path = env::var("UH_LISTENER_TEST").unwrap_or_else(|_| SOCKET_PATH.to_string());
        let socket_path = Path::new(&socket_path);
        if socket_path.exists() {
            fs::remove_file(&socket_path)?;
        }

        let listener = UnixListener::bind(socket_path).await?;
        loop {
            let (socket, ..) = listener.accept().await?;
            self.handle_connection(socket).await?;
        }
    }

    async fn handle_connection(&self, stream: UnixStream) -> Result<()> {
        let mut reader = BufReader::new(&stream);
        let mut line = String::new();

        reader.read_line(&mut line).await?;

        self.emit(stream, &line.trim()).await
    }

    async fn emit(&self, stream: UnixStream, input: &str) -> Result<()> {
        let callbacks = match input {
            "download" => &self.download_callbacks,
            "install" => &self.install_callbacks,
            "reboot" => &self.reboot_callbacks,
            "error" => &self.error_callbacks,
            _ => unreachable!("the input is not valid"),
        };

        for f in callbacks {
            let stream = stream.clone();
            f(Handler { stream }).await?;
        }

        Ok(())
    }
}
<commit_msg>updatehub-sdk: listener: Use `default()` to StateChangeListener::new() impl<commit_after>// Copyright (C) 2018, 2019, 2020 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::{Error, Result};
use async_std::{
    io::BufReader,
    os::unix::net::{UnixListener, UnixStream},
    prelude::*,
};
use log::warn;
use std::{env, fs, path::Path, pin::Pin};

const SDK_TRIGGER_FILENAME: &str =
    "/usr/share/updatehub/state-change-callbacks.d/10-updatehub-sdk-statechange-trigger";
const SOCKET_PATH: &str = "/run/updatehub-statechange.sock";

type CallbackFn = dyn Fn(Handler) -> Pin<Box<dyn Future<Output = Result<()>>>>;

#[derive(Default)]
pub struct StateChangeListener {
    download_callbacks: Vec<Box<CallbackFn>>,
    install_callbacks: Vec<Box<CallbackFn>>,
    reboot_callbacks: Vec<Box<CallbackFn>>,
    error_callbacks: Vec<Box<CallbackFn>>,
}

#[derive(Debug)]
pub enum State {
    Download,
    Install,
    Reboot,
    Error,
}

pub struct Handler {
    stream: UnixStream,
}

impl Handler {
    // Cancels the current action on the agent.
    pub async fn cancel(&mut self) -> Result<()> {
        self.stream.write_all(b"cancel").await.map_err(Error::Io)
    }

    // Tell the agent to proceed with the transition.
    pub async fn proceed(&self) -> Result<()> {
        // No message need to be sent to the connection in order to the
        // agent to proceed handling the current state.
        Ok(())
    }
}

impl StateChangeListener {
    #[inline]
    pub fn new() -> Self {
        StateChangeListener::default()
    }

    pub fn on_state<F, Fut>(&mut self, state: State, f: F)
    where
        F: Fn(Handler) -> Fut + 'static,
        Fut: Future<Output = Result<()>> + 'static,
    {
        match state {
            State::Download => self.download_callbacks.push(Box::new(move |d| Box::pin(f(d)))),
            State::Install => self.install_callbacks.push(Box::new(move |d| Box::pin(f(d)))),
            State::Reboot => self.reboot_callbacks.push(Box::new(move |d| Box::pin(f(d)))),
            State::Error => self.error_callbacks.push(Box::new(move |d| Box::pin(f(d)))),
        }
    }

    pub async fn listen(&self) -> Result<()> {
        let sdk_trigger = Path::new(SDK_TRIGGER_FILENAME);
        if !sdk_trigger.exists() {
            warn!("WARNING: updatehub-sdk-statechange-trigger not found on {:?}", sdk_trigger);
        }

        let socket_path = env::var("UH_LISTENER_TEST").unwrap_or_else(|_| SOCKET_PATH.to_string());
        let socket_path = Path::new(&socket_path);
        if socket_path.exists() {
            fs::remove_file(&socket_path)?;
        }

        let listener = UnixListener::bind(socket_path).await?;
        loop {
            let (socket, ..) = listener.accept().await?;
            self.handle_connection(socket).await?;
        }
    }

    async fn handle_connection(&self, stream: UnixStream) -> Result<()> {
        let mut reader = BufReader::new(&stream);
        let mut line = String::new();

        reader.read_line(&mut line).await?;

        self.emit(stream, &line.trim()).await
    }

    async fn emit(&self, stream: UnixStream, input: &str) -> Result<()> {
        let callbacks = match input {
            "download" => &self.download_callbacks,
            "install" => &self.install_callbacks,
            "reboot" => &self.reboot_callbacks,
            "error" => &self.error_callbacks,
            _ => unreachable!("the input is not valid"),
        };

        for f in callbacks {
            let stream = stream.clone();
            f(Handler { stream }).await?;
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>use crate::lexical::math::{Limb, Math};
use std::cmp;

#[derive(Clone, Default)]
struct Bigint {
    data: Vec<Limb>,
}

impl Math for Bigint {
    #[inline]
    fn data(&self) -> &Vec<Limb> {
        &self.data
    }

    #[inline]
    fn data_mut(&mut self) -> &mut Vec<Limb> {
        &mut self.data
    }
}

#[cfg(limb_width_32)]
pub(crate) fn from_u32(x: &[u32]) -> Vec<Limb> {
    x.iter().cloned().collect()
}

#[cfg(limb_width_64)]
pub(crate) fn from_u32(x: &[u32]) -> Vec<Limb> {
    let mut v = Vec::<Limb>::default();
    for xi in x.chunks(2) {
        match xi.len() {
            1 => v.push(xi[0] as u64),
            2 => v.push(((xi[1] as u64) << 32) | (xi[0] as u64)),
            _ => unreachable!(),
        }
    }

    v
}

#[test]
fn compare_test() {
    // Simple
    let x = Bigint {
        data: from_u32(&[1]),
    };
    let y = Bigint {
        data: from_u32(&[2]),
    };
    assert_eq!(x.compare(&y), cmp::Ordering::Less);
    assert_eq!(x.compare(&x), cmp::Ordering::Equal);
    assert_eq!(y.compare(&x), cmp::Ordering::Greater);

    // Check asymmetric
    let x = Bigint {
        data: from_u32(&[5, 1]),
    };
    let y = Bigint {
        data: from_u32(&[2]),
    };
    assert_eq!(x.compare(&y), cmp::Ordering::Greater);
    assert_eq!(x.compare(&x), cmp::Ordering::Equal);
    assert_eq!(y.compare(&x), cmp::Ordering::Less);

    // Check when we use reverse ordering properly.
    let x = Bigint {
        data: from_u32(&[5, 1, 9]),
    };
    let y = Bigint {
        data: from_u32(&[6, 2, 8]),
    };
    assert_eq!(x.compare(&y), cmp::Ordering::Greater);
    assert_eq!(x.compare(&x), cmp::Ordering::Equal);
    assert_eq!(y.compare(&x), cmp::Ordering::Less);

    // Complex scenario, check it properly uses reverse ordering.
    let x = Bigint {
        data: from_u32(&[0, 1, 9]),
    };
    let y = Bigint {
        data: from_u32(&[4294967295, 0, 9]),
    };
    assert_eq!(x.compare(&y), cmp::Ordering::Greater);
    assert_eq!(x.compare(&x), cmp::Ordering::Equal);
    assert_eq!(y.compare(&x), cmp::Ordering::Less);
}

#[test]
fn hi64_test() {
    assert_eq!(Bigint::from_u64(0xA).hi64(), (0xA000000000000000, false));
    assert_eq!(Bigint::from_u64(0xAB).hi64(), (0xAB00000000000000, false));
    assert_eq!(
        Bigint::from_u64(0xAB00000000).hi64(),
        (0xAB00000000000000, false)
    );
    assert_eq!(
        Bigint::from_u64(0xA23456789A).hi64(),
        (0xA23456789A000000, false)
    );
}

#[test]
fn bit_length_test() {
    let x = Bigint {
        data: from_u32(&[0, 0, 0, 1]),
    };
    assert_eq!(x.bit_length(), 97);

    let x = Bigint {
        data: from_u32(&[0, 0, 0, 3]),
    };
    assert_eq!(x.bit_length(), 98);

    let x = Bigint {
        data: from_u32(&[1 << 31]),
    };
    assert_eq!(x.bit_length(), 32);
}

#[test]
fn iadd_small_test() {
    // Overflow check (single)
    // This should set all the internal data values to 0, the top
    // value to (1<<31), and the bottom value to (4>>1).
    // This is because the max_value + 1 leads to all 0s, we set the
    // topmost bit to 1.
    let mut x = Bigint {
        data: from_u32(&[4294967295]),
    };
    x.iadd_small(5);
    assert_eq!(x.data, from_u32(&[4, 1]));

    // No overflow, single value
    let mut x = Bigint {
        data: from_u32(&[5]),
    };
    x.iadd_small(7);
    assert_eq!(x.data, from_u32(&[12]));

    // Single carry, internal overflow
    let mut x = Bigint::from_u64(0x80000000FFFFFFFF);
    x.iadd_small(7);
    assert_eq!(x.data, from_u32(&[6, 0x80000001]));

    // Double carry, overflow
    let mut x = Bigint::from_u64(0xFFFFFFFFFFFFFFFF);
    x.iadd_small(7);
    assert_eq!(x.data, from_u32(&[6, 0, 1]));
}

#[test]
fn imul_small_test() {
    // No overflow check, 1-int.
    let mut x = Bigint {
        data: from_u32(&[5]),
    };
    x.imul_small(7);
    assert_eq!(x.data, from_u32(&[35]));

    // No overflow check, 2-ints.
    let mut x = Bigint::from_u64(0x4000000040000);
    x.imul_small(5);
    assert_eq!(x.data, from_u32(&[0x00140000, 0x140000]));

    // Overflow, 1 carry.
    let mut x = Bigint {
        data: from_u32(&[0x33333334]),
    };
    x.imul_small(5);
    assert_eq!(x.data, from_u32(&[4, 1]));

    // Overflow, 1 carry, internal.
    let mut x = Bigint::from_u64(0x133333334);
    x.imul_small(5);
    assert_eq!(x.data, from_u32(&[4, 6]));

    // Overflow, 2 carries.
    let mut x = Bigint::from_u64(0x3333333333333334);
    x.imul_small(5);
    assert_eq!(x.data, from_u32(&[4, 0, 1]));
}

#[test]
fn shl_test() {
    // Pattern generated via `''.join(["1" +"0"*i for i in range(20)])`
    let mut big = Bigint {
        data: from_u32(&[0xD2210408]),
    };
    big.ishl(5);
    assert_eq!(big.data, from_u32(&[0x44208100, 0x1A]));
    big.ishl(32);
    assert_eq!(big.data, from_u32(&[0, 0x44208100, 0x1A]));
    big.ishl(27);
    assert_eq!(big.data, from_u32(&[0, 0, 0xD2210408]));

    // 96-bits of previous pattern
    let mut big = Bigint {
        data: from_u32(&[0x20020010, 0x8040100, 0xD2210408]),
    };
    big.ishl(5);
    assert_eq!(big.data, from_u32(&[0x400200, 0x802004, 0x44208101, 0x1A]));
    big.ishl(32);
    assert_eq!(
        big.data,
        from_u32(&[0, 0x400200, 0x802004, 0x44208101, 0x1A])
    );
    big.ishl(27);
    assert_eq!(
        big.data,
        from_u32(&[0, 0, 0x20020010, 0x8040100, 0xD2210408])
    );
}
<commit_msg>Remove gratuitous inline from lexical test<commit_after>use crate::lexical::math::{Limb, Math};
use std::cmp;

#[derive(Clone, Default)]
struct Bigint {
    data: Vec<Limb>,
}

impl Math for Bigint {
    fn data(&self) -> &Vec<Limb> {
        &self.data
    }

    fn data_mut(&mut self) -> &mut Vec<Limb> {
        &mut self.data
    }
}

#[cfg(limb_width_32)]
pub(crate) fn from_u32(x: &[u32]) -> Vec<Limb> {
    x.iter().cloned().collect()
}

#[cfg(limb_width_64)]
pub(crate) fn from_u32(x: &[u32]) -> Vec<Limb> {
    let mut v = Vec::<Limb>::default();
    for xi in x.chunks(2) {
        match xi.len() {
            1 => v.push(xi[0] as u64),
            2 => v.push(((xi[1] as u64) << 32) | (xi[0] as u64)),
            _ => unreachable!(),
        }
    }

    v
}

#[test]
fn compare_test() {
    // Simple
    let x = Bigint {
        data: from_u32(&[1]),
    };
    let y = Bigint {
        data: from_u32(&[2]),
    };
    assert_eq!(x.compare(&y), cmp::Ordering::Less);
    assert_eq!(x.compare(&x), cmp::Ordering::Equal);
    assert_eq!(y.compare(&x), cmp::Ordering::Greater);

    // Check asymmetric
    let x = Bigint {
        data: from_u32(&[5, 1]),
    };
    let y = Bigint {
        data: from_u32(&[2]),
    };
    assert_eq!(x.compare(&y), cmp::Ordering::Greater);
    assert_eq!(x.compare(&x), cmp::Ordering::Equal);
    assert_eq!(y.compare(&x), cmp::Ordering::Less);

    // Check when we use reverse ordering properly.
    let x = Bigint {
        data: from_u32(&[5, 1, 9]),
    };
    let y = Bigint {
        data: from_u32(&[6, 2, 8]),
    };
    assert_eq!(x.compare(&y), cmp::Ordering::Greater);
    assert_eq!(x.compare(&x), cmp::Ordering::Equal);
    assert_eq!(y.compare(&x), cmp::Ordering::Less);

    // Complex scenario, check it properly uses reverse ordering.
    let x = Bigint {
        data: from_u32(&[0, 1, 9]),
    };
    let y = Bigint {
        data: from_u32(&[4294967295, 0, 9]),
    };
    assert_eq!(x.compare(&y), cmp::Ordering::Greater);
    assert_eq!(x.compare(&x), cmp::Ordering::Equal);
    assert_eq!(y.compare(&x), cmp::Ordering::Less);
}

#[test]
fn hi64_test() {
    assert_eq!(Bigint::from_u64(0xA).hi64(), (0xA000000000000000, false));
    assert_eq!(Bigint::from_u64(0xAB).hi64(), (0xAB00000000000000, false));
    assert_eq!(
        Bigint::from_u64(0xAB00000000).hi64(),
        (0xAB00000000000000, false)
    );
    assert_eq!(
        Bigint::from_u64(0xA23456789A).hi64(),
        (0xA23456789A000000, false)
    );
}

#[test]
fn bit_length_test() {
    let x = Bigint {
        data: from_u32(&[0, 0, 0, 1]),
    };
    assert_eq!(x.bit_length(), 97);

    let x = Bigint {
        data: from_u32(&[0, 0, 0, 3]),
    };
    assert_eq!(x.bit_length(), 98);

    let x = Bigint {
        data: from_u32(&[1 << 31]),
    };
    assert_eq!(x.bit_length(), 32);
}

#[test]
fn iadd_small_test() {
    // Overflow check (single)
    // This should set all the internal data values to 0, the top
    // value to (1<<31), and the bottom value to (4>>1).
    // This is because the max_value + 1 leads to all 0s, we set the
    // topmost bit to 1.
    let mut x = Bigint {
        data: from_u32(&[4294967295]),
    };
    x.iadd_small(5);
    assert_eq!(x.data, from_u32(&[4, 1]));

    // No overflow, single value
    let mut x = Bigint {
        data: from_u32(&[5]),
    };
    x.iadd_small(7);
    assert_eq!(x.data, from_u32(&[12]));

    // Single carry, internal overflow
    let mut x = Bigint::from_u64(0x80000000FFFFFFFF);
    x.iadd_small(7);
    assert_eq!(x.data, from_u32(&[6, 0x80000001]));

    // Double carry, overflow
    let mut x = Bigint::from_u64(0xFFFFFFFFFFFFFFFF);
    x.iadd_small(7);
    assert_eq!(x.data, from_u32(&[6, 0, 1]));
}

#[test]
fn imul_small_test() {
    // No overflow check, 1-int.
    let mut x = Bigint {
        data: from_u32(&[5]),
    };
    x.imul_small(7);
    assert_eq!(x.data, from_u32(&[35]));

    // No overflow check, 2-ints.
    let mut x = Bigint::from_u64(0x4000000040000);
    x.imul_small(5);
    assert_eq!(x.data, from_u32(&[0x00140000, 0x140000]));

    // Overflow, 1 carry.
    let mut x = Bigint {
        data: from_u32(&[0x33333334]),
    };
    x.imul_small(5);
    assert_eq!(x.data, from_u32(&[4, 1]));

    // Overflow, 1 carry, internal.
    let mut x = Bigint::from_u64(0x133333334);
    x.imul_small(5);
    assert_eq!(x.data, from_u32(&[4, 6]));

    // Overflow, 2 carries.
    let mut x = Bigint::from_u64(0x3333333333333334);
    x.imul_small(5);
    assert_eq!(x.data, from_u32(&[4, 0, 1]));
}

#[test]
fn shl_test() {
    // Pattern generated via `''.join(["1" +"0"*i for i in range(20)])`
    let mut big = Bigint {
        data: from_u32(&[0xD2210408]),
    };
    big.ishl(5);
    assert_eq!(big.data, from_u32(&[0x44208100, 0x1A]));
    big.ishl(32);
    assert_eq!(big.data, from_u32(&[0, 0x44208100, 0x1A]));
    big.ishl(27);
    assert_eq!(big.data, from_u32(&[0, 0, 0xD2210408]));

    // 96-bits of previous pattern
    let mut big = Bigint {
        data: from_u32(&[0x20020010, 0x8040100, 0xD2210408]),
    };
    big.ishl(5);
    assert_eq!(big.data, from_u32(&[0x400200, 0x802004, 0x44208101, 0x1A]));
    big.ishl(32);
    assert_eq!(
        big.data,
        from_u32(&[0, 0x400200, 0x802004, 0x44208101, 0x1A])
    );
    big.ishl(27);
    assert_eq!(
        big.data,
        from_u32(&[0, 0, 0x20020010, 0x8040100, 0xD2210408])
    );
}
<|endoftext|>


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

//! An implementation of Ken Perlin's [Improved Noise]
//! (http://mrl.nyu.edu/~perlin/noise/) algorithm.

use std::num::cast;
use std::rand::Rng;

pub trait Perlin<T> {
    fn perlin(&self, ctx: &PerlinContext) -> T;
}

// impl<T: Clone + Float> Perlin<T> for T {
//     fn perlin(&self, ctx: &PerlinContext) -> T {
//         ctx.gen1(self)
//     }
// }

impl<T: Clone + Float> Perlin<T> for (T,) {
    fn perlin(&self, ctx: &PerlinContext) -> T {
        match *self {
            (ref x,) => ctx.gen1(x)
        }
    }
}

impl<T: Clone + Float> Perlin<T> for (T, T) {
    fn perlin(&self, ctx: &PerlinContext) -> T {
        match *self {
            (ref x, ref y) => ctx.gen2(x, y)
        }
    }
}

impl<T: Clone + Float> Perlin<T> for (T, T, T) {
    fn perlin(&self, ctx: &PerlinContext) -> T {
        match *self {
            (ref x, ref y, ref z) => ctx.gen3(x, y, z)
        }
    }
}

impl<T: Clone + Float> Perlin<T> for [T, ..1] {
    fn perlin(&self, ctx: &PerlinContext) -> T {
        match *self {
            [ref x] => ctx.gen1(x),
        }
    }
}

impl<T: Clone + Float> Perlin<T> for [T, ..2] {
    fn perlin(&self, ctx: &PerlinContext) -> T {
        match *self {
            [ref x, ref y] => ctx.gen2(x, y),
        }
    }
}

impl<T: Clone + Float> Perlin<T> for [T, ..3] {
    fn perlin(&self, ctx: &PerlinContext) -> T {
        match *self {
            [ref x, ref y, ref z] => ctx.gen3(x, y, z),
        }
    }
}

/// A perlin noise generator
pub struct PerlinContext {
    // permutation table
    priv ptable: ~[u8]//[uint, ..512],
}

impl PerlinContext {
    pub fn new<R: Rng>(rng: &mut R) -> PerlinContext {
        PerlinContext { ptable: rng.gen_vec::<u8>(512) }
    }

    pub fn gen1<T:Clone + Float>(&self, x: &T) -> T {
        self.gen2(x, &cast(0))
    }

    pub fn gen2<T:Clone + Float>(&self, x: &T, y: &T) -> T {
        self.gen3(x, y, &cast(0))
    }

    pub fn gen3<T:Clone + Float>(&self, x: &T, y: &T, z: &T) -> T {
        // Find the unit cube that contains the point
        let X = x.floor().to_uint() as u8;
        let Y = y.floor().to_uint() as u8;
        let Z = z.floor().to_uint() as u8;

        // Find the relative X, Y, Z of point in the cube
        let x_ = *x - x.floor();
        let y_ = *y - y.floor();
        let z_ = *z - z.floor();

        // Compute the fade curves for X, Y, Z
        let u = fade(x_.clone());
        let v = fade(y_.clone());
        let w = fade(z_.clone());

        // Hash coordinates of the 8 cube corners
        let A  = self.ptable[X    ] + Y;
        let AA = self.ptable[A    ] + Z;
        let AB = self.ptable[A + 1] + Z;
        let B  = self.ptable[X + 1] + Y;
        let BA = self.ptable[B    ] + Z;
        let BB = self.ptable[B + 1] + Z;

        // Add the blended results from the 8 corners of the cube
        lerp(w, lerp(v.clone(), lerp(u.clone(), grad(self.ptable[AA    ] as uint, x_.clone(), y_.clone(), z_.clone()),
                                                grad(self.ptable[BA    ] as uint, x_-cast(1), y_.clone(), z_.clone())),
                                lerp(u.clone(), grad(self.ptable[AB    ] as uint, x_.clone(), y_-cast(1), z_.clone()),
                                                grad(self.ptable[BB    ] as uint, x_-cast(1), y_-cast(1), z_.clone()))),
                lerp(v.clone(), lerp(u.clone(), grad(self.ptable[AA + 1] as uint, x_.clone(), y_.clone(), z_-cast(1)),
                                                grad(self.ptable[BA + 1] as uint, x_-cast(1), y_.clone(), z_-cast(1))),
                                lerp(u.clone(), grad(self.ptable[AB + 1] as uint, x_.clone(), y_-cast(1), z_-cast(1)),
                                                grad(self.ptable[BB + 1] as uint, x_-cast(1), y_-cast(1), z_-cast(1)))))
    }
}

fn fade<T:Num + NumCast>(t: T) -> T {
    t * t * t * (t * (t * cast(6) - cast(15)) + cast(10))
}

fn lerp<T:Num + NumCast>(t: T, a: T, b: T) -> T {
    a + t * (b - a)
}

fn grad<T:Clone + Num + NumCast>(hash: uint, x: T, y: T, z: T) -> T {
    let h = hash & 15;

    let u = match h {
        0..7 => x.clone(),
        _    => y.clone(),
    };
    let v = match h {
        0..3    => y.clone(),
        12 | 14 => x.clone(),
        _       => z.clone(),
    };

    (if (h & 1) == 0 { u } else { -u }) +
    (if (h & 2) == 0 { v } else { -v })
}

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

//! An implementation of Ken Perlin's [Improved Noise]
//! (http://mrl.nyu.edu/~perlin/noise/) algorithm.

use std::num::cast;
use std::rand::Rng;

pub trait Perlin<T> {
    fn perlin(&self, ctx: &PerlinContext) -> T;
}

// impl<T: Clone + Float> Perlin<T> for T {
//     fn perlin(&self, ctx: &PerlinContext) -> T {
//         ctx.gen1(self)
//     }
// }

impl<T: Clone + Float> Perlin<T> for (T,) {
    fn perlin(&self, ctx: &PerlinContext) -> T {
        match *self {
            (ref x,) => ctx.gen1(x)
        }
    }
}

impl<T: Clone + Float> Perlin<T> for (T, T) {
    fn perlin(&self, ctx: &PerlinContext) -> T {
        match *self {
            (ref x, ref y) => ctx.gen2(x, y)
        }
    }
}

impl<T: Clone + Float> Perlin<T> for (T, T, T) {
    fn perlin(&self, ctx: &PerlinContext) -> T {
        match *self {
            (ref x, ref y, ref z) => ctx.gen3(x, y, z)
        }
    }
}

impl<T: Clone + Float> Perlin<T> for [T, ..1] {
    fn perlin(&self, ctx: &PerlinContext) -> T {
        match *self {
            [ref x] => ctx.gen1(x),
        }
    }
}

impl<T: Clone + Float> Perlin<T> for [T, ..2] {
    fn perlin(&self, ctx: &PerlinContext) -> T {
        match *self {
            [ref x, ref y] => ctx.gen2(x, y),
        }
    }
}

impl<T: Clone + Float> Perlin<T> for [T, ..3] {
    fn perlin(&self, ctx: &PerlinContext) -> T {
        match *self {
            [ref x, ref y, ref z] => ctx.gen3(x, y, z),
        }
    }
}

/// A perlin noise generator
pub struct PerlinContext {
    // permutation table
    priv ptable: ~[u8]//[uint, ..512],
}

impl PerlinContext {
    pub fn new<R: Rng>(rng: &mut R) -> PerlinContext {
        PerlinContext { ptable: rng.gen_vec::<u8>(512) }
    }

    pub fn gen1<T:Clone + Float>(&self, x: &T) -> T {
        self.gen2(x, &cast(0))
    }

    pub fn gen2<T:Clone + Float>(&self, x: &T, y: &T) -> T {
        self.gen3(x, y, &cast(0))
    }

    pub fn gen3<T:Clone + Float>(&self, x: &T, y: &T, z: &T) -> T {
        // Find the unit cube that contains the point
        let X = x.floor().to_uint() as u8;
        let Y = y.floor().to_uint() as u8;
        let Z = z.floor().to_uint() as u8;

        // Find the relative X, Y, Z of point in the cube
        let x_ = *x - x.floor();
        let y_ = *y - y.floor();
        let z_ = *z - z.floor();

        // Compute the fade curves for X, Y, Z
        let u = fade(x_.clone());
        let v = fade(y_.clone());
        let w = fade(z_.clone());

        // Hash coordinates of the 8 cube corners
        let A  = self.ptable[X    ] + Y;
        let AA = self.ptable[A    ] + Z;
        let AB = self.ptable[A + 1] + Z;
        let B  = self.ptable[X + 1] + Y;
        let BA = self.ptable[B    ] + Z;
        let BB = self.ptable[B + 1] + Z;

        // Add the blended results from the 8 corners of the cube
        lerp(w, lerp(v.clone(), lerp(u.clone(), grad(self.ptable[AA    ], x_.clone(), y_.clone(), z_.clone()),
                                                grad(self.ptable[BA    ], x_-cast(1), y_.clone(), z_.clone())),
                                lerp(u.clone(), grad(self.ptable[AB    ], x_.clone(), y_-cast(1), z_.clone()),
                                                grad(self.ptable[BB    ], x_-cast(1), y_-cast(1), z_.clone()))),
                lerp(v.clone(), lerp(u.clone(), grad(self.ptable[AA + 1], x_.clone(), y_.clone(), z_-cast(1)),
                                                grad(self.ptable[BA + 1], x_-cast(1), y_.clone(), z_-cast(1))),
                                lerp(u.clone(), grad(self.ptable[AB + 1], x_.clone(), y_-cast(1), z_-cast(1)),
                                                grad(self.ptable[BB + 1], x_-cast(1), y_-cast(1), z_-cast(1)))))
    }
}

#[inline]
fn fade<T:Num + NumCast>(t: T) -> T {
    t * t * t * (t * (t * cast(6) - cast(15)) + cast(10))
}

#[inline]
fn lerp<T:Num + NumCast>(t: T, a: T, b: T) -> T {
    a + t * (b - a)
}

fn grad<T:Clone + Num + NumCast>(hash: u8, x: T, y: T, z: T) -> T {
    let h = hash & 15;

    let u = match h {
        0..7 => x.clone(),
        _    => y.clone(),
    };
    let v = match h {
        0..3    => y.clone(),
        12 | 14 => x.clone(),
        _       => z.clone(),
    };

    (if (h & 1) == 0 { u } else { -u }) +
    (if (h & 2) == 0 { v } else { -v })
}

<|endoftext|>


<commit_before>#[cfg(target_os = "linux")]
mod epoll;

#[cfg(target_os = "linux")]
pub use self::epoll::{Events, Selector};

#[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd", target_os = "dragonfly"))]
mod kqueue;

#[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd", target_os = "dragonfly"))]
pub use self::kqueue::{Events, Selector};

mod awakener;
mod eventedfd;
mod io;
mod net;
mod socket;
mod tcp;
mod udp;
mod uds;

pub use self::awakener::Awakener;
pub use self::eventedfd::EventedFd;
pub use self::io::Io;
pub use self::socket::Socket;
pub use self::tcp::{TcpStream, TcpListener};
pub use self::udp::UdpSocket;
pub use self::uds::UnixSocket;

pub fn pipe() -> ::io::Result<(Io, Io)> {
    use nix::fcntl::{O_NONBLOCK, O_CLOEXEC};
    use nix::unistd::pipe2;

    let (rd, wr) = try!(pipe2(O_NONBLOCK | O_CLOEXEC)
        .map_err(from_nix_error));

    Ok((Io::from_raw_fd(rd), Io::from_raw_fd(wr)))
}

pub fn from_nix_error(err: ::nix::Error) -> ::io::Error {
    ::io::Error::from_raw_os_error(err.errno() as i32)
}

mod nix {
    pub use nix::{
        c_int,
        Error,
    };
    pub use nix::errno::{EINPROGRESS, EAGAIN};
    pub use nix::fcntl::{fcntl, FcntlArg, O_NONBLOCK};
    pub use nix::sys::socket::{
        sockopt,
        AddressFamily,
        SockAddr,
        SockType,
        SockLevel,
        InetAddr,
        Ipv4Addr,
        Ipv6Addr,
        MSG_DONTWAIT,
        SOCK_NONBLOCK,
        SOCK_CLOEXEC,
        accept4,
        bind,
        connect,
        getpeername,
        getsockname,
        getsockopt,
        ip_mreq,
        ipv6_mreq,
        linger,
        listen,
        recvfrom,
        sendto,
        setsockopt,
        socket,
        shutdown,
        Shutdown,
    };
    pub use nix::sys::time::TimeVal;
    pub use nix::unistd::{
        read,
        write,
        dup,
    };
}

<commit_msg>epoll: should also work with Android.<commit_after>#[cfg(any(target_os = "linux", target_os = "android"))]
mod epoll;

#[cfg(any(target_os = "linux", target_os = "android"))]
pub use self::epoll::{Events, Selector};

#[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd", target_os = "dragonfly"))]
mod kqueue;

#[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd", target_os = "dragonfly"))]
pub use self::kqueue::{Events, Selector};

mod awakener;
mod eventedfd;
mod io;
mod net;
mod socket;
mod tcp;
mod udp;
mod uds;

pub use self::awakener::Awakener;
pub use self::eventedfd::EventedFd;
pub use self::io::Io;
pub use self::socket::Socket;
pub use self::tcp::{TcpStream, TcpListener};
pub use self::udp::UdpSocket;
pub use self::uds::UnixSocket;

pub fn pipe() -> ::io::Result<(Io, Io)> {
    use nix::fcntl::{O_NONBLOCK, O_CLOEXEC};
    use nix::unistd::pipe2;

    let (rd, wr) = try!(pipe2(O_NONBLOCK | O_CLOEXEC)
        .map_err(from_nix_error));

    Ok((Io::from_raw_fd(rd), Io::from_raw_fd(wr)))
}

pub fn from_nix_error(err: ::nix::Error) -> ::io::Error {
    ::io::Error::from_raw_os_error(err.errno() as i32)
}

mod nix {
    pub use nix::{
        c_int,
        Error,
    };
    pub use nix::errno::{EINPROGRESS, EAGAIN};
    pub use nix::fcntl::{fcntl, FcntlArg, O_NONBLOCK};
    pub use nix::sys::socket::{
        sockopt,
        AddressFamily,
        SockAddr,
        SockType,
        SockLevel,
        InetAddr,
        Ipv4Addr,
        Ipv6Addr,
        MSG_DONTWAIT,
        SOCK_NONBLOCK,
        SOCK_CLOEXEC,
        accept4,
        bind,
        connect,
        getpeername,
        getsockname,
        getsockopt,
        ip_mreq,
        ipv6_mreq,
        linger,
        listen,
        recvfrom,
        sendto,
        setsockopt,
        socket,
        shutdown,
        Shutdown,
    };
    pub use nix::sys::time::TimeVal;
    pub use nix::unistd::{
        read,
        write,
        dup,
    };
}

<|endoftext|>


<commit_before>use raft::raftpb::{HardState, ConfState, Entry, Snapshot};
use protobuf;
use raft::errors::Result;
use raft::errors::{Error, StorageError};

#[derive(Debug, Clone)]
pub struct RaftState {
    hard_state: HardState,
    conf_state: ConfState,
}

pub trait Storage {
    fn initial_state(&self) -> Result<RaftState>;
    fn entries(&self, low: u64, high: u64, max_size: u64) -> Result<&[Entry]>;
    fn term(&self, idx: u64) -> Result<u64>;
    fn first_index(&self) -> Result<u64>;
    fn last_index(&self) -> Result<u64>;
    fn snapshot(&self) -> Result<Snapshot>;
}

pub struct MemStorage {
    hard_state: HardState,
    snapshot: Snapshot,
    entries: Vec<Entry>,
}

impl MemStorage {
    pub fn new() -> MemStorage {
        MemStorage {
            // When starting from scratch populate the list with a dummy entry at term zero.
            entries: vec![Entry::new()],
            hard_state: HardState::new(),
            snapshot: Snapshot::new(),
        }
    }

    pub fn set_hardstate(&mut self, hs: HardState) {
        self.hard_state = hs;
    }

    fn inner_last_index(&self) -> u64 {
        return self.entries[0].get_Index() + self.entries.len() as u64 - 1;
    }

    fn limit_size(entries: &[Entry], max: u64) -> Result<&[Entry]> {
        if entries.len() == 0 {
            return Ok(entries);
        }

        let mut size = protobuf::Message::compute_size(&entries[0]) as u64;
        let mut limit = 1u64;
        while limit < entries.len() as u64 {
            size += protobuf::Message::compute_size(&entries[limit as usize]) as u64;
            if size > max {
                break;
            }
            limit += 1;
        }
        let ents = &entries[..limit as usize];
        Ok(ents)
    }
}

impl Storage for MemStorage {
    fn initial_state(&self) -> Result<RaftState> {
        Ok(RaftState {
            hard_state: self.hard_state.clone(),
            conf_state: self.snapshot.get_metadata().get_conf_state().clone(),
        })
    }

    fn entries(&self, low: u64, high: u64, max_size: u64) -> Result<&[Entry]> {
        let offset = self.entries[0].get_Index();
        if low <= offset {
            return Err(Error::Store(StorageError::Compacted));
        }

        if high > self.inner_last_index() + 1 {
            panic!("index out of bound")
        }
        // only contains dummy entries.
        if self.entries.len() == 1 {
            return Err(Error::Store(StorageError::Unavailable));
        }

        let lo = (low - offset) as usize;
        let hi = (high - offset) as usize;
        let ents: &[Entry] = &self.entries[lo..hi];
        return MemStorage::limit_size(ents, max_size);
    }

    fn term(&self, idx: u64) -> Result<u64> {
        let offset = self.entries[0].get_Index();
        if idx < offset {
            return Err(Error::Store(StorageError::Compacted));
        }
        Ok(self.entries[(idx - offset) as usize].get_Term())
    }

    fn first_index(&self) -> Result<u64> {
        Ok(self.entries[0].get_Index() + 1)
    }

    fn last_index(&self) -> Result<u64> {
        Ok(self.inner_last_index())
    }

    fn snapshot(&self) -> Result<Snapshot> {
        unimplemented!()
    }
}
<commit_msg>raft: implement apply_snapshot and snapshot method.<commit_after>use raft::raftpb::{HardState, ConfState, Entry, Snapshot};
use protobuf;
use raft::errors::Result;
use raft::errors::{Error, StorageError};

#[derive(Debug, Clone)]
pub struct RaftState {
    hard_state: HardState,
    conf_state: ConfState,
}

pub trait Storage {
    fn initial_state(&self) -> Result<RaftState>;
    fn entries(&self, low: u64, high: u64, max_size: u64) -> Result<&[Entry]>;
    fn term(&self, idx: u64) -> Result<u64>;
    fn first_index(&self) -> Result<u64>;
    fn last_index(&self) -> Result<u64>;
    fn snapshot(&self) -> Result<&Snapshot>;
}

pub struct MemStorage {
    hard_state: HardState,
    snapshot: Snapshot,
    entries: Vec<Entry>,
}

impl MemStorage {
    pub fn new() -> MemStorage {
        MemStorage {
            // When starting from scratch populate the list with a dummy entry at term zero.
            entries: vec![Entry::new()],
            hard_state: HardState::new(),
            snapshot: Snapshot::new(),
        }
    }

    pub fn set_hardstate(&mut self, hs: HardState) {
        self.hard_state = hs;
    }

    fn inner_last_index(&self) -> u64 {
        return self.entries[0].get_Index() + self.entries.len() as u64 - 1;
    }

    fn limit_size(entries: &[Entry], max: u64) -> Result<&[Entry]> {
        if entries.len() == 0 {
            return Ok(entries);
        }

        let mut size = protobuf::Message::compute_size(&entries[0]) as u64;
        let mut limit = 1u64;
        while limit < entries.len() as u64 {
            size += protobuf::Message::compute_size(&entries[limit as usize]) as u64;
            if size > max {
                break;
            }
            limit += 1;
        }
        let ents = &entries[..limit as usize];
        Ok(ents)
    }

    fn apply_snapshot(&mut self, snapshot: Snapshot) ->Result<()> {
	let mut e = Entry::new();
	e.set_Term(snapshot.get_metadata().get_term());
	e.set_Index(snapshot.get_metadata().get_index());
	self.entries = vec![e];
	self.snapshot  = snapshot;
	Ok(())
    }
}

impl Storage for MemStorage {
    fn initial_state(&self) -> Result<RaftState> {
        Ok(RaftState {
            hard_state: self.hard_state.clone(),
            conf_state: self.snapshot.get_metadata().get_conf_state().clone(),
        })
    }

    fn entries(&self, low: u64, high: u64, max_size: u64) -> Result<&[Entry]> {
        let offset = self.entries[0].get_Index();
        if low <= offset {
            return Err(Error::Store(StorageError::Compacted));
        }

        if high > self.inner_last_index() + 1 {
            panic!("index out of bound")
        }
        // only contains dummy entries.
        if self.entries.len() == 1 {
            return Err(Error::Store(StorageError::Unavailable));
        }

        let lo = (low - offset) as usize;
        let hi = (high - offset) as usize;
        let ents: &[Entry] = &self.entries[lo..hi];
        return MemStorage::limit_size(ents, max_size);
    }

    fn term(&self, idx: u64) -> Result<u64> {
        let offset = self.entries[0].get_Index();
        if idx < offset {
            return Err(Error::Store(StorageError::Compacted));
        }
        Ok(self.entries[(idx - offset) as usize].get_Term())
    }

    fn first_index(&self) -> Result<u64> {
        Ok(self.entries[0].get_Index() + 1)
    }

    fn last_index(&self) -> Result<u64> {
        Ok(self.inner_last_index())
    }

    fn snapshot(&self) -> Result<&Snapshot> {
	Ok(&self.snapshot)
    }
}
<|endoftext|>


<commit_before>mod entities;
mod input;
mod updates;
mod util;

use chrono::{DateTime, Duration as OldDuration, Utc};
use log::{error, trace};
use rand_core::{OsRng, RngCore};
use serde_derive::Serialize;
use std::collections::HashMap;
use std::mem;

pub use self::entities::*;
pub use self::input::*;
pub use self::updates::*;
pub use self::util::*;

use crate::server::{ArenaId, ArenaPoint, Direction, Line, Player, PlayerId};

const ARENA_WIDTH: usize = 800;
const ARENA_HEIGHT: usize = 800;
const ARENA_MAX_PLAYERS: usize = 8;
const ARENA_START_TIMER_SECONDS: i64 = 5;
const LIGHTCYCLE_SPEED: isize = 1;

#[derive(Debug, Clone, Serialize)]
pub struct Arena {
    pub id: ArenaId,
    pub name: String,
    pub width: usize,
    pub height: usize,
    pub max_players: usize,

    pub started: Option<DateTime<Utc>>,

    pub players: HashMap<PlayerId, Player>,
    pub lightcycles: HashMap<PlayerId, Lightcycle>,
    pub trails: HashMap<PlayerId, Trail>,

    #[serde(skip)]
    pub updates: Vec<ArenaUpdate>,
    #[serde(skip)]
    updates_applied_so_far: usize,
}

impl Arena {
    pub fn with_name(name: &str) -> Self {
        Self {
            name: name.to_uppercase().to_owned(),
            ..Default::default()
        }
    }

    pub fn add_player(&mut self, player: Player) {
        self.updates.push(ArenaUpdate::AddPlayer(player.id, player));
    }

    pub fn remove_player(&mut self, player_id: PlayerId) {
        self.updates.push(ArenaUpdate::RemovePlayer(player_id));
    }

    pub fn clear_updates(&mut self) {
        self.updates.clear();
        self.updates_applied_so_far = 0;
    }

    pub fn apply_updates(&mut self) -> &mut Self {
        let updates = mem::replace(&mut self.updates, Vec::new());
        for update in updates.iter().skip(self.updates_applied_so_far) {
            update.apply(self);
            self.updates_applied_so_far += 1;
        }
        mem::replace(&mut self.updates, updates);

        self
    }

    pub fn process_input(&mut self, player_id: PlayerId, input_event: ArenaInput) {
        input_event
            .process_into_updates(self, player_id)
            .drain(..)
            .for_each(|update| self.updates.push(update));
    }

    pub fn update(&mut self) {
        // apply process_input updates
        self.apply_updates();

        let started = match self.started {
            Some(started) => started,
            None => return,
        };

        let now = Utc::now();
        if now < started {
            return;
        }

        self.update_lightcycle_positions()
            .apply_updates()
            .calculate_lightcycle_collisions()
            .apply_updates()
            .update_trail_positions()
            .apply_updates()
            .test_round_end()
            .apply_updates();
    }

    //
    // update helpers
    //

    fn update_lightcycle_positions(&mut self) -> &mut Self {
        for (id, lightcycle) in self.lightcycles.iter() {
            if lightcycle.dead {
                continue;
            };

            self.updates.push(ArenaUpdate::UpdateLightcyclePosition(
                *id,
                lightcycle.position + lightcycle.direction.as_velocity() * lightcycle.speed,
            ))
        }
        self
    }

    fn calculate_lightcycle_collisions(&mut self) -> &mut Self {
        'next_lightcycle: for (id, lightcycle) in self.lightcycles.iter() {
            if lightcycle.dead {
                continue 'next_lightcycle;
            };

            // test for trail collisions
            for trail in self.trails.values() {
                for line in trail.points.windows(2) {
                    let start = line[0];
                    let end = line[1];

                    if is_point_on_line_2d(lightcycle.position, Line(start, end)) {
                        self.updates
                            .push(ArenaUpdate::UpdateLightcycleApplyDeath(*id));
                        continue 'next_lightcycle;
                    }
                }
            }

            // test for arena bounds collisions
            if lightcycle.position.x < 0
                || lightcycle.position.y < 0
                || lightcycle.position.x > self.width as isize
                || lightcycle.position.y > self.height as isize
            {
                self.updates
                    .push(ArenaUpdate::UpdateLightcycleApplyDeath(*id));
                continue 'next_lightcycle;
            }

            // test for collisions with other lightcycles
            if self
                .lightcycles
                .iter()
                .filter(|(_, other_lightcycle)| !other_lightcycle.dead)
                .filter(|(other_id, _)| id != *other_id)
                .any(|(_, other_lightcycle)| lightcycle.position == other_lightcycle.position)
            {
                self.updates
                    .push(ArenaUpdate::UpdateLightcycleApplyDeath(*id));
                continue 'next_lightcycle;
            }
        }
        self
    }

    fn update_trail_positions(&mut self) -> &mut Self {
        for id in self.trails.keys() {
            let latest_point = match self.lightcycles.get(id) {
                Some(lightcycle) => {
                    if lightcycle.dead {
                        continue;
                    };

                    lightcycle.position
                }
                None => {
                    error!(
                        "Failed to update trail position: No lightcycle with id {}",
                        id
                    );
                    continue;
                }
            };

            self.updates
                .push(ArenaUpdate::UpdateTrailReplaceLatestPoint(
                    *id,
                    latest_point,
                ));
        }
        self
    }

    fn test_round_end(&mut self) -> &mut Self {
        if self.lightcycles.values().all(|lightcycle| lightcycle.dead) {
            self.updates.push(ArenaUpdate::End);
        }
        self
    }
}

impl Default for Arena {
    fn default() -> Self {
        Self {
            id: ArenaId::new_v4(),
            name: Default::default(),
            width: ARENA_WIDTH,
            height: ARENA_HEIGHT,
            max_players: ARENA_MAX_PLAYERS,

            started: None,

            players: Default::default(),
            lightcycles: Default::default(),
            trails: Default::default(),

            updates: Default::default(),
            updates_applied_so_far: 0,
        }
    }
}

/// ArenaOverview represents an overview of an Arena for the arena selection screen.
#[derive(Debug, Clone, Serialize)]
pub struct ArenaOverview {
    id: ArenaId,
    name: String,
    max_players: usize,
    started: Option<DateTime<Utc>>,
    players: HashMap<PlayerId, Player>,
}

impl From<&Arena> for ArenaOverview {
    fn from(arena: &Arena) -> Self {
        Self {
            id: arena.id,
            name: arena.name.clone(),
            max_players: arena.max_players,
            started: arena.started,
            players: arena.players.clone(),
        }
    }
}
<commit_msg>fixed arena width and height on server<commit_after>mod entities;
mod input;
mod updates;
mod util;

use chrono::{DateTime, Duration as OldDuration, Utc};
use log::{error, trace};
use rand_core::{OsRng, RngCore};
use serde_derive::Serialize;
use std::collections::HashMap;
use std::mem;

pub use self::entities::*;
pub use self::input::*;
pub use self::updates::*;
pub use self::util::*;

use crate::server::{ArenaId, ArenaPoint, Direction, Line, Player, PlayerId};

const ARENA_WIDTH: usize = 560;
const ARENA_HEIGHT: usize = 560;
const ARENA_MAX_PLAYERS: usize = 8;
const ARENA_START_TIMER_SECONDS: i64 = 5;
const LIGHTCYCLE_SPEED: isize = 1;

#[derive(Debug, Clone, Serialize)]
pub struct Arena {
    pub id: ArenaId,
    pub name: String,
    pub width: usize,
    pub height: usize,
    pub max_players: usize,

    pub started: Option<DateTime<Utc>>,

    pub players: HashMap<PlayerId, Player>,
    pub lightcycles: HashMap<PlayerId, Lightcycle>,
    pub trails: HashMap<PlayerId, Trail>,

    #[serde(skip)]
    pub updates: Vec<ArenaUpdate>,
    #[serde(skip)]
    updates_applied_so_far: usize,
}

impl Arena {
    pub fn with_name(name: &str) -> Self {
        Self {
            name: name.to_uppercase().to_owned(),
            ..Default::default()
        }
    }

    pub fn add_player(&mut self, player: Player) {
        self.updates.push(ArenaUpdate::AddPlayer(player.id, player));
    }

    pub fn remove_player(&mut self, player_id: PlayerId) {
        self.updates.push(ArenaUpdate::RemovePlayer(player_id));
    }

    pub fn clear_updates(&mut self) {
        self.updates.clear();
        self.updates_applied_so_far = 0;
    }

    pub fn apply_updates(&mut self) -> &mut Self {
        let updates = mem::replace(&mut self.updates, Vec::new());
        for update in updates.iter().skip(self.updates_applied_so_far) {
            update.apply(self);
            self.updates_applied_so_far += 1;
        }
        mem::replace(&mut self.updates, updates);

        self
    }

    pub fn process_input(&mut self, player_id: PlayerId, input_event: ArenaInput) {
        input_event
            .process_into_updates(self, player_id)
            .drain(..)
            .for_each(|update| self.updates.push(update));
    }

    pub fn update(&mut self) {
        // apply process_input updates
        self.apply_updates();

        let started = match self.started {
            Some(started) => started,
            None => return,
        };

        let now = Utc::now();
        if now < started {
            return;
        }

        self.update_lightcycle_positions()
            .apply_updates()
            .calculate_lightcycle_collisions()
            .apply_updates()
            .update_trail_positions()
            .apply_updates()
            .test_round_end()
            .apply_updates();
    }

    //
    // update helpers
    //

    fn update_lightcycle_positions(&mut self) -> &mut Self {
        for (id, lightcycle) in self.lightcycles.iter() {
            if lightcycle.dead {
                continue;
            };

            self.updates.push(ArenaUpdate::UpdateLightcyclePosition(
                *id,
                lightcycle.position + lightcycle.direction.as_velocity() * lightcycle.speed,
            ))
        }
        self
    }

    fn calculate_lightcycle_collisions(&mut self) -> &mut Self {
        'next_lightcycle: for (id, lightcycle) in self.lightcycles.iter() {
            if lightcycle.dead {
                continue 'next_lightcycle;
            };

            // test for trail collisions
            for trail in self.trails.values() {
                for line in trail.points.windows(2) {
                    let start = line[0];
                    let end = line[1];

                    if is_point_on_line_2d(lightcycle.position, Line(start, end)) {
                        self.updates
                            .push(ArenaUpdate::UpdateLightcycleApplyDeath(*id));
                        continue 'next_lightcycle;
                    }
                }
            }

            // test for arena bounds collisions
            if lightcycle.position.x < 0
                || lightcycle.position.y < 0
                || lightcycle.position.x > self.width as isize
                || lightcycle.position.y > self.height as isize
            {
                self.updates
                    .push(ArenaUpdate::UpdateLightcycleApplyDeath(*id));
                continue 'next_lightcycle;
            }

            // test for collisions with other lightcycles
            if self
                .lightcycles
                .iter()
                .filter(|(_, other_lightcycle)| !other_lightcycle.dead)
                .filter(|(other_id, _)| id != *other_id)
                .any(|(_, other_lightcycle)| lightcycle.position == other_lightcycle.position)
            {
                self.updates
                    .push(ArenaUpdate::UpdateLightcycleApplyDeath(*id));
                continue 'next_lightcycle;
            }
        }
        self
    }

    fn update_trail_positions(&mut self) -> &mut Self {
        for id in self.trails.keys() {
            let latest_point = match self.lightcycles.get(id) {
                Some(lightcycle) => {
                    if lightcycle.dead {
                        continue;
                    };

                    lightcycle.position
                }
                None => {
                    error!(
                        "Failed to update trail position: No lightcycle with id {}",
                        id
                    );
                    continue;
                }
            };

            self.updates
                .push(ArenaUpdate::UpdateTrailReplaceLatestPoint(
                    *id,
                    latest_point,
                ));
        }
        self
    }

    fn test_round_end(&mut self) -> &mut Self {
        if self.lightcycles.values().all(|lightcycle| lightcycle.dead) {
            self.updates.push(ArenaUpdate::End);
        }
        self
    }
}

impl Default for Arena {
    fn default() -> Self {
        Self {
            id: ArenaId::new_v4(),
            name: Default::default(),
            width: ARENA_WIDTH,
            height: ARENA_HEIGHT,
            max_players: ARENA_MAX_PLAYERS,

            started: None,

            players: Default::default(),
            lightcycles: Default::default(),
            trails: Default::default(),

            updates: Default::default(),
            updates_applied_so_far: 0,
        }
    }
}

/// ArenaOverview represents an overview of an Arena for the arena selection screen.
#[derive(Debug, Clone, Serialize)]
pub struct ArenaOverview {
    id: ArenaId,
    name: String,
    max_players: usize,
    started: Option<DateTime<Utc>>,
    players: HashMap<PlayerId, Player>,
}

impl From<&Arena> for ArenaOverview {
    fn from(arena: &Arena) -> Self {
        Self {
            id: arena.id,
            name: arena.name.clone(),
            max_players: arena.max_players,
            started: arena.started,
            players: arena.players.clone(),
        }
    }
}
<|endoftext|>


<commit_before>use std::{
    hash::Hash,
    iter::{from_fn, FromIterator},
};

use indexmap::IndexSet;

use crate::{
    visit::{IntoNeighborsDirected, NodeCount},
    Direction::Outgoing,
};

/// Returns iterator that produces all simple paths from `from` node to `to`, which contains at least `min_intermediate_nodes` nodes
/// and at most `max_intermediate_nodes`, if given, limited by graph's order otherwise
/// Simple path is path without repetitions
/// Algorithm is adopted from https://networkx.github.io/documentation/stable/reference/algorithms/generated/networkx.algorithms.simple_paths.all_simple_paths.html
pub fn all_simple_paths<TargetColl, G>(
    graph: G,
    from: G::NodeId,
    to: G::NodeId,
    min_intermediate_nodes: usize,
    max_intermediate_nodes: Option<usize>,
) -> impl Iterator<Item = TargetColl>
where
    G: NodeCount,
    G: IntoNeighborsDirected,
    G::NodeId: Eq + Hash,
    TargetColl: FromIterator<G::NodeId>,
{
    // how many nodes are allowed in simple path up to target node
    // it is min/max allowed path length minus one, because it is more appropriate when implementing lookahead
    // than constantly add 1 to length of current path
    let max_length = if let Some(l) = max_intermediate_nodes {
        l + 1
    } else {
        graph.node_count() - 1
    };

    let min_length = min_intermediate_nodes + 1;

    // list of visited nodes
    let mut visited: IndexSet<G::NodeId> = IndexSet::from_iter(Some(from));
    // list of childs of currently exploring path nodes,
    // last elem is list of childs of last visited node
    let mut stack = vec![graph.neighbors_directed(from, Outgoing)];

    from_fn(move || {
        while let Some(children) = stack.last_mut() {
            if let Some(child) = children.next() {
                if visited.len() < max_length {
                    if child == to {
                        if visited.len() >= min_length {
                            let path = visited
                                .iter()
                                .cloned()
                                .chain(Some(to))
                                .collect::<TargetColl>();
                            return Some(path);
                        }
                    } else if !visited.contains(&child) {
                        visited.insert(child);
                        stack.push(graph.neighbors_directed(child, Outgoing));
                    }
                } else {
                    if (child == to || children.any(|v| v == to)) && visited.len() >= min_length {
                        let path = visited
                            .iter()
                            .cloned()
                            .chain(Some(to))
                            .collect::<TargetColl>();
                        return Some(path);
                    }
                    stack.pop();
                    visited.pop();
                }
            } else {
                stack.pop();
                visited.pop();
            }
        }
        None
    })
}

#[cfg(test)]
mod test {
    use std::{collections::HashSet, iter::FromIterator};

    use itertools::assert_equal;

    use crate::{dot::Dot, prelude::DiGraph};

    use super::all_simple_paths;

    #[test]
    fn test_all_simple_paths() {
        let graph = DiGraph::<i32, i32, _>::from_edges(&[
            (0, 1),
            (0, 2),
            (0, 3),
            (1, 2),
            (1, 3),
            (2, 3),
            (2, 4),
            (3, 2),
            (3, 4),
            (4, 2),
            (4, 5),
            (5, 2),
            (5, 3),
        ]);

        let expexted_simple_paths_0_to_5 = vec![
            vec![0usize, 1, 2, 3, 4, 5],
            vec![0, 1, 2, 4, 5],
            vec![0, 1, 3, 2, 4, 5],
            vec![0, 1, 3, 4, 5],
            vec![0, 2, 3, 4, 5],
            vec![0, 2, 4, 5],
            vec![0, 3, 2, 4, 5],
            vec![0, 3, 4, 5],
        ];

        println!("{}", Dot::new(&graph));
        let actual_simple_paths_0_to_5: HashSet<Vec<_>> =
            all_simple_paths(&graph, 0u32.into(), 5u32.into(), 0, None)
                .map(|v: Vec<_>| v.into_iter().map(|i| i.index()).collect())
                .collect();
        assert_eq!(actual_simple_paths_0_to_5.len(), 8);
        assert_eq!(
            HashSet::from_iter(expexted_simple_paths_0_to_5),
            actual_simple_paths_0_to_5
        );
    }

    #[test]
    fn test_one_simple_path() {
        let graph = DiGraph::<i32, i32, _>::from_edges(&[(0, 1), (2, 1)]);

        let expexted_simple_paths_0_to_1 = &[vec![0usize, 1]];
        println!("{}", Dot::new(&graph));
        let actual_simple_paths_0_to_1: Vec<Vec<_>> =
            all_simple_paths(&graph, 0u32.into(), 1u32.into(), 0, None)
                .map(|v: Vec<_>| v.into_iter().map(|i| i.index()).collect())
                .collect();

        assert_eq!(actual_simple_paths_0_to_1.len(), 1);
        assert_equal(expexted_simple_paths_0_to_1, &actual_simple_paths_0_to_1);
    }

    #[test]
    fn test_no_simple_paths() {
        let graph = DiGraph::<i32, i32, _>::from_edges(&[(0, 1), (2, 1)]);

        println!("{}", Dot::new(&graph));
        let actual_simple_paths_0_to_2: Vec<Vec<_>> =
            all_simple_paths(&graph, 0u32.into(), 2u32.into(), 0, None)
                .map(|v: Vec<_>| v.into_iter().map(|i| i.index()).collect())
                .collect();

        assert_eq!(actual_simple_paths_0_to_2.len(), 0);
    }
}
<commit_msg>Added an example on how to use the all_simple_paths function<commit_after>use std::{
    hash::Hash,
    iter::{from_fn, FromIterator},
};

use indexmap::IndexSet;

use crate::{
    visit::{IntoNeighborsDirected, NodeCount},
    Direction::Outgoing,
};

/// Returns iterator that produces all simple paths from `from` node to `to`, which contains at least `min_intermediate_nodes` nodes
/// and at most `max_intermediate_nodes`, if given, limited by graph's order otherwise
/// Simple path is path without repetitions
/// Algorithm is adopted from https://networkx.github.io/documentation/stable/reference/algorithms/generated/networkx.algorithms.simple_paths.all_simple_paths.html
///
/// # Example
/// ```
/// use petgraph::{algo, prelude::*};
///
/// let mut graph = DiGraph::<&str, i32>::new();
///
/// let a = graph.add_node("a");
/// let b = graph.add_node("b");
/// let c = graph.add_node("c");
/// let d = graph.add_node("d");
///
/// graph.extend_with_edges(&[(a, b, 1), (b, c, 1), (c, d, 1), (a, b, 1), (b, d, 1)]);
///
/// let ways = algo::all_simple_paths::<Vec<_>, _>(&graph, a, d, 0, None)
///   .collect::<Vec<_>>();
///
/// assert_eq!(4, ways.len());
/// ```
pub fn all_simple_paths<TargetColl, G>(
    graph: G,
    from: G::NodeId,
    to: G::NodeId,
    min_intermediate_nodes: usize,
    max_intermediate_nodes: Option<usize>,
) -> impl Iterator<Item = TargetColl>
where
    G: NodeCount,
    G: IntoNeighborsDirected,
    G::NodeId: Eq + Hash,
    TargetColl: FromIterator<G::NodeId>,
{
    // how many nodes are allowed in simple path up to target node
    // it is min/max allowed path length minus one, because it is more appropriate when implementing lookahead
    // than constantly add 1 to length of current path
    let max_length = if let Some(l) = max_intermediate_nodes {
        l + 1
    } else {
        graph.node_count() - 1
    };

    let min_length = min_intermediate_nodes + 1;

    // list of visited nodes
    let mut visited: IndexSet<G::NodeId> = IndexSet::from_iter(Some(from));
    // list of childs of currently exploring path nodes,
    // last elem is list of childs of last visited node
    let mut stack = vec![graph.neighbors_directed(from, Outgoing)];

    from_fn(move || {
        while let Some(children) = stack.last_mut() {
            if let Some(child) = children.next() {
                if visited.len() < max_length {
                    if child == to {
                        if visited.len() >= min_length {
                            let path = visited
                                .iter()
                                .cloned()
                                .chain(Some(to))
                                .collect::<TargetColl>();
                            return Some(path);
                        }
                    } else if !visited.contains(&child) {
                        visited.insert(child);
                        stack.push(graph.neighbors_directed(child, Outgoing));
                    }
                } else {
                    if (child == to || children.any(|v| v == to)) && visited.len() >= min_length {
                        let path = visited
                            .iter()
                            .cloned()
                            .chain(Some(to))
                            .collect::<TargetColl>();
                        return Some(path);
                    }
                    stack.pop();
                    visited.pop();
                }
            } else {
                stack.pop();
                visited.pop();
            }
        }
        None
    })
}

#[cfg(test)]
mod test {
    use std::{collections::HashSet, iter::FromIterator};

    use itertools::assert_equal;

    use crate::{dot::Dot, prelude::DiGraph};

    use super::all_simple_paths;

    #[test]
    fn test_all_simple_paths() {
        let graph = DiGraph::<i32, i32, _>::from_edges(&[
            (0, 1),
            (0, 2),
            (0, 3),
            (1, 2),
            (1, 3),
            (2, 3),
            (2, 4),
            (3, 2),
            (3, 4),
            (4, 2),
            (4, 5),
            (5, 2),
            (5, 3),
        ]);

        let expexted_simple_paths_0_to_5 = vec![
            vec![0usize, 1, 2, 3, 4, 5],
            vec![0, 1, 2, 4, 5],
            vec![0, 1, 3, 2, 4, 5],
            vec![0, 1, 3, 4, 5],
            vec![0, 2, 3, 4, 5],
            vec![0, 2, 4, 5],
            vec![0, 3, 2, 4, 5],
            vec![0, 3, 4, 5],
        ];

        println!("{}", Dot::new(&graph));
        let actual_simple_paths_0_to_5: HashSet<Vec<_>> =
            all_simple_paths(&graph, 0u32.into(), 5u32.into(), 0, None)
                .map(|v: Vec<_>| v.into_iter().map(|i| i.index()).collect())
                .collect();
        assert_eq!(actual_simple_paths_0_to_5.len(), 8);
        assert_eq!(
            HashSet::from_iter(expexted_simple_paths_0_to_5),
            actual_simple_paths_0_to_5
        );
    }

    #[test]
    fn test_one_simple_path() {
        let graph = DiGraph::<i32, i32, _>::from_edges(&[(0, 1), (2, 1)]);

        let expexted_simple_paths_0_to_1 = &[vec![0usize, 1]];
        println!("{}", Dot::new(&graph));
        let actual_simple_paths_0_to_1: Vec<Vec<_>> =
            all_simple_paths(&graph, 0u32.into(), 1u32.into(), 0, None)
                .map(|v: Vec<_>| v.into_iter().map(|i| i.index()).collect())
                .collect();

        assert_eq!(actual_simple_paths_0_to_1.len(), 1);
        assert_equal(expexted_simple_paths_0_to_1, &actual_simple_paths_0_to_1);
    }

    #[test]
    fn test_no_simple_paths() {
        let graph = DiGraph::<i32, i32, _>::from_edges(&[(0, 1), (2, 1)]);

        println!("{}", Dot::new(&graph));
        let actual_simple_paths_0_to_2: Vec<Vec<_>> =
            all_simple_paths(&graph, 0u32.into(), 2u32.into(), 0, None)
                .map(|v: Vec<_>| v.into_iter().map(|i| i.index()).collect())
                .collect();

        assert_eq!(actual_simple_paths_0_to_2.len(), 0);
    }
}
<|endoftext|>


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

use client::Client;
use mqtt3::{TopicPath, SubscribeTopic};
use error::Result;

pub struct SubscriptionList {
    concrete: HashMap<SubscribeTopic, Vec<Client>>,
    wild: HashMap<SubscribeTopic, Vec<Client>>,
}

impl SubscriptionList {
    pub fn new() -> Self {
        SubscriptionList {
            concrete: HashMap::new(),
            wild: HashMap::new(),
        }
    }

    pub fn add_subscription(&mut self, topic: SubscribeTopic, client: Client) -> Result<()> {
        let topic_path = TopicPath::from_str(topic.topic_path.clone())?;

        if topic_path.wildcards {
            let clients = self.wild.entry(topic).or_insert(Vec::new());
            // add client to a subscription only if it doesn't already exist or
            // else replace the existing one
            if let Some(index) = clients.iter().position(|v| v.id == client.id) {
                clients.insert(index, client);
            } else {
                clients.push(client);
            }
        } else {
            let clients = self.concrete.entry(topic).or_insert(Vec::new());
            // add client to a subscription only if it doesn't already exist or
            // else replace the existing one
            if let Some(index) = clients.iter().position(|v| v.id == client.id) {
                clients.insert(index, client);
            } else {
                clients.push(client);
            }
        }

        Ok(())
    }

    /// Remove a client from a subscription
    pub fn remove_subscription_client(&mut self, topic: SubscribeTopic, id: &str) -> Result<()> {
        let topic_path = TopicPath::from_str(topic.topic_path.clone())?;

        if topic_path.wildcards {
            if let Some(clients) = self.wild.get_mut(&topic) {
                if let Some(index) = clients.iter().position(|v| v.id == id) {
                    clients.remove(index);
                }
            }
        } else {
            if let Some(clients) = self.concrete.get_mut(&topic) {
                if let Some(index) = clients.iter().position(|v| v.id == id) {
                    clients.remove(index);
                }
            }
        }
        Ok(())
    }

    fn match_with_wild_topic(concrete: String, wild: String) -> bool {
        true
    }

    /// Get the list of clients for a given subscription
    pub fn get_subscribed_clients(&mut self, topic: SubscribeTopic) -> Result<Vec<Client>> {
        let topic_path = TopicPath::from_str(topic.topic_path.clone())?;

        let clients = if topic_path.wildcards {
            if let Some(v) = self.wild.get(&topic) {
                v.clone()
            } else {
                vec![]
            }
        } else {
            if let Some(v) = self.concrete.get(&topic) {
                v.clone()
            } else {
                vec![]
            }
        };

        Ok(clients)
    }
}<commit_msg>add method to get all subscribed clients (wildcard & concrete)<commit_after>use std::collections::HashMap;

use client::Client;
use mqtt3::{TopicPath, SubscribeTopic, ToTopicPath};
use error::Result;

// NOTE: split subscription list into concrete & and wild card subscriptions
// all concrete subscription clients could be fetched in O(1)~
pub struct SubscriptionList {
    concrete: HashMap<SubscribeTopic, Vec<Client>>,
    wild: HashMap<SubscribeTopic, Vec<Client>>,
}

impl SubscriptionList {
    pub fn new() -> Self {
        SubscriptionList {
            concrete: HashMap::new(),
            wild: HashMap::new(),
        }
    }

    pub fn add_subscription(&mut self, topic: SubscribeTopic, client: Client) -> Result<()> {
        let topic_path = TopicPath::from_str(topic.topic_path.clone())?;

        if topic_path.wildcards {
            let clients = self.wild.entry(topic).or_insert(Vec::new());
            // add client to a subscription only if it doesn't already exist or
            // else replace the existing one
            if let Some(index) = clients.iter().position(|v| v.id == client.id) {
                clients.insert(index, client);
            } else {
                clients.push(client);
            }
        } else {
            let clients = self.concrete.entry(topic).or_insert(Vec::new());
            // add client to a subscription only if it doesn't already exist or
            // else replace the existing one
            if let Some(index) = clients.iter().position(|v| v.id == client.id) {
                clients.insert(index, client);
            } else {
                clients.push(client);
            }
        }

        Ok(())
    }

    /// Remove a client from a subscription
    pub fn remove_subscription_client(&mut self, topic: SubscribeTopic, id: &str) -> Result<()> {
        let topic_path = TopicPath::from_str(topic.topic_path.clone())?;

        if topic_path.wildcards {
            if let Some(clients) = self.wild.get_mut(&topic) {
                if let Some(index) = clients.iter().position(|v| v.id == id) {
                    clients.remove(index);
                }
            }
        } else {
            if let Some(clients) = self.concrete.get_mut(&topic) {
                if let Some(index) = clients.iter().position(|v| v.id == id) {
                    clients.remove(index);
                }
            }
        }
        Ok(())
    }

    /// Get the list of subscribed clients for a given concrete subscription topic
    pub fn get_subscribed_clients(&mut self, topic: SubscribeTopic) -> Result<Vec<Client>> {
        let topic_path = TopicPath::from_str(topic.topic_path.clone())?;
        // subscription topic should only have concrete topic path
        let _ = topic_path.to_topic_name()?;

        let mut all_clients = vec![];

        // O(1) matches from concrete hashmap
        if let Some(clients) = self.concrete.get(&topic) {
            all_clients.extend(clients.clone());
        }

        for (subscription, clients) in self.wild.iter() {
            let wild_subscription_topic = TopicPath::from_str(subscription.topic_path.clone())?;
            if wild_subscription_topic.is_match(&topic_path) {
                all_clients.extend(clients.clone());
            }
        }

        Ok(all_clients)
    }
}

#[cfg(test)]
mod test {
    use super::SubscriptionList;

}<|endoftext|>


<commit_before>use io::MapNonBlock;
use std::cell::Cell;
use std::io::{Read, Write};
use std::net::{self, SocketAddr};
use std::os::unix::io::{RawFd, FromRawFd, IntoRawFd, AsRawFd};

use libc;
use net2::{TcpStreamExt, TcpListenerExt};
use nix::fcntl::FcntlArg::F_SETFL;
use nix::fcntl::{fcntl, O_NONBLOCK};

use {io, poll, Evented, EventSet, Poll, PollOpt, Token, TryAccept};
use sys::unix::eventedfd::EventedFd;

#[derive(Debug)]
pub struct TcpStream {
    inner: net::TcpStream,
    selector_id: Cell<Option<usize>>,
}

#[derive(Debug)]
pub struct TcpListener {
    inner: net::TcpListener,
    selector_id: Cell<Option<usize>>,
}

fn set_nonblock(s: &AsRawFd) -> io::Result<()> {
    fcntl(s.as_raw_fd(), F_SETFL(O_NONBLOCK)).map_err(super::from_nix_error)
                                             .map(|_| ())
}

impl TcpStream {
    pub fn connect(stream: net::TcpStream, addr: &SocketAddr) -> io::Result<TcpStream> {
        try!(set_nonblock(&stream));

        match stream.connect(addr) {
            Ok(..) => {}
            Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {}
            Err(e) => return Err(e),
        }

        Ok(TcpStream {
            inner: stream,
            selector_id: Cell::new(None),
        })
    }

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

    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        self.inner.local_addr()
    }

    pub fn try_clone(&self) -> io::Result<TcpStream> {
        self.inner.try_clone().map(|s| {
            TcpStream {
                inner: s,
                selector_id: self.selector_id.clone(),
            }
        })
    }

    pub fn shutdown(&self, how: net::Shutdown) -> io::Result<()> {
        self.inner.shutdown(how)
    }

    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
        TcpStreamExt::set_nodelay(&self.inner, nodelay)
    }

    pub fn set_keepalive(&self, seconds: Option<u32>) -> io::Result<()> {
        self.inner.set_keepalive_ms(seconds.map(|s| s * 1000))
    }

    pub fn take_socket_error(&self) -> io::Result<()> {
        self.inner.take_error().and_then(|e| {
            match e {
                Some(e) => Err(e),
                None => Ok(())
            }
        })
    }

    fn associate_selector(&self, poll: &Poll) -> io::Result<()> {
        let selector_id = self.selector_id.get();

        if selector_id.is_some() && selector_id != Some(poll::selector(poll).id()) {
            Err(io::Error::new(io::ErrorKind::Other, "socket already registered"))
        } else {
            self.selector_id.set(Some(poll::selector(poll).id()));
            Ok(())
        }
    }
}

impl Read for TcpStream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl Write for TcpStream {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.inner.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.inner.flush()
    }
}

impl Evented for TcpStream {
    fn register(&self, poll: &mut Poll, token: Token,
                interest: EventSet, opts: PollOpt) -> io::Result<()> {
        try!(self.associate_selector(poll));
        EventedFd(&self.as_raw_fd()).register(poll, token, interest, opts)
    }

    fn reregister(&self, poll: &mut Poll, token: Token,
                  interest: EventSet, opts: PollOpt) -> io::Result<()> {
        EventedFd(&self.as_raw_fd()).reregister(poll, token, interest, opts)
    }

    fn deregister(&self, poll: &mut Poll) -> io::Result<()> {
        EventedFd(&self.as_raw_fd()).deregister(poll)
    }
}

impl FromRawFd for TcpStream {
    unsafe fn from_raw_fd(fd: RawFd) -> TcpStream {
        TcpStream {
            inner: net::TcpStream::from_raw_fd(fd),
            selector_id: Cell::new(None),
        }
    }
}

impl IntoRawFd for TcpStream {
    fn into_raw_fd(self) -> RawFd {
        self.inner.into_raw_fd()
    }
}

impl AsRawFd for TcpStream {
    fn as_raw_fd(&self) -> RawFd {
        self.inner.as_raw_fd()
    }
}

impl TcpListener {
    pub fn new(inner: net::TcpListener, _addr: &SocketAddr) -> io::Result<TcpListener> {
        try!(set_nonblock(&inner));
        Ok(TcpListener {
            inner: inner,
            selector_id: Cell::new(None),
        })
    }

    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        self.inner.local_addr()
    }

    pub fn try_clone(&self) -> io::Result<TcpListener> {
        self.inner.try_clone().map(|s| {
            TcpListener {
                inner: s,
                selector_id: self.selector_id.clone(),
            }
        })
    }

    pub fn accept(&self) -> io::Result<Option<(TcpStream, SocketAddr)>> {
        self.inner.accept().and_then(|(s, a)| {
            try!(set_nonblock(&s));
            Ok((TcpStream {
                inner: s,
                selector_id: Cell::new(None),
            }, a))
        }).map_non_block()
    }

    pub fn take_socket_error(&self) -> io::Result<()> {
        self.inner.take_error().and_then(|e| {
            match e {
                Some(e) => Err(e),
                None => Ok(())
            }
        })
    }

    fn associate_selector(&self, poll: &Poll) -> io::Result<()> {
        let selector_id = self.selector_id.get();

        if selector_id.is_some() && selector_id != Some(poll::selector(poll).id()) {
            Err(io::Error::new(io::ErrorKind::Other, "socket already registered"))
        } else {
            self.selector_id.set(Some(poll::selector(poll).id()));
            Ok(())
        }
    }
}

impl Evented for TcpListener {
    fn register(&self, poll: &mut Poll, token: Token,
                interest: EventSet, opts: PollOpt) -> io::Result<()> {
        try!(self.associate_selector(poll));
        EventedFd(&self.as_raw_fd()).register(poll, token, interest, opts)
    }

    fn reregister(&self, poll: &mut Poll, token: Token,
                  interest: EventSet, opts: PollOpt) -> io::Result<()> {
        EventedFd(&self.as_raw_fd()).reregister(poll, token, interest, opts)
    }

    fn deregister(&self, poll: &mut Poll) -> io::Result<()> {
        EventedFd(&self.as_raw_fd()).deregister(poll)
    }
}

impl FromRawFd for TcpListener {
    unsafe fn from_raw_fd(fd: RawFd) -> TcpListener {
        TcpListener {
            inner: net::TcpListener::from_raw_fd(fd),
            selector_id: Cell::new(None),
        }
    }
}

impl IntoRawFd for TcpListener {
    fn into_raw_fd(self) -> RawFd {
        self.inner.into_raw_fd()
    }
}

impl AsRawFd for TcpListener {
    fn as_raw_fd(&self) -> RawFd {
        self.inner.as_raw_fd()
    }
}

<commit_msg>Fix compilation on nightly<commit_after>use io::MapNonBlock;
use std::cell::Cell;
use std::io::{Read, Write};
use std::net::{self, SocketAddr};
use std::os::unix::io::{RawFd, FromRawFd, IntoRawFd, AsRawFd};

use libc;
use net2::TcpStreamExt;

#[allow(unused_imports)]
use net2::TcpListenerExt;

use nix::fcntl::FcntlArg::F_SETFL;
use nix::fcntl::{fcntl, O_NONBLOCK};

use {io, poll, Evented, EventSet, Poll, PollOpt, Token};
use sys::unix::eventedfd::EventedFd;

#[derive(Debug)]
pub struct TcpStream {
    inner: net::TcpStream,
    selector_id: Cell<Option<usize>>,
}

#[derive(Debug)]
pub struct TcpListener {
    inner: net::TcpListener,
    selector_id: Cell<Option<usize>>,
}

fn set_nonblock(s: &AsRawFd) -> io::Result<()> {
    fcntl(s.as_raw_fd(), F_SETFL(O_NONBLOCK)).map_err(super::from_nix_error)
                                             .map(|_| ())
}

impl TcpStream {
    pub fn connect(stream: net::TcpStream, addr: &SocketAddr) -> io::Result<TcpStream> {
        try!(set_nonblock(&stream));

        match stream.connect(addr) {
            Ok(..) => {}
            Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {}
            Err(e) => return Err(e),
        }

        Ok(TcpStream {
            inner: stream,
            selector_id: Cell::new(None),
        })
    }

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

    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        self.inner.local_addr()
    }

    pub fn try_clone(&self) -> io::Result<TcpStream> {
        self.inner.try_clone().map(|s| {
            TcpStream {
                inner: s,
                selector_id: self.selector_id.clone(),
            }
        })
    }

    pub fn shutdown(&self, how: net::Shutdown) -> io::Result<()> {
        self.inner.shutdown(how)
    }

    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
        TcpStreamExt::set_nodelay(&self.inner, nodelay)
    }

    pub fn set_keepalive(&self, seconds: Option<u32>) -> io::Result<()> {
        self.inner.set_keepalive_ms(seconds.map(|s| s * 1000))
    }

    pub fn take_socket_error(&self) -> io::Result<()> {
        self.inner.take_error().and_then(|e| {
            match e {
                Some(e) => Err(e),
                None => Ok(())
            }
        })
    }

    fn associate_selector(&self, poll: &Poll) -> io::Result<()> {
        let selector_id = self.selector_id.get();

        if selector_id.is_some() && selector_id != Some(poll::selector(poll).id()) {
            Err(io::Error::new(io::ErrorKind::Other, "socket already registered"))
        } else {
            self.selector_id.set(Some(poll::selector(poll).id()));
            Ok(())
        }
    }
}

impl Read for TcpStream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl Write for TcpStream {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.inner.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.inner.flush()
    }
}

impl Evented for TcpStream {
    fn register(&self, poll: &mut Poll, token: Token,
                interest: EventSet, opts: PollOpt) -> io::Result<()> {
        try!(self.associate_selector(poll));
        EventedFd(&self.as_raw_fd()).register(poll, token, interest, opts)
    }

    fn reregister(&self, poll: &mut Poll, token: Token,
                  interest: EventSet, opts: PollOpt) -> io::Result<()> {
        EventedFd(&self.as_raw_fd()).reregister(poll, token, interest, opts)
    }

    fn deregister(&self, poll: &mut Poll) -> io::Result<()> {
        EventedFd(&self.as_raw_fd()).deregister(poll)
    }
}

impl FromRawFd for TcpStream {
    unsafe fn from_raw_fd(fd: RawFd) -> TcpStream {
        TcpStream {
            inner: net::TcpStream::from_raw_fd(fd),
            selector_id: Cell::new(None),
        }
    }
}

impl IntoRawFd for TcpStream {
    fn into_raw_fd(self) -> RawFd {
        self.inner.into_raw_fd()
    }
}

impl AsRawFd for TcpStream {
    fn as_raw_fd(&self) -> RawFd {
        self.inner.as_raw_fd()
    }
}

impl TcpListener {
    pub fn new(inner: net::TcpListener, _addr: &SocketAddr) -> io::Result<TcpListener> {
        try!(set_nonblock(&inner));
        Ok(TcpListener {
            inner: inner,
            selector_id: Cell::new(None),
        })
    }

    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        self.inner.local_addr()
    }

    pub fn try_clone(&self) -> io::Result<TcpListener> {
        self.inner.try_clone().map(|s| {
            TcpListener {
                inner: s,
                selector_id: self.selector_id.clone(),
            }
        })
    }

    pub fn accept(&self) -> io::Result<Option<(TcpStream, SocketAddr)>> {
        self.inner.accept().and_then(|(s, a)| {
            try!(set_nonblock(&s));
            Ok((TcpStream {
                inner: s,
                selector_id: Cell::new(None),
            }, a))
        }).map_non_block()
    }

    pub fn take_socket_error(&self) -> io::Result<()> {
        self.inner.take_error().and_then(|e| {
            match e {
                Some(e) => Err(e),
                None => Ok(())
            }
        })
    }

    fn associate_selector(&self, poll: &Poll) -> io::Result<()> {
        let selector_id = self.selector_id.get();

        if selector_id.is_some() && selector_id != Some(poll::selector(poll).id()) {
            Err(io::Error::new(io::ErrorKind::Other, "socket already registered"))
        } else {
            self.selector_id.set(Some(poll::selector(poll).id()));
            Ok(())
        }
    }
}

impl Evented for TcpListener {
    fn register(&self, poll: &mut Poll, token: Token,
                interest: EventSet, opts: PollOpt) -> io::Result<()> {
        try!(self.associate_selector(poll));
        EventedFd(&self.as_raw_fd()).register(poll, token, interest, opts)
    }

    fn reregister(&self, poll: &mut Poll, token: Token,
                  interest: EventSet, opts: PollOpt) -> io::Result<()> {
        EventedFd(&self.as_raw_fd()).reregister(poll, token, interest, opts)
    }

    fn deregister(&self, poll: &mut Poll) -> io::Result<()> {
        EventedFd(&self.as_raw_fd()).deregister(poll)
    }
}

impl FromRawFd for TcpListener {
    unsafe fn from_raw_fd(fd: RawFd) -> TcpListener {
        TcpListener {
            inner: net::TcpListener::from_raw_fd(fd),
            selector_id: Cell::new(None),
        }
    }
}

impl IntoRawFd for TcpListener {
    fn into_raw_fd(self) -> RawFd {
        self.inner.into_raw_fd()
    }
}

impl AsRawFd for TcpListener {
    fn as_raw_fd(&self) -> RawFd {
        self.inner.as_raw_fd()
    }
}

<|endoftext|>