asyncio/
dgram_socket.rs

1use prelude::{Protocol, IoControl, GetSocketOption, SetSocketOption};
2use ffi::{RawFd, AsRawFd, ioctl, getsockopt, setsockopt,
3          getsockname, getpeername, socket, bind, shutdown};
4use core::{IoContext, AsIoContext, Socket, AsyncFd};
5use async::Handler;
6use socket_base::{Shutdown, BytesReadable};
7use reactive_io::{AsAsyncFd, getnonblock, setnonblock, cancel, connect,
8                  send, async_send, sendto, async_sendto,
9                  recv, async_recv, recvfrom, async_recvfrom};
10
11use std::io;
12use std::fmt;
13
14/// Provides a datagram-oriented socket.
15pub struct DgramSocket<P> {
16    pro: P,
17    fd: AsyncFd,
18}
19
20impl<P: Protocol> DgramSocket<P> {
21    pub fn new(ctx: &IoContext, pro: P) -> io::Result<DgramSocket<P>> {
22        let fd = try!(socket(&pro));
23        Ok(unsafe { Self::from_raw_fd(ctx, pro, fd) })
24    }
25
26    pub fn async_connect<F>(&self, ep: &P:: Endpoint, handler: F) -> F::Output
27        where F: Handler<(), io::Error>,
28    {
29        handler.result(self.as_ctx(), self.connect(ep))
30    }
31
32    pub fn async_receive<F>(&self, buf: &mut [u8], flags: i32, handler: F) -> F::Output
33        where F: Handler<usize, io::Error>,
34    {
35        async_recv(self, buf, flags, handler)
36    }
37
38    pub fn async_receive_from<F>(&self, buf: &mut [u8], flags: i32, handler: F) -> F::Output
39        where F: Handler<(usize, P::Endpoint), io::Error>,
40    {
41        let ep = unsafe { self.pro.uninitialized() };
42        async_recvfrom(self, buf, flags, ep, handler)
43    }
44
45    pub fn async_send<F>(&self, buf: &[u8], flags: i32, handler: F) -> F::Output
46        where F: Handler<usize, io::Error>,
47    {
48        async_send(self, buf, flags, handler)
49    }
50
51    pub fn async_send_to<F>(&self, buf: &[u8], flags: i32, ep: P::Endpoint, handler: F) -> F::Output
52        where F: Handler<usize, io::Error>,
53    {
54        async_sendto(self, buf, flags, ep, handler)
55    }
56
57    pub fn available(&self) -> io::Result<usize> {
58        let mut bytes = BytesReadable::default();
59        try!(self.io_control(&mut bytes));
60        Ok(bytes.get())
61    }
62
63    pub fn bind(&self, ep: &P::Endpoint) -> io::Result<()> {
64        bind(self, ep)
65    }
66
67    pub fn cancel(&self) -> &Self {
68        cancel(self);
69        self
70    }
71
72    pub fn connect(&self, ep: &P:: Endpoint) -> io::Result<()> {
73        connect(self, ep)
74    }
75
76    pub fn get_non_blocking(&self) -> io::Result<bool> {
77        getnonblock(self)
78    }
79
80    pub fn get_option<C>(&self) -> io::Result<C>
81        where C: GetSocketOption<P>,
82    {
83        getsockopt(self, &self.pro)
84    }
85
86    pub fn io_control<T>(&self, cmd: &mut T) -> io::Result<()>
87        where T: IoControl,
88    {
89        ioctl(self, cmd)
90    }
91
92    pub fn local_endpoint(&self) -> io::Result<P::Endpoint> {
93        getsockname(self, &self.pro)
94    }
95
96    pub fn receive(&self, buf: &mut [u8], flags: i32) -> io::Result<usize> {
97        recv(self, buf, flags)
98    }
99
100    pub fn receive_from(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, P::Endpoint)> {
101        recvfrom(self, buf, flags, &self.pro)
102    }
103
104    pub fn remote_endpoint(&self) -> io::Result<P::Endpoint> {
105        getpeername(self, &self.pro)
106    }
107
108    pub fn send(&self, buf: &[u8], flags: i32) -> io::Result<usize> {
109        send(self, buf, flags)
110    }
111
112    pub fn send_to(&self, buf: &[u8], flags: i32, ep: P::Endpoint) -> io::Result<usize> {
113        sendto(self, buf, flags, ep)
114    }
115
116    pub fn set_non_blocking(&self, on: bool) -> io::Result<()> {
117        setnonblock(self, on)
118    }
119
120    pub fn set_option<C>(&self, cmd: C) -> io::Result<()>
121        where C: SetSocketOption<P>,
122    {
123        setsockopt(self, &self.pro, cmd)
124    }
125
126    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
127        shutdown(self, how)
128    }
129}
130
131impl<P: Protocol> fmt::Debug for DgramSocket<P> {
132    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
133        write!(f, "DgramSocket({:?})", self.pro)
134    }
135}
136
137impl<P> AsRawFd for DgramSocket<P> {
138    fn as_raw_fd(&self) -> RawFd {
139        self.fd.as_raw_fd()
140    }
141}
142
143unsafe impl<P> Send for DgramSocket<P> { }
144
145unsafe impl<P> AsIoContext for DgramSocket<P> {
146    fn as_ctx(&self) -> &IoContext {
147        self.fd.as_ctx()
148    }
149}
150
151impl<P: Protocol> Socket<P> for DgramSocket<P> {
152    unsafe fn from_raw_fd(ctx: &IoContext, pro: P, fd: RawFd) -> DgramSocket<P> {
153        DgramSocket {
154            pro: pro,
155            fd: AsyncFd::new::<Self>(fd, ctx),
156        }
157    }
158
159    fn protocol(&self) -> P {
160        self.pro.clone()
161    }
162}
163
164impl<P: Protocol> AsAsyncFd for DgramSocket<P> {
165    fn as_fd(&self) -> &AsyncFd {
166        &self.fd
167    }
168}