about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-04-17 17:55:21 -0700
committerBrian Anderson <banderson@mozilla.com>2013-04-19 12:05:18 -0700
commitc44d7a64865c5aa9507351be881e4c18ef38e4b0 (patch)
treeef5364d56885a819c18711ced6ac349788b1d70c
parent10e6869a54b3d9e703ca6bc29f49f522ee25d865 (diff)
downloadrust-c44d7a64865c5aa9507351be881e4c18ef38e4b0.tar.gz
rust-c44d7a64865c5aa9507351be881e4c18ef38e4b0.zip
core::rt: Declare large parts of the I/O API
-rw-r--r--src/libcore/rt/io/blocking/file.rs82
-rw-r--r--src/libcore/rt/io/comm_adapters.rs59
-rw-r--r--src/libcore/rt/io/file.rs64
-rw-r--r--src/libcore/rt/io/flate.rs121
-rw-r--r--src/libcore/rt/io/mem.rs166
-rw-r--r--src/libcore/rt/io/misc.rs42
-rw-r--r--src/libcore/rt/io/mod.rs269
-rw-r--r--src/libcore/rt/io/net/http.rs29
-rw-r--r--src/libcore/rt/io/net/ip.rs15
-rw-r--r--src/libcore/rt/io/net/mod.rs31
-rw-r--r--src/libcore/rt/io/net/tcp.rs50
-rw-r--r--src/libcore/rt/io/net/udp.rs51
-rw-r--r--src/libcore/rt/io/net/unix.rs51
-rw-r--r--src/libcore/rt/io/stdio.rs60
-rw-r--r--src/libcore/rt/io/util.rs469
-rw-r--r--src/libcore/rt/rtio.rs7
-rw-r--r--src/libcore/rt/uv/net.rs2
-rw-r--r--src/libcore/rt/uvio.rs1
18 files changed, 1539 insertions, 30 deletions
diff --git a/src/libcore/rt/io/blocking/file.rs b/src/libcore/rt/io/blocking/file.rs
new file mode 100644
index 00000000000..8daf8adf387
--- /dev/null
+++ b/src/libcore/rt/io/blocking/file.rs
@@ -0,0 +1,82 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Blocking posix-based file I/O
+
+use prelude::*;
+use super::super::*;
+use libc::{c_int, FILE};
+
+#[allow(non_camel_case_types)]
+pub type fd_t = c_int;
+
+// Make this a newtype so we can't do I/O on arbitrary integers
+pub struct FileDesc(fd_t);
+
+impl FileDesc {
+    /// Create a `FileDesc` from an open C file descriptor.
+    ///
+    /// The `FileDesc` takes ownership of the file descriptor
+    /// and will close it upon destruction.
+    pub fn new(_fd: fd_t) -> FileDesc { fail!() }
+}
+
+impl Reader for FileDesc {
+    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
+
+    fn eof(&mut self) -> bool { fail!() }
+}
+
+impl Writer for FileDesc {
+    fn write(&mut self, _buf: &[u8]) { fail!() }
+
+    fn flush(&mut self) { fail!() }
+}
+
+impl Closeable for FileDesc {
+    fn close(&mut self) { fail!() }
+}
+
+impl Seekable for FileDesc {
+    fn tell(&self) -> u64 { fail!() }
+
+    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
+}
+
+pub struct CFile(*FILE);
+
+impl CFile {
+    /// Create a `CFile` from an open `FILE` pointer.
+    ///
+    /// The `CFile` takes ownership of the file descriptor
+    /// and will close it upon destruction.
+    pub fn new(_file: *FILE) -> CFile { fail!() }
+}
+
+impl Reader for CFile {
+    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
+
+    fn eof(&mut self) -> bool { fail!() }
+}
+
+impl Writer for CFile {
+    fn write(&mut self, _buf: &[u8]) { fail!() }
+
+    fn flush(&mut self) { fail!() }
+}
+
+impl Closeable for CFile {
+    fn close(&mut self) { fail!() }
+}
+
+impl Seekable for CFile {
+    fn tell(&self) -> u64 { fail!() }
+    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
+}
diff --git a/src/libcore/rt/io/comm_adapters.rs b/src/libcore/rt/io/comm_adapters.rs
new file mode 100644
index 00000000000..1d6893b3ca6
--- /dev/null
+++ b/src/libcore/rt/io/comm_adapters.rs
@@ -0,0 +1,59 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use prelude::*;
+use super::{Reader, Writer};
+
+struct PortReader<P>;
+
+impl<P: GenericPort<~[u8]>> PortReader<P> {
+    pub fn new(_port: P) -> PortReader<P> { fail!() }
+}
+
+impl<P: GenericPort<~[u8]>> Reader for PortReader<P> {
+    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
+
+    fn eof(&mut self) -> bool { fail!() }
+}
+
+struct ChanWriter<C>;
+
+impl<C: GenericChan<~[u8]>> ChanWriter<C> {
+    pub fn new(_chan: C) -> ChanWriter<C> { fail!() }
+}
+
+impl<C: GenericChan<~[u8]>> Writer for ChanWriter<C> {
+    pub fn write(&mut self, _buf: &[u8]) { fail!() }
+
+    pub fn flush(&mut self) { fail!() }
+}
+
+struct ReaderPort<R>;
+
+impl<R: Reader> ReaderPort<R> {
+    pub fn new(_reader: R) -> ReaderPort<R> { fail!() }
+}
+
+impl<R: Reader> GenericPort<~[u8]> for ReaderPort<R> {
+    fn recv(&self) -> ~[u8] { fail!() }
+
+    fn try_recv(&self) -> Option<~[u8]> { fail!() }
+}
+
+struct WriterChan<W>;
+
+impl<W: Writer> WriterChan<W> {
+    pub fn new(_writer: W) -> WriterChan<W> { fail!() }
+}
+
+impl<W: Writer> GenericChan<~[u8]> for WriterChan<W> {
+    fn send(&self, _x: ~[u8]) { fail!() }
+}
+
diff --git a/src/libcore/rt/io/file.rs b/src/libcore/rt/io/file.rs
index b7f3ed280a8..0fa357f0ac9 100644
--- a/src/libcore/rt/io/file.rs
+++ b/src/libcore/rt/io/file.rs
@@ -9,35 +9,79 @@
 // except according to those terms.
 
 use prelude::*;
-use super::Stream;
+use super::misc::PathLike;
+use super::{Reader, Writer, Seekable, Closeable};
+use super::{IoError, SeekStyle};
+
+/// Open a file with the default FileMode and FileAccess
+/// # TODO are there sane defaults here?
+pub fn open_file<P: PathLike>(_path: &P) -> FileStream { fail!() }
+
+/// # TODO
+/// * Ugh, this is ridiculous. What is the best way to represent these options?
+enum FileMode {
+    /// Opens an existing file. IoError if file does not exist.
+    Open,
+    /// Creates a file. IoError if file exists.
+    Create,
+    /// Opens an existing file or creates a new one.
+    OpenOrCreate,
+    /// Opens an existing file or creates a new one, positioned at EOF.
+    Append,
+    /// Opens an existing file, truncating it to 0 bytes.
+    Truncate,
+    /// Opens an existing file or creates a new one, truncating it to 0 bytes.
+    CreateOrTruncate,
+}
+ 
+enum FileAccess {
+    Read,
+    Write,
+    ReadWrite
+}
 
 pub struct FileStream;
 
-pub impl FileStream {
-    fn new(_path: Path) -> FileStream {
+impl FileStream {
+    pub fn open<P: PathLike>(_path: &P,
+                             _mode: FileMode,
+                             _access: FileAccess
+                            ) -> Result<FileStream, IoError> {
         fail!()
     }
 }
 
-impl Stream for FileStream {
-    fn read(&mut self, _buf: &mut [u8]) -> uint {
+impl Reader for FileStream {
+    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> {
         fail!()
     }
 
     fn eof(&mut self) -> bool {
         fail!()
     }
+}
 
-    fn write(&mut self, _v: &const [u8]) {
-        fail!()
-    }
+impl Writer for FileStream {
+    fn write(&mut self, _v: &[u8]) { fail!() }
+
+    fn flush(&mut self) { fail!() }
+}
+
+impl Seekable for FileStream {
+    fn tell(&self) -> u64 { fail!() }
+
+    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
+}
+
+impl Closeable for FileStream {
+    fn close(&mut self) { fail!() }
 }
 
 #[test]
 #[ignore]
 fn super_simple_smoke_test_lets_go_read_some_files_and_have_a_good_time() {
     let message = "it's alright. have a good time";
-    let filename = Path("test.txt");
-    let mut outstream = FileStream::new(filename);
+    let filename = &Path("test.txt");
+    let mut outstream = FileStream::open(filename, Create, Read).unwrap();
     outstream.write(message.to_bytes());
 }
diff --git a/src/libcore/rt/io/flate.rs b/src/libcore/rt/io/flate.rs
new file mode 100644
index 00000000000..24537bef329
--- /dev/null
+++ b/src/libcore/rt/io/flate.rs
@@ -0,0 +1,121 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Some various other I/O types
+
+// NOTE: These ultimately belong somewhere else
+
+use prelude::*;
+use super::*;
+
+/// A Writer decorator that compresses using the 'deflate' scheme
+pub struct DeflateWriter<W> {
+    inner_writer: W
+}
+
+impl<W: Writer> DeflateWriter<W> {
+    pub fn new(inner_writer: W) -> DeflateWriter<W> {
+        DeflateWriter {
+            inner_writer: inner_writer
+        }
+    }
+}
+
+impl<W: Writer> Writer for DeflateWriter<W> {
+    fn write(&mut self, _buf: &[u8]) { fail!() }
+
+    fn flush(&mut self) { fail!() }
+}
+
+impl<W: Writer> Decorator<W> for DeflateWriter<W> {
+    fn inner(self) -> W {
+        match self {
+            DeflateWriter { inner_writer: w } => w
+        }
+    }
+
+    fn inner_ref<'a>(&'a self) -> &'a W {
+        match *self {
+            DeflateWriter { inner_writer: ref w } => w
+        }
+    }
+
+    fn inner_mut_ref<'a>(&'a mut self) -> &'a mut W {
+        match *self {
+            DeflateWriter { inner_writer: ref mut w } => w
+        }
+    }
+}
+
+/// A Reader decorator that decompresses using the 'deflate' scheme
+pub struct InflateReader<R> {
+    inner_reader: R
+}
+
+impl<R: Reader> InflateReader<R> {
+    pub fn new(inner_reader: R) -> InflateReader<R> {
+        InflateReader {
+            inner_reader: inner_reader
+        }
+    }
+}
+
+impl<R: Reader> Reader for InflateReader<R> {
+    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
+
+    fn eof(&mut self) -> bool { fail!() }
+}
+
+impl<R: Reader> Decorator<R> for InflateReader<R> {
+    fn inner(self) -> R {
+        match self {
+            InflateReader { inner_reader: r } => r
+        }
+    }
+
+    fn inner_ref<'a>(&'a self) -> &'a R {
+        match *self {
+            InflateReader { inner_reader: ref r } => r
+        }
+    }
+
+    fn inner_mut_ref<'a>(&'a mut self) -> &'a mut R {
+        match *self {
+            InflateReader { inner_reader: ref mut r } => r
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use prelude::*;
+    use super::*;
+    use super::super::mem::*;
+    use super::super::Decorator;
+
+    #[test]
+    #[ignore]
+    fn smoke_test() {
+        let mem_writer = MemWriter::new();
+        let mut deflate_writer = DeflateWriter::new(mem_writer);
+        let in_msg = "test";
+        let in_bytes = in_msg.to_bytes();
+        deflate_writer.write(in_bytes);
+        deflate_writer.flush();
+        let buf = deflate_writer.inner().inner();
+        let mem_reader = MemReader::new(buf);
+        let mut inflate_reader = InflateReader::new(mem_reader);
+        let mut out_bytes = [0, .. 100];
+        let bytes_read = inflate_reader.read(out_bytes).get();
+        assert!(bytes_read == in_bytes.len());
+        let out_msg = str::from_bytes(out_bytes);
+        assert!(in_msg == out_msg);
+    }
+}
\ No newline at end of file
diff --git a/src/libcore/rt/io/mem.rs b/src/libcore/rt/io/mem.rs
new file mode 100644
index 00000000000..04790c57913
--- /dev/null
+++ b/src/libcore/rt/io/mem.rs
@@ -0,0 +1,166 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Readers and Writers for in-memory buffers
+//!
+//! # TODO
+//!
+//! * Should probably have something like this for strings.
+//! * Should they implement Closable? Would take extra state.
+
+use prelude::*;
+use super::*;
+
+
+/// Writes to an owned, growable byte vector
+pub struct MemWriter {
+    buf: ~[u8]
+}
+
+impl MemWriter {
+    pub fn new() -> MemWriter { MemWriter { buf: ~[] } }
+}
+
+impl Writer for MemWriter {
+    fn write(&mut self, _buf: &[u8]) { fail!() }
+
+    fn flush(&mut self) { /* no-op */ }
+}
+
+impl Seekable for MemWriter {
+    fn tell(&self) -> u64 { fail!() }
+
+    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
+}
+
+impl Decorator<~[u8]> for MemWriter {
+
+    fn inner(self) -> ~[u8] {
+        match self {
+            MemWriter { buf: buf } => buf
+        }
+    }
+
+    fn inner_ref<'a>(&'a self) -> &'a ~[u8] {
+        match *self {
+            MemWriter { buf: ref buf } => buf
+        }
+    }
+
+    fn inner_mut_ref<'a>(&'a mut self) -> &'a mut ~[u8] {
+        match *self {
+            MemWriter { buf: ref mut buf } => buf
+        }
+    }
+}
+
+/// Reads from an owned byte vector 
+pub struct MemReader {
+    buf: ~[u8],
+    pos: uint
+}
+
+impl MemReader {
+    pub fn new(buf: ~[u8]) -> MemReader {
+        MemReader {
+            buf: buf,
+            pos: 0
+        }
+    }
+}
+
+impl Reader for MemReader {
+    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
+
+    fn eof(&mut self) -> bool { fail!() }
+}
+
+impl Seekable for MemReader {
+    fn tell(&self) -> u64 { fail!() }
+
+    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
+}
+
+impl Decorator<~[u8]> for MemReader {
+
+    fn inner(self) -> ~[u8] {
+        match self {
+            MemReader { buf: buf, _ } => buf
+        }
+    }
+
+    fn inner_ref<'a>(&'a self) -> &'a ~[u8] {
+        match *self {
+            MemReader { buf: ref buf, _ } => buf
+        }
+    }
+
+    fn inner_mut_ref<'a>(&'a mut self) -> &'a mut ~[u8] {
+        match *self {
+            MemReader { buf: ref mut buf, _ } => buf
+        }
+    }
+}
+
+ 
+/// Writes to a fixed-size byte slice
+struct BufWriter<'self> {
+    buf: &'self mut [u8],
+    pos: uint
+}
+ 
+impl<'self> BufWriter<'self> {
+    pub fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> {
+        BufWriter {
+            buf: buf,
+            pos: 0
+        }
+    }
+}
+
+impl<'self> Writer for BufWriter<'self> {
+    fn write(&mut self, _buf: &[u8]) { fail!() }
+
+    fn flush(&mut self) { fail!() }
+}
+
+impl<'self> Seekable for BufWriter<'self> {
+    fn tell(&self) -> u64 { fail!() }
+
+    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
+}
+
+
+/// Reads from a fixed-size byte slice 
+struct BufReader<'self> {
+    buf: &'self [u8],
+    pos: uint
+}
+
+impl<'self> BufReader<'self> {
+    pub fn new<'a>(buf: &'a [u8]) -> BufReader<'a> {
+        BufReader {
+            buf: buf,
+            pos: 0
+        }
+    }
+}
+
+impl<'self> Reader for BufReader<'self> {
+    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
+
+    fn eof(&mut self) -> bool { fail!() }
+}
+
+impl<'self> Seekable for BufReader<'self> {
+    fn tell(&self) -> u64 { fail!() }
+
+    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
+}
\ No newline at end of file
diff --git a/src/libcore/rt/io/misc.rs b/src/libcore/rt/io/misc.rs
new file mode 100644
index 00000000000..7bace5d6df2
--- /dev/null
+++ b/src/libcore/rt/io/misc.rs
@@ -0,0 +1,42 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use path::*;
+
+pub trait PathLike {
+    fn path_as_str<T>(&self, f: &fn(&str) -> T) -> T;
+}
+
+impl<'self> PathLike for &'self str {
+    fn path_as_str<T>(&self, f: &fn(&str) -> T) -> T {
+        f(*self)
+    }
+}
+
+impl PathLike for Path {
+    fn path_as_str<T>(&self, f: &fn(&str) -> T) -> T {
+        let s = self.to_str();
+        f(s)
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use path::*;
+    use super::PathLike;
+
+    #[test]
+    fn path_like_smoke_test() {
+        let expected = "/home";
+        let path = Path(expected);
+        path.path_as_str(|p| assert!(p == expected));
+        path.path_as_str(|p| assert!(p == expected));
+    }
+}
diff --git a/src/libcore/rt/io/mod.rs b/src/libcore/rt/io/mod.rs
index 1634e7443b4..e711c2ff66e 100644
--- a/src/libcore/rt/io/mod.rs
+++ b/src/libcore/rt/io/mod.rs
@@ -8,35 +8,276 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+/*! Synchronous I/O
+
+This module defines the Rust interface for synchronous I/O.
+It supports file access, 
+
+This will likely live in core::io, not core::rt::io.
+
+# Examples
+
+Some examples of obvious things you might want to do
+
+* Read lines from stdin
+
+    for stdin().each_line |line| {
+        println(line)
+    }
+
+* Read a complete file to a string, (converting newlines?)
+
+    let contents = open("message.txt").read_to_str(); // read_to_str??
+
+* Write a line to a file
+
+    let file = FileStream::open("message.txt", Create, Write);
+    file.write_line("hello, file!");
+
+* Iterate over the lines of a file
+
+* Pull the lines of a file into a vector of strings
+
+* Connect based on URL? Requires thinking about where the URL type lives
+  and how to make protocol handlers extensible, e.g. the "tcp" protocol
+  yields a `TcpStream`.
+
+    connect("tcp://localhost:8080").write_line("HTTP 1.0 GET /");
+
+# Terms
+
+* reader
+* writer
+* stream
+* Blocking vs. non-blocking
+* synchrony and asynchrony
+
+I tend to call this implementation non-blocking, because performing I/O
+doesn't block the progress of other tasks. Is that how we want to present
+it, 'synchronous but non-blocking'?
+
+# Error Handling
+
+# Resource management
+
+* `close` vs. RAII
+
+# Paths and URLs
+
+# std
+
+Some I/O things don't belong in core
+
+  - url
+  - net - `fn connect`
+    - http
+  - flate
+
+# TODO
+
+* Should default constructors take `Path` or `&str`? `Path` makes simple cases verbose.
+  Overloading would be nice.
+* Add overloading for Path and &str and Url &str
+* stdin/err/out
+* print, println, etc.
+* fsync
+* relationship with filesystem querying, Directory, File types etc.
+* Rename Reader/Writer to ByteReader/Writer, make Reader/Writer generic?
+* Trait for things that are both readers and writers, Stream?
+* How to handle newline conversion
+* String conversion
+* File vs. FileStream? File is shorter but could also be used for getting file info
+  - maybe File is for general file querying and *also* has a static `open` method
+* open vs. connect for generic stream opening
+* Do we need `close` at all? dtors might be good enough
+* How does I/O relate to the Iterator trait?
+* std::base64 filters
+
+*/
+
+use prelude::*;
+
+// Reexports
+pub use self::stdio::stdin;
+pub use self::stdio::stdout;
+pub use self::stdio::stderr;
+pub use self::stdio::print;
+pub use self::stdio::println;
+
+pub use self::file::open_file;
+pub use self::file::FileStream;
+pub use self::net::Listener;
+pub use self::net::ip::IpAddr;
+pub use self::net::tcp::TcpListener;
+pub use self::net::tcp::TcpStream;
+pub use self::net::udp::UdpStream;
+
+// Some extension traits that all Readers and Writers get.
+pub use self::util::ReaderUtil;
+pub use self::util::ReaderByteConversions;
+pub use self::util::WriterByteConversions;
+
+/// Synchronous, non-blocking file I/O.
 pub mod file;
 
-// FIXME #5370 Strongly want this to be StreamError(&mut Stream)
-pub struct StreamError;
+/// Synchronous, non-blocking network I/O.
+#[path = "net/mod.rs"]
+pub mod net;
+
+/// Readers and Writers for memory buffers and strings.
+#[cfg(not(stage0))] // XXX Using unsnapshotted features
+pub mod mem;
+
+/// Non-blocking access to stdin, stdout, stderr
+pub mod stdio;
+
+/// Basic stream compression. XXX: Belongs with other flate code
+#[cfg(not(stage0))] // XXX Using unsnapshotted features
+pub mod flate;
+
+/// Interop between byte streams and pipes. Not sure where it belongs
+#[cfg(not(stage0))] // XXX "
+pub mod comm_adapters;
+
+/// Extension traits
+mod util;
+
+/// Non-I/O things needed by the I/O module
+mod misc;
+
+/// Thread-blocking implementations
+pub mod blocking {
+    /// Posix file I/O
+    pub mod file;
+    /// # TODO - implement this
+    pub mod stdio { }
+    /// Sockets
+    /// # TODO - implement this
+    pub mod net {
+        pub mod tcp { }
+        pub mod udp { }
+        #[cfg(unix)]
+        pub mod unix { }
+    }
+}
+
+
+/// The type passed to I/O condition handlers to indicate error
+///
+/// # TODO
+///
+/// Is something like this sufficient? It's kind of archaic
+pub struct IoError {
+    kind: IoErrorKind,
+    desc: &'static str,
+    detail: Option<~str>
+}
+
+pub enum IoErrorKind {
+    FileNotFound,
+    FilePermission,
+    ConnectionFailed,
+    Closed,
+    OtherIoError
+}
 
 // XXX: Can't put doc comments on macros
-// Raised by `Stream` instances on error. Returning `true` from the handler
-// indicates that the `Stream` should continue, `false` that it should fail.
+// Raised by `I/O` operations on error.
 condition! {
-    stream_error: super::StreamError -> bool;
+    io_error: super::IoError -> ();
 }
 
-pub trait Stream {
-    /// Read bytes, up to the length of `buf` and place them in `buf`,
-    /// returning the number of bytes read or an `IoError`. Reads
-    /// 0 bytes on EOF.
+pub trait Reader {
+    /// Read bytes, up to the length of `buf` and place them in `buf`.
+    /// Returns the number of bytes read, or `None` on EOF.
     ///
     /// # Failure
     ///
-    /// Raises the `reader_error` condition on error
-    fn read(&mut self, buf: &mut [u8]) -> uint;
+    /// Raises the `io_error` condition on error, then returns `None`.
+    ///
+    /// # TODO
+    ///
+    /// This doesn't take a `len` argument like the old `read`.
+    /// Will people often need to slice their vectors to call this
+    /// and will that be annoying?
+    fn read(&mut self, buf: &mut [u8]) -> Option<uint>;
 
-    /// Return whether the Reader has reached the end of the stream
+    /// Return whether the Reader has reached the end of the stream.
+    ///
+    /// # Example
+    ///
+    ///     let reader = FileStream::new()
+    ///     while !reader.eof() {
+    ///         println(reader.read_line());
+    ///     }
+    ///
+    /// # TODO
+    ///
+    /// What does this return if the Reader is in an error state?
     fn eof(&mut self) -> bool;
+}
 
+pub trait Writer {
     /// Write the given buffer
     ///
     /// # Failure
     ///
-    /// Raises the `writer_error` condition on error
-    fn write(&mut self, v: &const [u8]);
+    /// Raises the `io_error` condition on error
+    fn write(&mut self, buf: &[u8]);
+
+    /// Flush output
+    fn flush(&mut self);
+}
+
+/// I/O types that may be closed
+///
+/// Any further operations performed on a closed resource will raise
+/// on `io_error`
+pub trait Closeable {
+    /// Close the I/O resource
+    fn close(&mut self);
+}
+
+pub trait Stream: Reader + Writer + Closeable { }
+
+pub enum SeekStyle {
+    /// Seek from the beginning of the stream
+    SeekSet,
+    /// Seek from the end of the stream
+    SeekEnd,
+    /// Seek from the current position
+    SeekCur,
+}
+
+/// # TODO
+/// * Are `u64` and `i64` the right choices?
+pub trait Seekable {
+    fn tell(&self) -> u64;
+    fn seek(&mut self, pos: i64, style: SeekStyle);
+}
+
+/// Common trait for decorator types.
+///
+/// Provides accessors to get the inner, 'decorated' values. The I/O library
+/// uses decorators to add functionality like compression and encryption to I/O
+/// streams.
+///
+/// # TODO
+///
+/// Is this worth having a trait for? May be overkill
+pub trait Decorator<T> {
+    /// Destroy the decorator and extract the decorated value
+    ///
+    /// # TODO
+    ///
+    /// Because this takes `self' one could never 'undecorate' a Reader/Writer
+    /// that has been boxed. Is that ok? This feature is mostly useful for
+    /// extracting the buffer from MemWriter
+    fn inner(self) -> T;
+
+    /// Take an immutable reference to the decorated value
+    fn inner_ref<'a>(&'a self) -> &'a T;
+
+    /// Take a mutable reference to the decorated value
+    fn inner_mut_ref<'a>(&'a mut self) -> &'a mut T;
 }
diff --git a/src/libcore/rt/io/net/http.rs b/src/libcore/rt/io/net/http.rs
new file mode 100644
index 00000000000..40f0b315e05
--- /dev/null
+++ b/src/libcore/rt/io/net/http.rs
@@ -0,0 +1,29 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Simple HTTP client and server
+
+// XXX This should not be in core
+
+struct HttpServer;
+
+#[cfg(test)]
+mod test {
+    use unstable::run_in_bare_thread;
+    
+    #[test] #[ignore]
+    fn smoke_test() {
+        do run_in_bare_thread {
+        }
+
+        do run_in_bare_thread {
+        }
+    }
+}
diff --git a/src/libcore/rt/io/net/ip.rs b/src/libcore/rt/io/net/ip.rs
new file mode 100644
index 00000000000..d9b7f4e6e40
--- /dev/null
+++ b/src/libcore/rt/io/net/ip.rs
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub enum IpAddr {
+    Ipv4(u8, u8, u8, u8, u16),
+    Ipv6
+}
+
diff --git a/src/libcore/rt/io/net/mod.rs b/src/libcore/rt/io/net/mod.rs
new file mode 100644
index 00000000000..130ff6b38fa
--- /dev/null
+++ b/src/libcore/rt/io/net/mod.rs
@@ -0,0 +1,31 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use prelude::*;
+
+pub mod tcp;
+pub mod udp;
+pub mod ip;
+#[cfg(unix)]
+pub mod unix;
+pub mod http;
+
+/// A listener is a value that listens for connections
+pub trait Listener<S> {
+    /// Wait for and accept an incoming connection
+    ///
+    /// Returns `None` on timeout.
+    ///
+    /// # Failure
+    ///
+    /// Raises `io_error` condition. If the condition is handled,
+    /// then `accept` returns `None`.
+    fn accept(&mut self) -> Option<S>;
+}
diff --git a/src/libcore/rt/io/net/tcp.rs b/src/libcore/rt/io/net/tcp.rs
new file mode 100644
index 00000000000..ddd75cd8415
--- /dev/null
+++ b/src/libcore/rt/io/net/tcp.rs
@@ -0,0 +1,50 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use prelude::*;
+use super::*;
+use super::super::*;
+use super::ip::IpAddr;
+
+pub struct TcpStream;
+
+impl TcpStream {
+    pub fn connect(_addr: IpAddr) -> Result<TcpStream, IoError> {
+        fail!()
+    }
+}
+
+impl Reader for TcpStream {
+    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
+
+    fn eof(&mut self) -> bool { fail!() }
+}
+
+impl Writer for TcpStream {
+    fn write(&mut self, _buf: &[u8]) { fail!() }
+
+    fn flush(&mut self) { fail!() }
+}
+
+impl Closeable for TcpStream {
+    fn close(&mut self) { fail!() }
+}
+
+pub struct TcpListener;
+
+impl TcpListener {
+    pub fn new(_addr: IpAddr) -> TcpListener {
+        fail!()
+    }
+}
+
+impl Listener<TcpStream> for TcpListener {
+    fn accept(&mut self) -> Option<TcpStream> { fail!() }
+}
diff --git a/src/libcore/rt/io/net/udp.rs b/src/libcore/rt/io/net/udp.rs
new file mode 100644
index 00000000000..a0f7aa81989
--- /dev/null
+++ b/src/libcore/rt/io/net/udp.rs
@@ -0,0 +1,51 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use prelude::*;
+use super::*;
+use super::super::*;
+use super::ip::IpAddr;
+
+pub struct UdpStream;
+
+impl UdpStream {
+    pub fn connect(_addr: IpAddr) -> Result<UdpStream, IoError> {
+        fail!()
+    }
+}
+
+impl Reader for UdpStream {
+    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
+
+    fn eof(&mut self) -> bool { fail!() }
+}
+
+impl Writer for UdpStream {
+    fn write(&mut self, _buf: &[u8]) { fail!() }
+
+    fn flush(&mut self) { fail!() }
+}
+
+impl Closeable for UdpStream {
+    fn close(&mut self) { fail!() }
+}
+
+pub struct UdpListener;
+
+impl UdpListener {
+    pub fn new(_addr: IpAddr) -> UdpListener {
+        fail!()
+    }
+}
+
+impl Listener<UdpStream> for UdpListener {
+    fn accept(&mut self) -> Option<UdpStream> { fail!() }
+}
+
diff --git a/src/libcore/rt/io/net/unix.rs b/src/libcore/rt/io/net/unix.rs
new file mode 100644
index 00000000000..fde87deef33
--- /dev/null
+++ b/src/libcore/rt/io/net/unix.rs
@@ -0,0 +1,51 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use prelude::*;
+use super::*;
+use super::super::*;
+use super::super::misc::PathLike;
+
+pub struct UnixStream;
+
+impl UnixStream {
+    pub fn connect<P: PathLike>(_path: &P) -> Result<UnixStream, IoError> {
+        fail!()
+    }
+}
+
+impl Reader for UnixStream {
+    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
+
+    fn eof(&mut self) -> bool { fail!() }
+}
+
+impl Writer for UnixStream {
+    fn write(&mut self, _v: &[u8]) { fail!() }
+
+    fn flush(&mut self) { fail!() }
+}
+
+impl Closeable for UnixStream {
+    fn close(&mut self) { fail!() }
+}
+
+pub struct UnixListener;
+
+impl UnixListener {
+    pub fn new<P: PathLike>(_path: &P) -> UnixListener {
+        fail!()
+    }
+}
+
+impl Listener<UnixStream> for UnixListener {
+    fn accept(&mut self) -> Option<UnixStream> { fail!() }
+}
+
diff --git a/src/libcore/rt/io/stdio.rs b/src/libcore/rt/io/stdio.rs
new file mode 100644
index 00000000000..3a742266f81
--- /dev/null
+++ b/src/libcore/rt/io/stdio.rs
@@ -0,0 +1,60 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use prelude::*;
+use super::{Reader, Writer, Closeable};
+
+pub fn stdin() -> StdReader { fail!() }
+
+pub fn stdout() -> StdWriter { fail!() }
+
+pub fn stderr() -> StdReader { fail!() }
+
+pub fn print(s: &str) { fail!() }
+
+pub fn println(s: &str) { fail!() }
+
+pub enum StdStream {
+    StdIn,
+    StdOut,
+    StdErr
+}
+
+pub struct StdReader;
+
+impl StdReader {
+    pub fn new(_stream: StdStream) -> StdReader { fail!() }
+}
+
+impl Reader for StdReader {
+    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }
+
+    fn eof(&mut self) -> bool { fail!() }
+}
+
+impl Closeable for StdReader {
+    fn close(&mut self) { fail!() }
+}
+
+pub struct StdWriter;
+
+impl StdWriter {
+    pub fn new(_stream: StdStream) -> StdWriter { fail!() }
+}
+
+impl Writer for StdWriter {
+    fn write(&mut self, _buf: &[u8]) { fail!() }
+
+    fn flush(&mut self) { fail!() }
+}
+
+impl Closeable for StdWriter {
+    fn close(&mut self) { fail!() }
+}
diff --git a/src/libcore/rt/io/util.rs b/src/libcore/rt/io/util.rs
new file mode 100644
index 00000000000..d695815adce
--- /dev/null
+++ b/src/libcore/rt/io/util.rs
@@ -0,0 +1,469 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Utility mixins that apply to all Readers and Writers
+
+// TODO: Not sure how this should be structured
+// TODO: Iteration should probably be considered seperately
+
+pub trait ReaderUtil {
+
+    /// Reads `len` bytes and gives you back a new vector
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns an empty
+    /// vector if the condition is handled.
+    fn read_bytes(&mut self, len: uint) -> ~[u8];
+
+    /// Reads all remaining bytes from the stream.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns an empty
+    /// vector if the condition is handled.
+    fn read_to_end(&mut self) -> ~[u8];
+
+}
+
+pub trait ReaderByteConversions {
+    /// Reads `n` little-endian unsigned integer bytes.
+    ///
+    /// `n` must be between 1 and 8, inclusive.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_le_uint_n(&mut self, nbytes: uint) -> u64;
+
+    /// Reads `n` little-endian signed integer bytes.
+    ///
+    /// `n` must be between 1 and 8, inclusive.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_le_int_n(&mut self, nbytes: uint) -> i64;
+
+    /// Reads `n` big-endian unsigned integer bytes.
+    ///
+    /// `n` must be between 1 and 8, inclusive.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_be_uint_n(&mut self, nbytes: uint) -> u64;
+
+    /// Reads `n` big-endian signed integer bytes.
+    ///
+    /// `n` must be between 1 and 8, inclusive.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_be_int_n(&mut self, nbytes: uint) -> i64;
+
+    /// Reads a little-endian unsigned integer.
+    ///
+    /// The number of bytes returned is system-dependant.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_le_uint(&mut self) -> uint;
+
+    /// Reads a little-endian integer.
+    ///
+    /// The number of bytes returned is system-dependant.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_le_int(&mut self) -> int;
+
+    /// Reads a big-endian unsigned integer.
+    ///
+    /// The number of bytes returned is system-dependant.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_be_uint(&mut self) -> uint;
+
+    /// Reads a big-endian integer.
+    ///
+    /// The number of bytes returned is system-dependant.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_be_int(&mut self) -> int;
+
+    /// Reads a big-endian `u64`.
+    ///
+    /// `u64`s are 8 bytes long.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_be_u64(&mut self) -> u64;
+
+    /// Reads a big-endian `u32`.
+    ///
+    /// `u32`s are 4 bytes long.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_be_u32(&mut self) -> u32;
+
+    /// Reads a big-endian `u16`.
+    ///
+    /// `u16`s are 2 bytes long.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_be_u16(&mut self) -> u16;
+
+    /// Reads a big-endian `i64`.
+    ///
+    /// `i64`s are 8 bytes long.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_be_i64(&mut self) -> i64;
+
+    /// Reads a big-endian `i32`.
+    ///
+    /// `i32`s are 4 bytes long.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_be_i32(&mut self) -> i32;
+
+    /// Reads a big-endian `i16`.
+    ///
+    /// `i16`s are 2 bytes long.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_be_i16(&mut self) -> i16;
+
+    /// Reads a big-endian `f64`.
+    ///
+    /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_be_f64(&mut self) -> f64;
+
+    /// Reads a big-endian `f32`.
+    ///
+    /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_be_f32(&mut self) -> f32;
+
+    /// Reads a little-endian `u64`.
+    ///
+    /// `u64`s are 8 bytes long.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_le_u64(&mut self) -> u64;
+
+    /// Reads a little-endian `u32`.
+    ///
+    /// `u32`s are 4 bytes long.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_le_u32(&mut self) -> u32;
+
+    /// Reads a little-endian `u16`.
+    ///
+    /// `u16`s are 2 bytes long.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_le_u16(&mut self) -> u16;
+
+    /// Reads a little-endian `i64`.
+    ///
+    /// `i64`s are 8 bytes long.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_le_i64(&mut self) -> i64;
+
+    /// Reads a little-endian `i32`.
+    ///
+    /// `i32`s are 4 bytes long.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_le_i32(&mut self) -> i32;
+
+    /// Reads a little-endian `i16`.
+    ///
+    /// `i16`s are 2 bytes long.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_le_i16(&mut self) -> i16;
+
+    /// Reads a little-endian `f64`.
+    ///
+    /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_le_f64(&mut self) -> f64;
+
+    /// Reads a little-endian `f32`.
+    ///
+    /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_le_f32(&mut self) -> f32;
+
+    /// Read a u8.
+    ///
+    /// `u8`s are 1 byte.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_u8(&mut self) -> u8;
+
+    /// Read an i8.
+    ///
+    /// `i8`s are 1 byte.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error. Returns `0` if
+    /// the condition is handled.
+    fn read_i8(&mut self) -> i8;
+
+}
+
+pub trait WriterByteConversions {
+    /// Write the result of passing n through `int::to_str_bytes`.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_int(&mut self, n: int);
+
+    /// Write the result of passing n through `uint::to_str_bytes`.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_uint(&mut self, n: uint);
+
+    /// Write a little-endian uint (number of bytes depends on system).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_le_uint(&mut self, n: uint);
+
+    /// Write a little-endian int (number of bytes depends on system).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_le_int(&mut self, n: int);
+
+    /// Write a big-endian uint (number of bytes depends on system).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_be_uint(&mut self, n: uint);
+
+    /// Write a big-endian int (number of bytes depends on system).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_be_int(&mut self, n: int);
+
+    /// Write a big-endian u64 (8 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_be_u64(&mut self, n: u64);
+
+    /// Write a big-endian u32 (4 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_be_u32(&mut self, n: u32);
+
+    /// Write a big-endian u16 (2 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_be_u16(&mut self, n: u16);
+
+    /// Write a big-endian i64 (8 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_be_i64(&mut self, n: i64);
+
+    /// Write a big-endian i32 (4 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_be_i32(&mut self, n: i32);
+
+    /// Write a big-endian i16 (2 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_be_i16(&mut self, n: i16);
+
+    /// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_be_f64(&mut self, f: f64);
+
+    /// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_be_f32(&mut self, f: f32);
+
+    /// Write a little-endian u64 (8 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_le_u64(&mut self, n: u64);
+
+    /// Write a little-endian u32 (4 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_le_u32(&mut self, n: u32);
+
+    /// Write a little-endian u16 (2 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_le_u16(&mut self, n: u16);
+
+    /// Write a little-endian i64 (8 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_le_i64(&mut self, n: i64);
+
+    /// Write a little-endian i32 (4 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_le_i32(&mut self, n: i32);
+
+    /// Write a little-endian i16 (2 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_le_i16(&mut self, n: i16);
+
+    /// Write a little-endian IEEE754 double-precision floating-point
+    /// (8 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_le_f64(&mut self, f: f64);
+
+    /// Write a litten-endian IEEE754 single-precision floating-point
+    /// (4 bytes).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_le_f32(&mut self, f: f32);
+
+    /// Write a u8 (1 byte).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_u8(&mut self, n: u8);
+
+    /// Write a i8 (1 byte).
+    ///
+    /// # Failure
+    ///
+    /// Raises the `io_error` condition on error.
+    fn write_i8(&mut self, n: i8);
+}
diff --git a/src/libcore/rt/rtio.rs b/src/libcore/rt/rtio.rs
index 6a7c3970c00..66eb79ba6ae 100644
--- a/src/libcore/rt/rtio.rs
+++ b/src/libcore/rt/rtio.rs
@@ -11,6 +11,8 @@
 use option::*;
 use result::*;
 
+use super::io::net::ip::IpAddr;
+
 // XXX: ~object doesn't work currently so these are some placeholder
 // types to use instead
 pub type EventLoopObject = super::uvio::UvEventLoop;
@@ -43,8 +45,3 @@ pub trait Stream {
     fn read(&mut self, buf: &mut [u8]) -> Result<uint, ()>;
     fn write(&mut self, buf: &[u8]) -> Result<(), ()>;
 }
-
-pub enum IpAddr {
-    Ipv4(u8, u8, u8, u8, u16),
-    Ipv6
-}
diff --git a/src/libcore/rt/uv/net.rs b/src/libcore/rt/uv/net.rs
index 4b9ff4504dd..0dc1a4d86cb 100644
--- a/src/libcore/rt/uv/net.rs
+++ b/src/libcore/rt/uv/net.rs
@@ -17,7 +17,7 @@ use super::{Loop, Watcher, Request, UvError, Buf, Callback, NativeHandle, NullCa
             loop_from_watcher, status_to_maybe_uv_error,
             install_watcher_data, get_watcher_data, drop_watcher_data,
             vec_to_uv_buf, vec_from_uv_buf};
-use super::super::rtio::{IpAddr, Ipv4, Ipv6};
+use super::super::io::net::ip::{IpAddr, Ipv4, Ipv6};
 
 #[cfg(test)]
 use unstable::run_in_bare_thread;
diff --git a/src/libcore/rt/uvio.rs b/src/libcore/rt/uvio.rs
index fe7b0a71dbf..b069c67a5f7 100644
--- a/src/libcore/rt/uvio.rs
+++ b/src/libcore/rt/uvio.rs
@@ -11,6 +11,7 @@
 use option::*;
 use result::*;
 
+use super::io::net::ip::{IpAddr, Ipv4};
 use super::uv::*;
 use super::rtio::*;
 use ops::Drop;