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