core::rt: Declare large parts of the I/O API

This commit is contained in:
Brian Anderson 2013-04-17 17:55:21 -07:00
parent 10e6869a54
commit c44d7a6486
18 changed files with 1541 additions and 32 deletions

View File

@ -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!() }
}

View File

@ -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!() }
}

View File

@ -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());
}

121
src/libcore/rt/io/flate.rs Normal file
View File

@ -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);
}
}

166
src/libcore/rt/io/mem.rs Normal file
View File

@ -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!() }
}

42
src/libcore/rt/io/misc.rs Normal file
View File

@ -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));
}
}

View File

@ -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;
// 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.
condition! {
stream_error: super::StreamError -> bool;
/// 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 { }
}
}
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.
/// 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 `I/O` operations on error.
condition! {
io_error: super::IoError -> ();
}
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;
}

View File

@ -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 {
}
}
}

View File

@ -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
}

View File

@ -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>;
}

View File

@ -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!() }
}

View File

@ -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!() }
}

View File

@ -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!() }
}

View File

@ -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!() }
}

469
src/libcore/rt/io/util.rs Normal file
View File

@ -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);
}

View File

@ -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
}

View File

@ -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;

View File

@ -11,6 +11,7 @@
use option::*;
use result::*;
use super::io::net::ip::{IpAddr, Ipv4};
use super::uv::*;
use super::rtio::*;
use ops::Drop;