use std::{ptr, slice, mem};
use libc::size_t;
use std::vec::Vec;
use traits::Wrappable;
use network::{Packet, IpAddress, SocketStatus};
use sfml_types::sfBool;
use csfml_network_sys as ffi;
pub struct UdpSocket {
socket: *mut ffi::sfUdpSocket
}
impl UdpSocket {
pub fn new() -> Option<UdpSocket> {
let udp = unsafe { ffi::sfUdpSocket_create() };
if udp.is_null() {
None
}
else {
Some(UdpSocket {
socket: udp
})
}
}
pub fn set_blocking(&self, blocking: bool) {
unsafe {
ffi::sfUdpSocket_setBlocking(self.socket, sfBool::from_bool(blocking))
}
}
pub fn is_blocking(&self) -> bool {
unsafe { ffi::sfUdpSocket_isBlocking(self.socket) }.to_bool()
}
pub fn get_local_port(&self) -> u16 {
unsafe {
ffi::sfUdpSocket_getLocalPort(self.socket)
}
}
pub fn bind(&self, port: u16) -> SocketStatus {
unsafe {
mem::transmute(ffi::sfUdpSocket_bind(self.socket, port) as i32)
}
}
pub fn unbind(&self) {
unsafe {
ffi::sfUdpSocket_unbind(self.socket)
}
}
pub fn send(&self, data: &[i8], address: &IpAddress, port: u16) -> SocketStatus {
unsafe {
mem::transmute(ffi::sfUdpSocket_send(self.socket, data.as_ptr() as *mut i8, data.len() as size_t, address.unwrap(), port) as i32)
}
}
pub fn receive(&self, max_size: size_t) -> (Vec<i8>, SocketStatus, size_t, IpAddress, u16) {
unsafe {
let mut s: size_t = 0;
let datas: *mut i8 = ptr::null_mut();
let addr: *mut ffi::sfIpAddress = ptr::null_mut();
let mut port: u16 = 0;
let stat: SocketStatus = mem::transmute(ffi::sfUdpSocket_receive(self.socket, datas, max_size, &mut s, addr, &mut port) as i32);
(slice::from_raw_parts(datas, s as usize).to_vec(), stat, s, Wrappable::wrap(*addr), port)
}
}
pub fn send_packet(&self, packet: &Packet, address: &IpAddress, port: u16) -> SocketStatus {
unsafe {
mem::transmute(ffi::sfUdpSocket_sendPacket(self.socket, packet.unwrap(), address.unwrap(), port) as i32)
}
}
pub fn receive_packet(&self) -> (Packet, SocketStatus, IpAddress, u16) {
unsafe {
let pack: *mut ffi::sfPacket = ptr::null_mut();
let addr: *mut ffi::sfIpAddress = ptr::null_mut();
let mut port: u16 = 0;
let stat: SocketStatus = mem::transmute(ffi::sfUdpSocket_receivePacket(self.socket, pack, addr, &mut port) as i32);
(Wrappable::wrap(pack), stat, Wrappable::wrap(*addr), port)
}
}
pub fn max_datagram_size() -> u32 {
unsafe {
ffi::sfUdpSocket_maxDatagramSize()
}
}
}
impl Wrappable<*mut ffi::sfUdpSocket> for UdpSocket {
fn wrap(socket: *mut ffi::sfUdpSocket) -> UdpSocket {
UdpSocket {
socket: socket
}
}
fn unwrap(&self) -> *mut ffi::sfUdpSocket {
self.socket
}
}
impl Drop for UdpSocket {
fn drop(&mut self) {
unsafe {
ffi::sfUdpSocket_destroy(self.socket)
}
}
}