diff options
| author | Eric Reed <ereed@mozilla.com> | 2013-06-19 17:23:55 -0700 |
|---|---|---|
| committer | Eric Reed <ereed@mozilla.com> | 2013-06-19 17:23:55 -0700 |
| commit | ac49b74e8254b3129694f5a5425dbda4ffc4b186 (patch) | |
| tree | f54b743dfb552d0516fc54cd7b7f34c0d5741d60 /src/libstd/rt/io | |
| parent | 083c692565340791b06ab67d66c4c95d63b222cb (diff) | |
| download | rust-ac49b74e8254b3129694f5a5425dbda4ffc4b186.tar.gz rust-ac49b74e8254b3129694f5a5425dbda4ffc4b186.zip | |
socket based UDP io
Diffstat (limited to 'src/libstd/rt/io')
| -rw-r--r-- | src/libstd/rt/io/net/udp.rs | 101 |
1 files changed, 77 insertions, 24 deletions
diff --git a/src/libstd/rt/io/net/udp.rs b/src/libstd/rt/io/net/udp.rs index 6275eff9249..ac5a118f22a 100644 --- a/src/libstd/rt/io/net/udp.rs +++ b/src/libstd/rt/io/net/udp.rs @@ -8,47 +8,100 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use option::{Option}; +use option::{Option, Some, None}; +use result::{Ok, Err}; use rt::io::net::ip::IpAddr; -use rt::io::{Reader, Writer, Listener}; -use rt::rtio::{RtioUdpStreamObject}; +use rt::io::{Reader, Writer}; +use rt::io::{io_error, read_error, EndOfFile}; +use rt::rtio::{RtioUdpSocketObject, RtioUdpSocket, IoFactory, IoFactoryObject}; +use rt::local::Local; + +pub struct UdpSocket { + rtsocket: ~RtioUdpSocketObject +} + +impl UdpSocket { + fn new(s: ~RtioUdpSocketObject) -> UdpSocket { + UdpSocket { rtsocket: s } + } + + pub fn bind(addr: IpAddr) -> Option<UdpSocket> { + let socket = unsafe { + let io = Local::unsafe_borrow::<IoFactoryObject>(); + (*io).udp_bind(addr) + }; + match socket { + Ok(s) => { Some(UdpSocket { rtsocket: s }) } + Err(ioerr) => { + io_error::cond.raise(ioerr); + return None; + } + } + } + + pub fn recvfrom(&self, buf: &mut [u8]) -> Option<(uint, IpAddr)> { + match (*self.rtsocket).recvfrom(buf) { + Ok((nread, src)) => Some((nread, src)), + Err(ioerr) => { + // EOF is indicated by returning None + // XXX do we ever find EOF reading UDP packets? + if ioerr.kind != EndOfFile { + read_error::cond.raise(ioerr); + } + None + } + } + } + + pub fn sendto(&self, buf: &[u8], dst: IpAddr) { + match (*self.rtsocket).sendto(buf, dst) { + Ok(_) => (), + Err(ioerr) => { + io_error::cond.raise(ioerr); + } + } + } + + // XXX convert ~self to self eventually + pub fn connect(~self, other: IpAddr) -> UdpStream { + UdpStream { socket: self, connectedTo: other } + } +} pub struct UdpStream { - rtstream: ~RtioUdpStreamObject + socket: ~UdpSocket, + connectedTo: IpAddr } impl UdpStream { - fn new(s: ~RtioUdpStreamObject) -> UdpStream { - UdpStream { - rtstream: s - } + pub fn as_socket<T>(&self, f: &fn(&UdpSocket) -> T) -> T { + f(self.socket) } - pub fn connect(_addr: IpAddr) -> Option<UdpStream> { - fail!() + pub fn disconnect(self) -> ~UdpSocket { + let UdpStream { socket: s, _ } = self; + s } } impl Reader for UdpStream { - fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() } + fn read(&mut self, buf: &mut [u8]) -> Option<uint> { + let conn = self.connectedTo; + do self.as_socket |sock| { + sock.recvfrom(buf) + .map_consume(|(nread,src)| if src == conn {nread} else {0}) + } + } fn eof(&mut self) -> bool { fail!() } } impl Writer for UdpStream { - fn write(&mut self, _buf: &[u8]) { fail!() } - - fn flush(&mut self) { fail!() } -} - -pub struct UdpListener; - -impl UdpListener { - pub fn bind(_addr: IpAddr) -> Option<UdpListener> { - fail!() + fn write(&mut self, buf: &[u8]) { + do self.as_socket |sock| { + sock.sendto(buf, self.connectedTo); + } } -} -impl Listener<UdpStream> for UdpListener { - fn accept(&mut self) -> Option<UdpStream> { fail!() } + fn flush(&mut self) { fail!() } } |
