From 72557d83124aac4a362b99cbdb31a00f46be4bae Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 25 Oct 2013 18:08:45 -0700 Subject: [PATCH] Remove the extension traits for Readers/Writers These methods are all excellent candidates for default methods, so there's no need to require extra imports of various traits. --- src/compiletest/runtest.rs | 2 +- src/libextra/json.rs | 3 +- src/libextra/terminfo/parser/compiled.rs | 19 +- src/libextra/workcache.rs | 3 +- src/librustc/metadata/encoder.rs | 15 +- src/librustc/rustc.rs | 2 +- src/librustpkg/workcache_support.rs | 2 +- src/libstd/rand/reader.rs | 9 +- src/libstd/rt/io/extensions.rs | 618 +---------------------- src/libstd/rt/io/mod.rs | 477 ++++++++++++++++- src/libstd/run.rs | 2 +- src/libsyntax/ext/source_util.rs | 2 +- src/libsyntax/parse/comments.rs | 3 +- src/libsyntax/parse/mod.rs | 2 +- 14 files changed, 518 insertions(+), 641 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 4ae9ad81daf..e7e1b110289 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -23,7 +23,7 @@ use util::logv; use std::cell::Cell; use std::rt::io; use std::rt::io::Writer; -use std::rt::io::extensions::ReaderUtil; +use std::rt::io::Reader; use std::rt::io::file::FileInfo; use std::os; use std::str; diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 0aab7b743ba..9f75d677136 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -22,7 +22,6 @@ use std::f64; use std::hashmap::HashMap; use std::rt::io; use std::rt::io::Decorator; -use std::rt::io::extensions::ReaderUtil; use std::rt::io::mem::MemWriter; use std::num; use std::str; @@ -843,7 +842,7 @@ impl> Parser { } /// Decodes a json value from an `&mut io::Reader` -pub fn from_reader(mut rdr: &mut io::Reader) -> Result { +pub fn from_reader(rdr: &mut io::Reader) -> Result { let s = str::from_utf8(rdr.read_to_end()); let mut parser = Parser(~s.iter()); parser.parse() diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs index 0020f432114..b530c1b6334 100644 --- a/src/libextra/terminfo/parser/compiled.rs +++ b/src/libextra/terminfo/parser/compiled.rs @@ -16,7 +16,6 @@ use std::{vec, str}; use std::hashmap::HashMap; use std::rt::io; -use std::rt::io::extensions::{ReaderByteConversions, ReaderUtil}; use super::super::TermInfo; // These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable. @@ -161,7 +160,7 @@ pub static stringnames: &'static[&'static str] = &'static[ "cbt", "_", "cr", "cs "box1"]; /// Parse a compiled terminfo entry, using long capability names if `longnames` is true -pub fn parse(mut file: &mut io::Reader, +pub fn parse(file: &mut io::Reader, longnames: bool) -> Result<~TermInfo, ~str> { let bnames; let snames; @@ -178,17 +177,17 @@ pub fn parse(mut file: &mut io::Reader, } // Check magic number - let magic = file.read_le_u16_(); + let magic = file.read_le_u16(); if (magic != 0x011A) { return Err(format!("invalid magic number: expected {:x} but found {:x}", 0x011A, magic as uint)); } - let names_bytes = file.read_le_i16_() as int; - let bools_bytes = file.read_le_i16_() as int; - let numbers_count = file.read_le_i16_() as int; - let string_offsets_count = file.read_le_i16_() as int; - let string_table_bytes = file.read_le_i16_() as int; + let names_bytes = file.read_le_i16() as int; + let bools_bytes = file.read_le_i16() as int; + let numbers_count = file.read_le_i16() as int; + let string_offsets_count = file.read_le_i16() as int; + let string_table_bytes = file.read_le_i16() as int; assert!(names_bytes > 0); @@ -247,7 +246,7 @@ pub fn parse(mut file: &mut io::Reader, let mut numbers_map = HashMap::new(); if numbers_count != 0 { for i in range(0, numbers_count) { - let n = file.read_le_u16_(); + let n = file.read_le_u16(); if n != 0xFFFF { debug!("{}\\#{}", nnames[i], n); numbers_map.insert(nnames[i].to_owned(), n); @@ -262,7 +261,7 @@ pub fn parse(mut file: &mut io::Reader, if string_offsets_count != 0 { let mut string_offsets = vec::with_capacity(10); for _ in range(0, string_offsets_count) { - string_offsets.push(file.read_le_u16_()); + string_offsets.push(file.read_le_u16()); } debug!("offsets: {:?}", string_offsets); diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index bdc8b95ad41..507962c0b1a 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -20,6 +20,7 @@ use std::comm::{PortOne, oneshot}; use std::{os, str, task}; use std::rt::io; use std::rt::io::Writer; +use std::rt::io::Reader; use std::rt::io::Decorator; use std::rt::io::mem::MemWriter; use std::rt::io::file::FileInfo; @@ -481,7 +482,7 @@ impl<'self, T:Send + #[test] fn test() { use std::{os, run}; - use std::rt::io::ReaderUtil; + use std::rt::io::Reader; use std::str::from_utf8_owned; // Create a path to a new file 'filename' in the directory in which diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index d64820332a5..ade5bfe85e4 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -22,7 +22,6 @@ use middle::typeck; use middle; use std::hashmap::{HashMap, HashSet}; -use std::rt::io::extensions::WriterByteConversions; use std::rt::io::{Writer, Seek, Decorator}; use std::rt::io::mem::MemWriter; use std::str; @@ -894,11 +893,11 @@ fn encode_info_for_item(ecx: &EncodeContext, vis: ast::visibility) { let tcx = ecx.tcx; - fn add_to_index_(item: @item, ebml_w: &writer::Encoder, + fn add_to_index(item: @item, ebml_w: &writer::Encoder, index: @mut ~[entry]) { index.push(entry { val: item.id as i64, pos: ebml_w.writer.tell() }); } - let add_to_index: &fn() = || add_to_index_(item, ebml_w, index); + let add_to_index: &fn() = || add_to_index(item, ebml_w, index); debug!("encoding info for item at {}", ecx.tcx.sess.codemap.span_to_str(item.span)); @@ -1411,7 +1410,7 @@ fn encode_index( assert!(elt.pos < 0xffff_ffff); { let wr: &mut MemWriter = ebml_w.writer; - wr.write_be_u32_(elt.pos as u32); + wr.write_be_u32(elt.pos as u32); } write_fn(ebml_w.writer, &elt.val); ebml_w.end_tag(); @@ -1423,7 +1422,7 @@ fn encode_index( for pos in bucket_locs.iter() { assert!(*pos < 0xffff_ffff); let wr: &mut MemWriter = ebml_w.writer; - wr.write_be_u32_(*pos as u32); + wr.write_be_u32(*pos as u32); } ebml_w.end_tag(); ebml_w.end_tag(); @@ -1436,7 +1435,7 @@ fn write_str(writer: @mut MemWriter, s: ~str) { fn write_i64(writer: @mut MemWriter, &n: &i64) { let wr: &mut MemWriter = writer; assert!(n < 0x7fff_ffff); - wr.write_be_u32_(n as u32); + wr.write_be_u32(n as u32); } fn encode_meta_item(ebml_w: &mut writer::Encoder, mi: @MetaItem) { @@ -1591,14 +1590,14 @@ fn encode_lang_items(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) { ebml_w.start_tag(tag_lang_items_item_id); { let wr: &mut MemWriter = ebml_w.writer; - wr.write_be_u32_(i as u32); + wr.write_be_u32(i as u32); } ebml_w.end_tag(); // tag_lang_items_item_id ebml_w.start_tag(tag_lang_items_item_node_id); { let wr: &mut MemWriter = ebml_w.writer; - wr.write_be_u32_(id.node as u32); + wr.write_be_u32(id.node as u32); } ebml_w.end_tag(); // tag_lang_items_item_node_id diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index ce50397d003..6a5ed2f9e6e 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -37,7 +37,7 @@ use middle::lint; use std::comm; use std::rt::io; -use std::rt::io::extensions::ReaderUtil; +use std::rt::io::Reader; use std::num; use std::os; use std::result; diff --git a/src/librustpkg/workcache_support.rs b/src/librustpkg/workcache_support.rs index 3adb33ec2f4..2e4894b854d 100644 --- a/src/librustpkg/workcache_support.rs +++ b/src/librustpkg/workcache_support.rs @@ -9,7 +9,7 @@ // except according to those terms. use std::rt::io; -use std::rt::io::extensions::ReaderUtil; +use std::rt::io::Reader; use std::rt::io::file::FileInfo; use extra::workcache; use sha1::{Digest, Sha1}; diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs index f1e67da815e..b98dade4bf6 100644 --- a/src/libstd/rand/reader.rs +++ b/src/libstd/rand/reader.rs @@ -12,7 +12,6 @@ use option::{Some, None}; use rt::io::Reader; -use rt::io::ReaderByteConversions; use rand::Rng; @@ -51,17 +50,17 @@ impl Rng for ReaderRng { // platform just involves blitting the bytes into the memory // of the u32, similarly for BE on BE; avoiding byteswapping. if cfg!(target_endian="little") { - self.reader.read_le_u32_() + self.reader.read_le_u32() } else { - self.reader.read_be_u32_() + self.reader.read_be_u32() } } fn next_u64(&mut self) -> u64 { // see above for explanation. if cfg!(target_endian="little") { - self.reader.read_le_u64_() + self.reader.read_le_u64() } else { - self.reader.read_be_u64_() + self.reader.read_be_u64() } } fn fill_bytes(&mut self, v: &mut [u8]) { diff --git a/src/libstd/rt/io/extensions.rs b/src/libstd/rt/io/extensions.rs index 4b16f0bc0e1..8bbc4b62eb9 100644 --- a/src/libstd/rt/io/extensions.rs +++ b/src/libstd/rt/io/extensions.rs @@ -13,344 +13,9 @@ // XXX: Not sure how this should be structured // XXX: Iteration should probably be considered separately -use uint; -use int; use iter::Iterator; -use vec; -use rt::io::{Reader, Writer, Decorator}; -use rt::io::{io_error, standard_error, EndOfFile, DEFAULT_BUF_SIZE}; -use option::{Option, Some, None}; -use unstable::finally::Finally; -use cast; - -pub trait ReaderUtil { - - /// Reads a single byte. Returns `None` on EOF. - /// - /// # Failure - /// - /// Raises the same conditions as the `read` method. Returns - /// `None` if the condition is handled. - fn read_byte(&mut self) -> Option; - - /// Reads `len` bytes and appends them to a vector. - /// - /// May push fewer than the requested number of bytes on error - /// or EOF. Returns true on success, false on EOF or error. - /// - /// # Failure - /// - /// Raises the same conditions as `read`. Additionally raises `io_error` - /// on EOF. If `io_error` is handled then `push_bytes` may push less - /// than the requested number of bytes. - fn push_bytes(&mut self, buf: &mut ~[u8], len: uint); - - /// Reads `len` bytes and gives you back a new vector of length `len` - /// - /// # Failure - /// - /// Raises the same conditions as `read`. Additionally raises `io_error` - /// on EOF. If `io_error` is handled then the returned vector may - /// contain less than the requested number of bytes. - fn read_bytes(&mut self, len: uint) -> ~[u8]; - - /// Reads all remaining bytes from the stream. - /// - /// # Failure - /// - /// Raises the same conditions as the `read` method. - fn read_to_end(&mut self) -> ~[u8]; - - /// Create an iterator that reads a single byte on - /// each iteration, until EOF. - /// - /// # Failure - /// - /// Raises the same conditions as the `read` method, for - /// each call to its `.next()` method. - /// Ends the iteration if the condition is handled. - fn bytes(self) -> ByteIterator; - -} - -pub trait ReaderByteConversions { - /// Reads `n` little-endian unsigned integer bytes. - /// - /// `n` must be between 1 and 8, inclusive. - 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. - 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. - 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. - fn read_be_int_n_(&mut self, nbytes: uint) -> i64; - - /// Reads a little-endian unsigned integer. - /// - /// The number of bytes returned is system-dependant. - fn read_le_uint_(&mut self) -> uint; - - /// Reads a little-endian integer. - /// - /// The number of bytes returned is system-dependant. - fn read_le_int_(&mut self) -> int; - - /// Reads a big-endian unsigned integer. - /// - /// The number of bytes returned is system-dependant. - fn read_be_uint_(&mut self) -> uint; - - /// Reads a big-endian integer. - /// - /// The number of bytes returned is system-dependant. - fn read_be_int_(&mut self) -> int; - - /// Reads a big-endian `u64`. - /// - /// `u64`s are 8 bytes long. - fn read_be_u64_(&mut self) -> u64; - - /// Reads a big-endian `u32`. - /// - /// `u32`s are 4 bytes long. - fn read_be_u32_(&mut self) -> u32; - - /// Reads a big-endian `u16`. - /// - /// `u16`s are 2 bytes long. - fn read_be_u16_(&mut self) -> u16; - - /// Reads a big-endian `i64`. - /// - /// `i64`s are 8 bytes long. - fn read_be_i64_(&mut self) -> i64; - - /// Reads a big-endian `i32`. - /// - /// `i32`s are 4 bytes long. - fn read_be_i32_(&mut self) -> i32; - - /// Reads a big-endian `i16`. - /// - /// `i16`s are 2 bytes long. - fn read_be_i16_(&mut self) -> i16; - - /// Reads a big-endian `f64`. - /// - /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers. - fn read_be_f64_(&mut self) -> f64; - - /// Reads a big-endian `f32`. - /// - /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers. - fn read_be_f32_(&mut self) -> f32; - - /// Reads a little-endian `u64`. - /// - /// `u64`s are 8 bytes long. - fn read_le_u64_(&mut self) -> u64; - - /// Reads a little-endian `u32`. - /// - /// `u32`s are 4 bytes long. - fn read_le_u32_(&mut self) -> u32; - - /// Reads a little-endian `u16`. - /// - /// `u16`s are 2 bytes long. - fn read_le_u16_(&mut self) -> u16; - - /// Reads a little-endian `i64`. - /// - /// `i64`s are 8 bytes long. - fn read_le_i64_(&mut self) -> i64; - - /// Reads a little-endian `i32`. - /// - /// `i32`s are 4 bytes long. - fn read_le_i32_(&mut self) -> i32; - - /// Reads a little-endian `i16`. - /// - /// `i16`s are 2 bytes long. - fn read_le_i16_(&mut self) -> i16; - - /// Reads a little-endian `f64`. - /// - /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers. - fn read_le_f64_(&mut self) -> f64; - - /// Reads a little-endian `f32`. - /// - /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers. - fn read_le_f32_(&mut self) -> f32; - - /// Read a u8. - /// - /// `u8`s are 1 byte. - fn read_u8_(&mut self) -> u8; - - /// Read an i8. - /// - /// `i8`s are 1 byte. - fn read_i8_(&mut self) -> i8; - -} - -pub trait WriterByteConversions { - /// Write the result of passing n through `int::to_str_bytes`. - fn write_int_(&mut self, n: int); - - /// Write the result of passing n through `uint::to_str_bytes`. - fn write_uint_(&mut self, n: uint); - - /// Write a little-endian uint (number of bytes depends on system). - fn write_le_uint_(&mut self, n: uint); - - /// Write a little-endian int (number of bytes depends on system). - fn write_le_int_(&mut self, n: int); - - /// Write a big-endian uint (number of bytes depends on system). - fn write_be_uint_(&mut self, n: uint); - - /// Write a big-endian int (number of bytes depends on system). - fn write_be_int_(&mut self, n: int); - - /// Write a big-endian u64 (8 bytes). - fn write_be_u64_(&mut self, n: u64); - - /// Write a big-endian u32 (4 bytes). - fn write_be_u32_(&mut self, n: u32); - - /// Write a big-endian u16 (2 bytes). - fn write_be_u16_(&mut self, n: u16); - - /// Write a big-endian i64 (8 bytes). - fn write_be_i64_(&mut self, n: i64); - - /// Write a big-endian i32 (4 bytes). - fn write_be_i32_(&mut self, n: i32); - - /// Write a big-endian i16 (2 bytes). - fn write_be_i16_(&mut self, n: i16); - - /// Write a big-endian IEEE754 double-precision floating-point (8 bytes). - fn write_be_f64_(&mut self, f: f64); - - /// Write a big-endian IEEE754 single-precision floating-point (4 bytes). - fn write_be_f32_(&mut self, f: f32); - - /// Write a little-endian u64 (8 bytes). - fn write_le_u64_(&mut self, n: u64); - - /// Write a little-endian u32 (4 bytes). - fn write_le_u32_(&mut self, n: u32); - - /// Write a little-endian u16 (2 bytes). - fn write_le_u16_(&mut self, n: u16); - - /// Write a little-endian i64 (8 bytes). - fn write_le_i64_(&mut self, n: i64); - - /// Write a little-endian i32 (4 bytes). - fn write_le_i32_(&mut self, n: i32); - - /// Write a little-endian i16 (2 bytes). - fn write_le_i16_(&mut self, n: i16); - - /// Write a little-endian IEEE754 double-precision floating-point - /// (8 bytes). - fn write_le_f64_(&mut self, f: f64); - - /// Write a little-endian IEEE754 single-precision floating-point - /// (4 bytes). - fn write_le_f32_(&mut self, f: f32); - - /// Write a u8 (1 byte). - fn write_u8_(&mut self, n: u8); - - /// Write a i8 (1 byte). - fn write_i8_(&mut self, n: i8); -} - -impl ReaderUtil for T { - fn read_byte(&mut self) -> Option { - let mut buf = [0]; - match self.read(buf) { - Some(0) => { - debug!("read 0 bytes. trying again"); - self.read_byte() - } - Some(1) => Some(buf[0]), - Some(_) => unreachable!(), - None => None - } - } - - fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) { - unsafe { - let start_len = buf.len(); - let mut total_read = 0; - - buf.reserve_additional(len); - vec::raw::set_len(buf, start_len + len); - - do (|| { - while total_read < len { - let len = buf.len(); - let slice = buf.mut_slice(start_len + total_read, len); - match self.read(slice) { - Some(nread) => { - total_read += nread; - } - None => { - io_error::cond.raise(standard_error(EndOfFile)); - break; - } - } - } - }).finally { - vec::raw::set_len(buf, start_len + total_read); - } - } - } - - fn read_bytes(&mut self, len: uint) -> ~[u8] { - let mut buf = vec::with_capacity(len); - self.push_bytes(&mut buf, len); - return buf; - } - - fn read_to_end(&mut self) -> ~[u8] { - let mut buf = vec::with_capacity(DEFAULT_BUF_SIZE); - let mut keep_reading = true; - do io_error::cond.trap(|e| { - if e.kind == EndOfFile { - keep_reading = false; - } else { - io_error::cond.raise(e) - } - }).inside { - while keep_reading { - self.push_bytes(&mut buf, DEFAULT_BUF_SIZE) - } - } - return buf; - } - - fn bytes(self) -> ByteIterator { - ByteIterator{reader: self} - } -} +use option::Option; +use rt::io::{Reader, Decorator}; /// An iterator that reads a single byte on each iteration, /// until `.read_byte()` returns `None`. @@ -370,6 +35,12 @@ pub struct ByteIterator { priv reader: T, } +impl ByteIterator { + pub fn new(r: R) -> ByteIterator { + ByteIterator { reader: r } + } +} + impl Decorator for ByteIterator { fn inner(self) -> R { self.reader } fn inner_ref<'a>(&'a self) -> &'a R { &self.reader } @@ -383,256 +54,6 @@ impl<'self, R: Reader> Iterator for ByteIterator { } } -impl ReaderByteConversions for T { - fn read_le_uint_n_(&mut self, nbytes: uint) -> u64 { - assert!(nbytes > 0 && nbytes <= 8); - - let mut val = 0u64; - let mut pos = 0; - let mut i = nbytes; - while i > 0 { - val += (self.read_u8_() as u64) << pos; - pos += 8; - i -= 1; - } - val - } - - fn read_le_int_n_(&mut self, nbytes: uint) -> i64 { - extend_sign(self.read_le_uint_n_(nbytes), nbytes) - } - - fn read_be_uint_n_(&mut self, nbytes: uint) -> u64 { - assert!(nbytes > 0 && nbytes <= 8); - - let mut val = 0u64; - let mut i = nbytes; - while i > 0 { - i -= 1; - val += (self.read_u8_() as u64) << i * 8; - } - val - } - - fn read_be_int_n_(&mut self, nbytes: uint) -> i64 { - extend_sign(self.read_be_uint_n_(nbytes), nbytes) - } - - fn read_le_uint_(&mut self) -> uint { - self.read_le_uint_n_(uint::bytes) as uint - } - - fn read_le_int_(&mut self) -> int { - self.read_le_int_n_(int::bytes) as int - } - - fn read_be_uint_(&mut self) -> uint { - self.read_be_uint_n_(uint::bytes) as uint - } - - fn read_be_int_(&mut self) -> int { - self.read_be_int_n_(int::bytes) as int - } - - fn read_be_u64_(&mut self) -> u64 { - self.read_be_uint_n_(8) as u64 - } - - fn read_be_u32_(&mut self) -> u32 { - self.read_be_uint_n_(4) as u32 - } - - fn read_be_u16_(&mut self) -> u16 { - self.read_be_uint_n_(2) as u16 - } - - fn read_be_i64_(&mut self) -> i64 { - self.read_be_int_n_(8) as i64 - } - - fn read_be_i32_(&mut self) -> i32 { - self.read_be_int_n_(4) as i32 - } - - fn read_be_i16_(&mut self) -> i16 { - self.read_be_int_n_(2) as i16 - } - - fn read_be_f64_(&mut self) -> f64 { - unsafe { - cast::transmute::(self.read_be_u64_()) - } - } - - fn read_be_f32_(&mut self) -> f32 { - unsafe { - cast::transmute::(self.read_be_u32_()) - } - } - - fn read_le_u64_(&mut self) -> u64 { - self.read_le_uint_n_(8) as u64 - } - - fn read_le_u32_(&mut self) -> u32 { - self.read_le_uint_n_(4) as u32 - } - - fn read_le_u16_(&mut self) -> u16 { - self.read_le_uint_n_(2) as u16 - } - - fn read_le_i64_(&mut self) -> i64 { - self.read_le_int_n_(8) as i64 - } - - fn read_le_i32_(&mut self) -> i32 { - self.read_le_int_n_(4) as i32 - } - - fn read_le_i16_(&mut self) -> i16 { - self.read_le_int_n_(2) as i16 - } - - fn read_le_f64_(&mut self) -> f64 { - unsafe { - cast::transmute::(self.read_le_u64_()) - } - } - - fn read_le_f32_(&mut self) -> f32 { - unsafe { - cast::transmute::(self.read_le_u32_()) - } - } - - fn read_u8_(&mut self) -> u8 { - match self.read_byte() { - Some(b) => b as u8, - None => 0 - } - } - - fn read_i8_(&mut self) -> i8 { - match self.read_byte() { - Some(b) => b as i8, - None => 0 - } - } - -} - -impl WriterByteConversions for T { - fn write_int_(&mut self, n: int) { - int::to_str_bytes(n, 10u, |bytes| self.write(bytes)) - } - - fn write_uint_(&mut self, n: uint) { - uint::to_str_bytes(n, 10u, |bytes| self.write(bytes)) - } - - fn write_le_uint_(&mut self, n: uint) { - u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v)) - } - - fn write_le_int_(&mut self, n: int) { - u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v)) - } - - fn write_be_uint_(&mut self, n: uint) { - u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v)) - } - - fn write_be_int_(&mut self, n: int) { - u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v)) - } - - fn write_be_u64_(&mut self, n: u64) { - u64_to_be_bytes(n, 8u, |v| self.write(v)) - } - - fn write_be_u32_(&mut self, n: u32) { - u64_to_be_bytes(n as u64, 4u, |v| self.write(v)) - } - - fn write_be_u16_(&mut self, n: u16) { - u64_to_be_bytes(n as u64, 2u, |v| self.write(v)) - } - - fn write_be_i64_(&mut self, n: i64) { - u64_to_be_bytes(n as u64, 8u, |v| self.write(v)) - } - - fn write_be_i32_(&mut self, n: i32) { - u64_to_be_bytes(n as u64, 4u, |v| self.write(v)) - } - - fn write_be_i16_(&mut self, n: i16) { - u64_to_be_bytes(n as u64, 2u, |v| self.write(v)) - } - - fn write_be_f64_(&mut self, f: f64) { - unsafe { - self.write_be_u64_(cast::transmute(f)) - } - } - - fn write_be_f32_(&mut self, f: f32) { - unsafe { - self.write_be_u32_(cast::transmute(f)) - } - } - - fn write_le_u64_(&mut self, n: u64) { - u64_to_le_bytes(n, 8u, |v| self.write(v)) - } - - fn write_le_u32_(&mut self, n: u32) { - u64_to_le_bytes(n as u64, 4u, |v| self.write(v)) - } - - fn write_le_u16_(&mut self, n: u16) { - u64_to_le_bytes(n as u64, 2u, |v| self.write(v)) - } - - fn write_le_i64_(&mut self, n: i64) { - u64_to_le_bytes(n as u64, 8u, |v| self.write(v)) - } - - fn write_le_i32_(&mut self, n: i32) { - u64_to_le_bytes(n as u64, 4u, |v| self.write(v)) - } - - fn write_le_i16_(&mut self, n: i16) { - u64_to_le_bytes(n as u64, 2u, |v| self.write(v)) - } - - fn write_le_f64_(&mut self, f: f64) { - unsafe { - self.write_le_u64_(cast::transmute(f)) - } - } - - fn write_le_f32_(&mut self, f: f32) { - unsafe { - self.write_le_u32_(cast::transmute(f)) - } - } - - fn write_u8_(&mut self, n: u8) { - self.write([n]) - } - - fn write_i8_(&mut self, n: i8) { - self.write([n as u8]) - } -} - -fn extend_sign(val: u64, nbytes: uint) -> i64 { - let shift = (8 - nbytes) * 8; - (val << shift) as i64 >> shift -} - pub fn u64_to_le_bytes(n: u64, size: uint, f: &fn(v: &[u8]) -> T) -> T { assert!(size <= 8u); @@ -717,7 +138,6 @@ pub fn u64_from_be_bytes(data: &[u8], #[cfg(test)] mod test { - use super::ReaderUtil; use option::{Some, None}; use cell::Cell; use rt::io::mem::{MemReader, MemWriter}; @@ -999,12 +419,12 @@ mod test { let mut writer = MemWriter::new(); for i in uints.iter() { - writer.write_le_u64_(*i); + writer.write_le_u64(*i); } let mut reader = MemReader::new(writer.inner()); for i in uints.iter() { - assert!(reader.read_le_u64_() == *i); + assert!(reader.read_le_u64() == *i); } } @@ -1015,12 +435,12 @@ mod test { let mut writer = MemWriter::new(); for i in uints.iter() { - writer.write_be_u64_(*i); + writer.write_be_u64(*i); } let mut reader = MemReader::new(writer.inner()); for i in uints.iter() { - assert!(reader.read_be_u64_() == *i); + assert!(reader.read_be_u64() == *i); } } @@ -1030,14 +450,14 @@ mod test { let mut writer = MemWriter::new(); for i in ints.iter() { - writer.write_be_i32_(*i); + writer.write_be_i32(*i); } let mut reader = MemReader::new(writer.inner()); for i in ints.iter() { // this tests that the sign extension is working // (comparing the values as i32 would not test this) - assert!(reader.read_be_int_n_(4) == *i as i64); + assert!(reader.read_be_int_n(4) == *i as i64); } } @@ -1050,7 +470,7 @@ mod test { writer.write(buf); let mut reader = MemReader::new(writer.inner()); - let f = reader.read_be_f32_(); + let f = reader.read_be_f32(); assert!(f == 8.1250); } @@ -1059,12 +479,12 @@ mod test { let f:f32 = 8.1250; let mut writer = MemWriter::new(); - writer.write_be_f32_(f); - writer.write_le_f32_(f); + writer.write_be_f32(f); + writer.write_le_f32(f); let mut reader = MemReader::new(writer.inner()); - assert!(reader.read_be_f32_() == 8.1250); - assert!(reader.read_le_f32_() == 8.1250); + assert!(reader.read_be_f32() == 8.1250); + assert!(reader.read_le_f32() == 8.1250); } } diff --git a/src/libstd/rt/io/mod.rs b/src/libstd/rt/io/mod.rs index dc69c8486da..5eba3b2b801 100644 --- a/src/libstd/rt/io/mod.rs +++ b/src/libstd/rt/io/mod.rs @@ -242,10 +242,15 @@ Out of scope */ -use prelude::*; -use to_str::ToStr; -use str::{StrSlice, OwnedStr}; +use cast; +use int; use path::Path; +use prelude::*; +use str::{StrSlice, OwnedStr}; +use to_str::ToStr; +use uint; +use unstable::finally::Finally; +use vec; // Reexports pub use self::stdio::stdin; @@ -263,11 +268,6 @@ pub use self::net::udp::UdpStream; pub use self::pipe::PipeStream; pub use self::process::Process; -// Some extension traits that all Readers and Writers get. -pub use self::extensions::ReaderUtil; -pub use self::extensions::ReaderByteConversions; -pub use self::extensions::WriterByteConversions; - /// Synchronous, non-blocking file I/O. pub mod file; @@ -422,6 +422,9 @@ pub fn ignore_io_error(cb: &fn() -> T) -> T { } pub trait Reader { + + // Only two methods which need to get implemented for this trait + /// Read bytes, up to the length of `buf` and place them in `buf`. /// Returns the number of bytes read. The number of bytes read my /// be less than the number requested, even 0. Returns `None` on EOF. @@ -459,6 +462,329 @@ pub trait Reader { /// /// Returns `true` on failure. fn eof(&mut self) -> bool; + + // Convenient helper methods based on the above methods + + /// Reads a single byte. Returns `None` on EOF. + /// + /// # Failure + /// + /// Raises the same conditions as the `read` method. Returns + /// `None` if the condition is handled. + fn read_byte(&mut self) -> Option { + let mut buf = [0]; + match self.read(buf) { + Some(0) => { + debug!("read 0 bytes. trying again"); + self.read_byte() + } + Some(1) => Some(buf[0]), + Some(_) => unreachable!(), + None => None + } + } + + /// Reads `len` bytes and appends them to a vector. + /// + /// May push fewer than the requested number of bytes on error + /// or EOF. Returns true on success, false on EOF or error. + /// + /// # Failure + /// + /// Raises the same conditions as `read`. Additionally raises `io_error` + /// on EOF. If `io_error` is handled then `push_bytes` may push less + /// than the requested number of bytes. + fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) { + unsafe { + let start_len = buf.len(); + let mut total_read = 0; + + buf.reserve_additional(len); + vec::raw::set_len(buf, start_len + len); + + do (|| { + while total_read < len { + let len = buf.len(); + let slice = buf.mut_slice(start_len + total_read, len); + match self.read(slice) { + Some(nread) => { + total_read += nread; + } + None => { + io_error::cond.raise(standard_error(EndOfFile)); + break; + } + } + } + }).finally { + vec::raw::set_len(buf, start_len + total_read); + } + } + } + + /// Reads `len` bytes and gives you back a new vector of length `len` + /// + /// # Failure + /// + /// Raises the same conditions as `read`. Additionally raises `io_error` + /// on EOF. If `io_error` is handled then the returned vector may + /// contain less than the requested number of bytes. + fn read_bytes(&mut self, len: uint) -> ~[u8] { + let mut buf = vec::with_capacity(len); + self.push_bytes(&mut buf, len); + return buf; + } + + /// Reads all remaining bytes from the stream. + /// + /// # Failure + /// + /// Raises the same conditions as the `read` method. + fn read_to_end(&mut self) -> ~[u8] { + let mut buf = vec::with_capacity(DEFAULT_BUF_SIZE); + let mut keep_reading = true; + do io_error::cond.trap(|e| { + if e.kind == EndOfFile { + keep_reading = false; + } else { + io_error::cond.raise(e) + } + }).inside { + while keep_reading { + self.push_bytes(&mut buf, DEFAULT_BUF_SIZE) + } + } + return buf; + } + + /// Create an iterator that reads a single byte on + /// each iteration, until EOF. + /// + /// # Failure + /// + /// Raises the same conditions as the `read` method, for + /// each call to its `.next()` method. + /// Ends the iteration if the condition is handled. + fn bytes(self) -> extensions::ByteIterator { + extensions::ByteIterator::new(self) + } + + // Byte conversion helpers + + /// Reads `n` little-endian unsigned integer bytes. + /// + /// `n` must be between 1 and 8, inclusive. + fn read_le_uint_n(&mut self, nbytes: uint) -> u64 { + assert!(nbytes > 0 && nbytes <= 8); + + let mut val = 0u64; + let mut pos = 0; + let mut i = nbytes; + while i > 0 { + val += (self.read_u8() as u64) << pos; + pos += 8; + i -= 1; + } + val + } + + /// Reads `n` little-endian signed integer bytes. + /// + /// `n` must be between 1 and 8, inclusive. + fn read_le_int_n(&mut self, nbytes: uint) -> i64 { + extend_sign(self.read_le_uint_n(nbytes), nbytes) + } + + /// Reads `n` big-endian unsigned integer bytes. + /// + /// `n` must be between 1 and 8, inclusive. + fn read_be_uint_n(&mut self, nbytes: uint) -> u64 { + assert!(nbytes > 0 && nbytes <= 8); + + let mut val = 0u64; + let mut i = nbytes; + while i > 0 { + i -= 1; + val += (self.read_u8() as u64) << i * 8; + } + val + } + + /// Reads `n` big-endian signed integer bytes. + /// + /// `n` must be between 1 and 8, inclusive. + fn read_be_int_n(&mut self, nbytes: uint) -> i64 { + extend_sign(self.read_be_uint_n(nbytes), nbytes) + } + + /// Reads a little-endian unsigned integer. + /// + /// The number of bytes returned is system-dependant. + fn read_le_uint(&mut self) -> uint { + self.read_le_uint_n(uint::bytes) as uint + } + + /// Reads a little-endian integer. + /// + /// The number of bytes returned is system-dependant. + fn read_le_int(&mut self) -> int { + self.read_le_int_n(int::bytes) as int + } + + /// Reads a big-endian unsigned integer. + /// + /// The number of bytes returned is system-dependant. + fn read_be_uint(&mut self) -> uint { + self.read_be_uint_n(uint::bytes) as uint + } + + /// Reads a big-endian integer. + /// + /// The number of bytes returned is system-dependant. + fn read_be_int(&mut self) -> int { + self.read_be_int_n(int::bytes) as int + } + + /// Reads a big-endian `u64`. + /// + /// `u64`s are 8 bytes long. + fn read_be_u64(&mut self) -> u64 { + self.read_be_uint_n(8) as u64 + } + + /// Reads a big-endian `u32`. + /// + /// `u32`s are 4 bytes long. + fn read_be_u32(&mut self) -> u32 { + self.read_be_uint_n(4) as u32 + } + + /// Reads a big-endian `u16`. + /// + /// `u16`s are 2 bytes long. + fn read_be_u16(&mut self) -> u16 { + self.read_be_uint_n(2) as u16 + } + + /// Reads a big-endian `i64`. + /// + /// `i64`s are 8 bytes long. + fn read_be_i64(&mut self) -> i64 { + self.read_be_int_n(8) as i64 + } + + /// Reads a big-endian `i32`. + /// + /// `i32`s are 4 bytes long. + fn read_be_i32(&mut self) -> i32 { + self.read_be_int_n(4) as i32 + } + + /// Reads a big-endian `i16`. + /// + /// `i16`s are 2 bytes long. + fn read_be_i16(&mut self) -> i16 { + self.read_be_int_n(2) as i16 + } + + /// Reads a big-endian `f64`. + /// + /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers. + fn read_be_f64(&mut self) -> f64 { + unsafe { + cast::transmute::(self.read_be_u64()) + } + } + + /// Reads a big-endian `f32`. + /// + /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers. + fn read_be_f32(&mut self) -> f32 { + unsafe { + cast::transmute::(self.read_be_u32()) + } + } + + /// Reads a little-endian `u64`. + /// + /// `u64`s are 8 bytes long. + fn read_le_u64(&mut self) -> u64 { + self.read_le_uint_n(8) as u64 + } + + /// Reads a little-endian `u32`. + /// + /// `u32`s are 4 bytes long. + fn read_le_u32(&mut self) -> u32 { + self.read_le_uint_n(4) as u32 + } + + /// Reads a little-endian `u16`. + /// + /// `u16`s are 2 bytes long. + fn read_le_u16(&mut self) -> u16 { + self.read_le_uint_n(2) as u16 + } + + /// Reads a little-endian `i64`. + /// + /// `i64`s are 8 bytes long. + fn read_le_i64(&mut self) -> i64 { + self.read_le_int_n(8) as i64 + } + + /// Reads a little-endian `i32`. + /// + /// `i32`s are 4 bytes long. + fn read_le_i32(&mut self) -> i32 { + self.read_le_int_n(4) as i32 + } + + /// Reads a little-endian `i16`. + /// + /// `i16`s are 2 bytes long. + fn read_le_i16(&mut self) -> i16 { + self.read_le_int_n(2) as i16 + } + + /// Reads a little-endian `f64`. + /// + /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers. + fn read_le_f64(&mut self) -> f64 { + unsafe { + cast::transmute::(self.read_le_u64()) + } + } + + /// Reads a little-endian `f32`. + /// + /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers. + fn read_le_f32(&mut self) -> f32 { + unsafe { + cast::transmute::(self.read_le_u32()) + } + } + + /// Read a u8. + /// + /// `u8`s are 1 byte. + fn read_u8(&mut self) -> u8 { + match self.read_byte() { + Some(b) => b as u8, + None => 0 + } + } + + /// Read an i8. + /// + /// `i8`s are 1 byte. + fn read_i8(&mut self) -> i8 { + match self.read_byte() { + Some(b) => b as i8, + None => 0 + } + } + } impl Reader for ~Reader { @@ -471,6 +797,11 @@ impl<'self> Reader for &'self mut Reader { fn eof(&mut self) -> bool { self.eof() } } +fn extend_sign(val: u64, nbytes: uint) -> i64 { + let shift = (8 - nbytes) * 8; + (val << shift) as i64 >> shift +} + pub trait Writer { /// Write the given buffer /// @@ -481,6 +812,136 @@ pub trait Writer { /// Flush output fn flush(&mut self); + + /// Write the result of passing n through `int::to_str_bytes`. + fn write_int(&mut self, n: int) { + int::to_str_bytes(n, 10u, |bytes| self.write(bytes)) + } + + /// Write the result of passing n through `uint::to_str_bytes`. + fn write_uint(&mut self, n: uint) { + uint::to_str_bytes(n, 10u, |bytes| self.write(bytes)) + } + + /// Write a little-endian uint (number of bytes depends on system). + fn write_le_uint(&mut self, n: uint) { + extensions::u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v)) + } + + /// Write a little-endian int (number of bytes depends on system). + fn write_le_int(&mut self, n: int) { + extensions::u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v)) + } + + /// Write a big-endian uint (number of bytes depends on system). + fn write_be_uint(&mut self, n: uint) { + extensions::u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v)) + } + + /// Write a big-endian int (number of bytes depends on system). + fn write_be_int(&mut self, n: int) { + extensions::u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v)) + } + + /// Write a big-endian u64 (8 bytes). + fn write_be_u64(&mut self, n: u64) { + extensions::u64_to_be_bytes(n, 8u, |v| self.write(v)) + } + + /// Write a big-endian u32 (4 bytes). + fn write_be_u32(&mut self, n: u32) { + extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v)) + } + + /// Write a big-endian u16 (2 bytes). + fn write_be_u16(&mut self, n: u16) { + extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v)) + } + + /// Write a big-endian i64 (8 bytes). + fn write_be_i64(&mut self, n: i64) { + extensions::u64_to_be_bytes(n as u64, 8u, |v| self.write(v)) + } + + /// Write a big-endian i32 (4 bytes). + fn write_be_i32(&mut self, n: i32) { + extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v)) + } + + /// Write a big-endian i16 (2 bytes). + fn write_be_i16(&mut self, n: i16) { + extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v)) + } + + /// Write a big-endian IEEE754 double-precision floating-point (8 bytes). + fn write_be_f64(&mut self, f: f64) { + unsafe { + self.write_be_u64(cast::transmute(f)) + } + } + + /// Write a big-endian IEEE754 single-precision floating-point (4 bytes). + fn write_be_f32(&mut self, f: f32) { + unsafe { + self.write_be_u32(cast::transmute(f)) + } + } + + /// Write a little-endian u64 (8 bytes). + fn write_le_u64(&mut self, n: u64) { + extensions::u64_to_le_bytes(n, 8u, |v| self.write(v)) + } + + /// Write a little-endian u32 (4 bytes). + fn write_le_u32(&mut self, n: u32) { + extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v)) + } + + /// Write a little-endian u16 (2 bytes). + fn write_le_u16(&mut self, n: u16) { + extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v)) + } + + /// Write a little-endian i64 (8 bytes). + fn write_le_i64(&mut self, n: i64) { + extensions::u64_to_le_bytes(n as u64, 8u, |v| self.write(v)) + } + + /// Write a little-endian i32 (4 bytes). + fn write_le_i32(&mut self, n: i32) { + extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v)) + } + + /// Write a little-endian i16 (2 bytes). + fn write_le_i16(&mut self, n: i16) { + extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v)) + } + + /// Write a little-endian IEEE754 double-precision floating-point + /// (8 bytes). + fn write_le_f64(&mut self, f: f64) { + unsafe { + self.write_le_u64(cast::transmute(f)) + } + } + + /// Write a little-endian IEEE754 single-precision floating-point + /// (4 bytes). + fn write_le_f32(&mut self, f: f32) { + unsafe { + self.write_le_u32(cast::transmute(f)) + } + } + + /// Write a u8 (1 byte). + fn write_u8(&mut self, n: u8) { + self.write([n]) + } + + /// Write a i8 (1 byte). + fn write_i8(&mut self, n: i8) { + self.write([n as u8]) + } } impl Writer for ~Writer { diff --git a/src/libstd/run.rs b/src/libstd/run.rs index 6e7d681d40a..973e866e335 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -19,7 +19,7 @@ use libc; use prelude::*; use rt::io::process; use rt::io; -use rt::io::extensions::ReaderUtil; +use rt::io::Reader; use task; /** diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 119a74cccd6..fda6f782af4 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -20,7 +20,7 @@ use parse::token::{get_ident_interner}; use print::pprust; use std::rt::io; -use std::rt::io::extensions::ReaderUtil; +use std::rt::io::Reader; use std::rt::io::file::FileInfo; use std::str; diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index e9e6eb872c8..38fd65836aa 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -19,7 +19,6 @@ use parse::token; use parse::token::{get_ident_interner}; use std::rt::io; -use std::rt::io::extensions::ReaderUtil; use std::str; use std::uint; @@ -347,7 +346,7 @@ pub struct lit { pub fn gather_comments_and_literals(span_diagnostic: @mut diagnostic::span_handler, path: @str, - mut srdr: &mut io::Reader) + srdr: &mut io::Reader) -> (~[cmnt], ~[lit]) { let src = str::from_utf8(srdr.read_to_end()).to_managed(); let cm = CodeMap::new(); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 0de571978a0..003bc006ebe 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -21,7 +21,7 @@ use parse::parser::Parser; use std::path::Path; use std::rt::io; -use std::rt::io::extensions::ReaderUtil; +use std::rt::io::Reader; use std::rt::io::file::FileInfo; use std::str;