use libc::size_t;
use std::{slice, ptr, mem};
use std::vec::Vec;
use traits::Wrappable;
use network::{IpAddress, Packet, SocketStatus};
use system::Time;
use sfml_types::sfBool;
use csfml_network_sys as ffi;
pub struct TcpSocket {
socket: *mut ffi::sfTcpSocket
}
impl TcpSocket {
pub fn new() -> Option<TcpSocket> {
let tcp = unsafe { ffi::sfTcpSocket_create() };
if tcp.is_null() {
None
}
else {
Some(TcpSocket {
socket: tcp
})
}
}
pub fn set_blocking(&mut self, blocking: bool) {
unsafe {
ffi::sfTcpSocket_setBlocking(self.socket, sfBool::from_bool(blocking))
}
}
pub fn is_blocking(&self) -> bool {
unsafe { ffi::sfTcpSocket_isBlocking(self.socket) }.to_bool()
}
pub fn get_local_port(&self) -> u16 {
unsafe {
ffi::sfTcpSocket_getLocalPort(self.socket)
}
}
pub fn get_remote_address(&self) -> IpAddress {
unsafe {
Wrappable::wrap(ffi::sfTcpSocket_getRemoteAddress(self.socket))
}
}
pub fn get_remote_port(&self) -> u16 {
unsafe {
ffi::sfTcpSocket_getRemotePort(self.socket)
}
}
pub fn connect(&self, host: &IpAddress, port: u16, timeout: Time) -> SocketStatus {
unsafe {
mem::transmute(ffi::sfTcpSocket_connect(self.socket, host.unwrap(), port, timeout.unwrap()) as i32)
}
}
pub fn disconnect(&mut self) {
unsafe {
ffi::sfTcpSocket_disconnect(self.socket)
}
}
pub fn send(&self, data: &[i8]) -> SocketStatus {
unsafe {
mem::transmute(ffi::sfTcpSocket_send(self.socket, data.as_ptr(), data.len() as size_t) as i32)
}
}
pub fn receive(&self, max_size: size_t) -> (Vec<i8>, SocketStatus, size_t) {
unsafe {
let mut s: size_t = 0;
let datas: *mut i8 = ptr::null_mut();
let stat: SocketStatus = mem::transmute(ffi::sfTcpSocket_receive(self.socket, datas, max_size, &mut s) as i32);
(slice::from_raw_parts(datas, s as usize).to_vec(), stat, s)
}
}
pub fn send_packet(&self, packet: &Packet) -> SocketStatus {
unsafe {
mem::transmute(ffi::sfTcpSocket_sendPacket(self.socket, packet.unwrap()) as i32)
}
}
pub fn receive_packet(&self) -> (Packet, SocketStatus) {
unsafe {
let pack: *mut ffi::sfPacket = ptr::null_mut();
let stat: SocketStatus = mem::transmute(ffi::sfTcpSocket_receivePacket(self.socket, pack) as i32);
(Wrappable::wrap(pack), stat)
}
}
}
impl Wrappable<*mut ffi::sfTcpSocket> for TcpSocket {
fn wrap(socket: *mut ffi::sfTcpSocket) -> TcpSocket {
TcpSocket {
socket: socket
}
}
fn unwrap(&self) -> *mut ffi::sfTcpSocket {
self.socket
}
}
impl Drop for TcpSocket {
fn drop(&mut self) {
unsafe {
ffi::sfTcpSocket_destroy(self.socket)
}
}
}