use ax_api::net::{self as api, AxTcpSocketHandle};
use super::{SocketAddr, ToSocketAddrs};
use crate::{
StdResult,
io::{self, prelude::*},
};
pub struct TcpStream(AxTcpSocketHandle);
pub struct TcpListener(AxTcpSocketHandle);
impl TcpStream {
pub fn connect<A: ToSocketAddrs>(addr: A) -> StdResult<TcpStream> {
super::each_addr(addr, |addr: StdResult<&SocketAddr>| {
let addr = addr?;
let socket = api::ax_tcp_socket();
api::ax_tcp_connect(&socket, *addr)?;
Ok(TcpStream(socket))
})
}
pub fn local_addr(&self) -> StdResult<SocketAddr> {
Ok(api::ax_tcp_socket_addr(&self.0)?)
}
pub fn peer_addr(&self) -> StdResult<SocketAddr> {
Ok(api::ax_tcp_peer_addr(&self.0)?)
}
pub fn shutdown(&self) -> StdResult {
api::ax_tcp_shutdown(&self.0)?;
Ok(())
}
}
impl Read for TcpStream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
Ok(api::ax_tcp_recv(&self.0, buf)?)
}
}
impl Write for TcpStream {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
Ok(api::ax_tcp_send(&self.0, buf)?)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl TcpListener {
pub fn bind<A: ToSocketAddrs>(addr: A) -> StdResult<TcpListener> {
super::each_addr(addr, |addr: StdResult<&SocketAddr>| {
let addr = addr?;
let backlog = 128;
let socket = api::ax_tcp_socket();
api::ax_tcp_bind(&socket, *addr)?;
api::ax_tcp_listen(&socket, backlog)?;
Ok(TcpListener(socket))
})
}
pub fn local_addr(&self) -> StdResult<SocketAddr> {
Ok(api::ax_tcp_socket_addr(&self.0)?)
}
pub fn accept(&self) -> StdResult<(TcpStream, SocketAddr)> {
let (socket, address) = api::ax_tcp_accept(&self.0)?;
Ok((TcpStream(socket), address))
}
}