about summary refs log tree commit diff
path: root/src/libstd/rt/io
diff options
context:
space:
mode:
authorEric Reed <ereed@mozilla.com>2013-06-19 17:23:55 -0700
committerEric Reed <ereed@mozilla.com>2013-06-19 17:23:55 -0700
commitac49b74e8254b3129694f5a5425dbda4ffc4b186 (patch)
treef54b743dfb552d0516fc54cd7b7f34c0d5741d60 /src/libstd/rt/io
parent083c692565340791b06ab67d66c4c95d63b222cb (diff)
downloadrust-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.rs101
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!() }
 }