simpletcp 1.2.1

Crate for simple and secure tcp communication
Documentation
#[cfg(unix)]
use std::os::unix::io::AsRawFd;

use std::convert::TryInto;
#[cfg(windows)]
use std::os::windows::io::AsRawSocket;

mod platform {
    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}

#[cfg(test)]
mod tests;

pub const EV_POLLIN: i16 = 1 << 0;
pub const EV_POLLOUT: i16 = 1 << 1;

/// Polls the socket
///
/// # Arguments
///
/// * `socket` - Socket to poll
/// * `event` - Event to poll ([EV_POLLIN](constant.EV_POLLIN.html) or [EV_POLLOUT](constant.EV_POLLOUT.html))
///
/// # Returns
/// `true` if polled event has occurred, `false` if not
#[cfg(unix)]
pub fn poll<A: AsRawFd>(socket: &A, event: i16) -> bool {
    poll_timeout(socket, event, -1)
}

/// Polls the socket with timeout
///
/// # Arguments
///
/// * `socket` - Socket to poll
/// * `event` - Event to poll ([EV_POLLIN](constant.EV_POLLIN.html) or [EV_POLLOUT](constant.EV_POLLOUT.html))
/// * `timeout` - Timeout in milliseconds
///
/// # Returns
/// `true` if polled event has occurred, `false` if not
#[cfg(unix)]
pub fn poll_timeout<A: AsRawFd>(socket: &A, event: i16, timeout: i32) -> bool {
    let mut fd = socket.as_raw_fd();
    let fd_ptr = &mut fd as *mut i32;
    unsafe {
        let translated_events = translate_event(event);
        return platform::c_poll(fd_ptr, 1, translated_events, timeout) == 0;
    }
}

/// Polls set of sockets
///
/// # Arguments
///
/// * `fds` - Set of socket descriptors generated by [get_fd_array](fn.get_fd_array.html)
/// * `event` - Event to poll ([EV_POLLIN](constant.EV_POLLIN.html) or [EV_POLLOUT](constant.EV_POLLOUT.html))
///
/// # Returns
/// Index of socket on which an event has occurred
#[cfg(unix)]
pub fn poll_set(fds: &mut [i32], event: i16) -> i32 {
    poll_set_timeout(fds, event, -1).unwrap()
}

/// Polls set of sockets with timeout
///
/// # Arguments
///
/// * `fds` - Set of socket descriptors generated by [get_fd_array](fn.get_fd_array.html)
/// * `event` - Event to poll ([EV_POLLIN](constant.EV_POLLIN.html) or [EV_POLLOUT](constant.EV_POLLOUT.html))
/// * `timeout` - Timeout in milliseconds
///
/// # Returns
/// Index of socket on which an event has occurred or `None` if poll timed out
#[cfg(unix)]
pub fn poll_set_timeout(fds: &mut [i32], event: i16, timeout: i32) -> Option<i32> {
    unsafe {
        let translated_events = translate_event(event);
        let res = platform::c_poll(
            fds.as_mut_ptr(),
            fds.len().try_into().unwrap(),
            translated_events,
            timeout,
        );
        if res == -1 {
            return None;
        }
        return Some(res);
    }
}

/// Polls set of sockets with set of events
///
/// # Arguments
///
/// * `fds` - Set of socket descriptors generated by [get_fd_array](fn.get_fd_array.html)
/// * `events` - Set of events to poll ([EV_POLLIN](constant.EV_POLLIN.html) or [EV_POLLOUT](constant.EV_POLLOUT.html)), `fds[x]` will be polled with `events[x]`
///
/// # Returns
/// Index of socket on which an event has occurred
#[cfg(unix)]
pub fn poll_set_ev(fds: &mut [i32], events: &mut [i16]) -> i32 {
    poll_set_ev_timeout(fds, events, -1).unwrap()
}

/// Polls set of sockets with set of events with timeout
///
/// # Arguments
///
/// * `fds` - Set of socket descriptors generated by [get_fd_array](fn.get_fd_array.html)
/// * `events` - Set of events to poll ([EV_POLLIN](constant.EV_POLLIN.html) or [EV_POLLOUT](constant.EV_POLLOUT.html)), `fds[x]` will be polled with `events[x]`
/// * `timeout` - Timeout in milliseconds
///
/// # Returns
/// Index of socket on which an event has occurred or `None` if poll timed out
#[cfg(unix)]
pub fn poll_set_ev_timeout(fds: &mut [i32], events: &mut [i16], timeout: i32) -> Option<i32> {
    unsafe {
        let mut translated = Vec::new();
        for e in events {
            translated.push(translate_event(*e));
        }
        let res = platform::c_poll_ev(
            fds.as_mut_ptr(),
            translated.as_mut_ptr(),
            fds.len().try_into().unwrap(),
            timeout,
        );
        if res == -1 {
            return None;
        }
        return Some(res);
    }
}

/// Creates array of raw socket descriptors
///
/// # Arguments
///
/// * `sockets` - Sockets
///
/// # Returns
/// `Vec` containing socket descriptors
#[cfg(unix)]
pub fn get_fd_array<A: AsRawFd>(sockets: &[A]) -> Vec<i32> {
    let mut res = Vec::new();
    for socket in sockets {
        res.push(socket.as_raw_fd());
    }

    res
}

/// Polls the socket
///
/// # Arguments
///
/// * `socket` - Socket to poll
/// * `event` - Event to poll ([EV_POLLIN](constant.EV_POLLIN.html) or [EV_POLLOUT](constant.EV_POLLOUT.html))
///
/// # Returns
/// `true` if polled event has occurred, `false` if not
#[cfg(windows)]
pub fn poll<A: AsRawSocket>(socket: &A, event: i16) -> bool {
    poll_timeout(socket, event, -1)
}

/// Polls the socket with timeout
///
/// # Arguments
///
/// * `socket` - Socket to poll
/// * `event` - Event to poll ([EV_POLLIN](constant.EV_POLLIN.html) or [EV_POLLOUT](constant.EV_POLLOUT.html))
/// * `timeout` - Timeout in milliseconds
///
/// # Returns
/// `true` if polled event has occurred, `false` if not
#[cfg(windows)]
pub fn poll_timeout<A: AsRawSocket>(socket: &A, event: i16, timeout: i32) -> bool {
    let mut fd = socket.as_raw_socket();
    let fd_ptr = &mut fd as *mut u64;
    unsafe {
        let translated_events = translate_event(event);
        return platform::c_poll(fd_ptr, 1, translated_events, timeout) == 0;
    }
}

/// Polls set of sockets with timeout
///
/// # Arguments
///
/// * `fds` - Set of socket descriptors generated by [get_fd_array](fn.get_fd_array.html)
/// * `event` - Event to poll ([EV_POLLIN](constant.EV_POLLIN.html) or [EV_POLLOUT](constant.EV_POLLOUT.html))
/// * `timeout` - Timeout in milliseconds
///
/// # Returns
/// Index of socket on which an event has occurred or `None` if poll timed out
#[cfg(windows)]
pub fn poll_set_timeout(fds: &mut [u64], event: i16, timeout: i32) -> Option<i32> {
    unsafe {
        let translated_events = translate_event(event);
        let res = platform::c_poll(
            fds.as_mut_ptr(),
            fds.len().try_into().unwrap(),
            translated_events,
            timeout,
        );
        if res == -1 {
            return None;
        }
        return Some(res);
    }
}

/// Polls set of sockets
///
/// # Arguments
///
/// * `fds` - Set of socket descriptors generated by [get_fd_array](fn.get_fd_array.html)
/// * `event` - Event to poll ([EV_POLLIN](constant.EV_POLLIN.html) or [EV_POLLOUT](constant.EV_POLLOUT.html))
///
/// # Returns
/// Index of socket on which an event has occurred
#[cfg(windows)]
pub fn poll_set(fds: &mut [u64], event: i16) -> i32 {
    poll_set_timeout(fds, event, -1).unwrap()
}

/// Polls set of sockets with set of events with timeout
///
/// # Arguments
///
/// * `fds` - Set of socket descriptors generated by [get_fd_array](fn.get_fd_array.html)
/// * `events` - Set of events to poll ([EV_POLLIN](constant.EV_POLLIN.html) or [EV_POLLOUT](constant.EV_POLLOUT.html)), `fds[x]` will be polled with `events[x]`
/// * `timeout` - Timeout in milliseconds
///
/// # Returns
/// Index of socket on which an event has occurred or `None` if poll timed out
#[cfg(windows)]
pub fn poll_set_ev_timeout(fds: &mut [u64], events: &mut [i16], timeout: i32) -> Option<i32> {
    unsafe {
        let mut translated = Vec::new();
        for e in events {
            translated.push(translate_event(*e));
        }
        let res = platform::c_poll_ev(
            fds.as_mut_ptr(),
            translated.as_mut_ptr(),
            fds.len().try_into().unwrap(),
            timeout,
        );
        if res == -1 {
            return None;
        }
        return Some(res);
    }
}

/// Polls set of sockets with set of events
///
/// # Arguments
///
/// * `fds` - Set of socket descriptors generated by [get_fd_array](fn.get_fd_array.html)
/// * `events` - Set of events to poll ([EV_POLLIN](constant.EV_POLLIN.html) or [EV_POLLOUT](constant.EV_POLLOUT.html)), `fds[x]` will be polled with `events[x]`
///
/// # Returns
/// Index of socket on which an event has occurred
#[cfg(windows)]
pub fn poll_set_ev(fds: &mut [u64], events: &mut [i16]) -> i32 {
    poll_set_ev_timeout(fds, events, -1).unwrap()
}

/// Creates array of raw socket descriptors
///
/// # Arguments
///
/// * `sockets` - Sockets
///
/// # Returns
/// `Vec` containing socket descriptors
#[cfg(windows)]
pub fn get_fd_array<A: AsRawSocket>(sockets: &[A]) -> Vec<u64> {
    let mut res = Vec::new();
    for socket in sockets {
        res.push(socket.as_raw_socket());
    }

    res
}

unsafe fn translate_event(ev: i16) -> i16 {
    let mut translated = 0;
    if (ev & EV_POLLIN) != 0 {
        translated |= platform::ev_pollin;
    }
    if (ev & EV_POLLOUT) != 0 {
        translated |= platform::ev_pollout;
    }
    translated
}