diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2013-10-21 23:06:12 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2013-10-24 14:22:34 -0700 |
| commit | 6bb1df92511e7ecafe0554b01410f4e68d7bc66f (patch) | |
| tree | 77e1bd3a3d541add698d44120bc8293c48fadc45 /src/libstd | |
| parent | c4907cfd14f9afa1fc26e2fdddf128f834fe5ce5 (diff) | |
| download | rust-6bb1df92511e7ecafe0554b01410f4e68d7bc66f.tar.gz rust-6bb1df92511e7ecafe0554b01410f4e68d7bc66f.zip | |
Remove std::io once and for all!
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/io.rs | 1817 | ||||
| -rw-r--r-- | src/libstd/prelude.rs | 1 | ||||
| -rw-r--r-- | src/libstd/rt/io/extensions.rs | 83 | ||||
| -rw-r--r-- | src/libstd/std.rs | 1 | ||||
| -rw-r--r-- | src/libstd/to_bytes.rs | 7 |
5 files changed, 86 insertions, 1823 deletions
diff --git a/src/libstd/io.rs b/src/libstd/io.rs deleted file mode 100644 index 2ffe654d3bd..00000000000 --- a/src/libstd/io.rs +++ /dev/null @@ -1,1817 +0,0 @@ -// Copyright 2012 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. - -/*! - -The `io` module contains basic input and output routines. - -A quick summary: - -## `Reader` and `Writer` traits - -These traits define the minimal set of methods that anything that can do -input and output should implement. - -## `ReaderUtil` and `WriterUtil` traits - -Richer methods that allow you to do more. `Reader` only lets you read a certain -number of bytes into a buffer, while `ReaderUtil` allows you to read a whole -line, for example. - -Generally, these richer methods are probably the ones you want to actually -use in day-to-day Rust. - -Furthermore, because there is an implementation of `ReaderUtil` for -`<T: Reader>`, when your input or output code implements `Reader`, you get -all of these methods for free. - -## `print` and `println` - -These very useful functions are defined here. You generally don't need to -import them, though, as the prelude already does. - -## `stdin`, `stdout`, and `stderr` - -These functions return references to the classic three file descriptors. They -implement `Reader` and `Writer`, where appropriate. - -*/ - -#[allow(missing_doc)]; - -use cast; -use cast::transmute; -use clone::Clone; -use c_str::ToCStr; -use container::Container; -use int; -use iter::Iterator; -use libc::consts::os::posix88::*; -use libc::{c_int, c_void, size_t}; -use libc; -use num; -use ops::Drop; -use option::{Some, None}; -use os; -use path::{Path,GenericPath}; -use ptr; -use result::{Result, Ok, Err}; -use str::{StrSlice, OwnedStr}; -use str; -use uint; -use vec::{MutableVector, ImmutableVector, OwnedVector, OwnedCopyableVector, CopyableVector}; -use vec; - -#[cfg(stage0)] -pub use rt::io::stdio::{print, println}; - -#[allow(non_camel_case_types)] // not sure what to do about this -type fd_t = c_int; - -mod rustrt { - use libc; - - #[link_name = "rustrt"] - extern { - pub fn rust_get_stdin() -> *libc::FILE; - pub fn rust_get_stdout() -> *libc::FILE; - pub fn rust_get_stderr() -> *libc::FILE; - } -} - -// Reading - -// FIXME (#2004): This is all buffered. We might need an unbuffered variant -// as well -/** -* The SeekStyle enum describes the relationship between the position -* we'd like to seek to from our current position. It's used as an argument -* to the `seek` method defined on the `Reader` trait. -* -* There are three seek styles: -* -* 1. `SeekSet` means that the new position should become our position. -* 2. `SeekCur` means that we should seek from the current position. -* 3. `SeekEnd` means that we should seek from the end. -* -* # Examples -* -* None right now. -*/ -pub enum SeekStyle { SeekSet, SeekEnd, SeekCur, } - - -/** -* The core Reader trait. All readers must implement this trait. -* -* # Examples -* -* None right now. -*/ -pub trait Reader { - // FIXME (#2004): Seekable really should be orthogonal. - - // FIXME (#2982): This should probably return an error. - /** - * Reads bytes and puts them into `bytes`, advancing the cursor. Returns the - * number of bytes read. - * - * The number of bytes to be read is `len` or the end of the file, - * whichever comes first. - * - * The buffer must be at least `len` bytes long. - * - * `read` is conceptually similar to C's `fread` function. - * - * # Examples - * - * None right now. - */ - fn read(&self, bytes: &mut [u8], len: uint) -> uint; - - /** - * Reads a single byte, advancing the cursor. - * - * In the case of an EOF or an error, returns a negative value. - * - * `read_byte` is conceptually similar to C's `getc` function. - * - * # Examples - * - * None right now. - */ - fn read_byte(&self) -> int; - - /** - * Returns a boolean value: are we currently at EOF? - * - * Note that stream position may be already at the end-of-file point, - * but `eof` returns false until an attempt to read at that position. - * - * `eof` is conceptually similar to C's `feof` function. - * - * # Examples - * - * None right now. - */ - fn eof(&self) -> bool; - - /** - * Seek to a given `position` in the stream. - * - * Takes an optional SeekStyle, which affects how we seek from the - * position. See `SeekStyle` docs for more details. - * - * `seek` is conceptually similar to C's `fseek` function. - * - * # Examples - * - * None right now. - */ - fn seek(&self, position: int, style: SeekStyle); - - /** - * Returns the current position within the stream. - * - * `tell` is conceptually similar to C's `ftell` function. - * - * # Examples - * - * None right now. - */ - fn tell(&self) -> uint; -} - -impl Reader for @Reader { - fn read(&self, bytes: &mut [u8], len: uint) -> uint { - self.read(bytes, len) - } - fn read_byte(&self) -> int { - self.read_byte() - } - fn eof(&self) -> bool { - self.eof() - } - fn seek(&self, position: int, style: SeekStyle) { - self.seek(position, style) - } - fn tell(&self) -> uint { - self.tell() - } -} - -/** -* The `ReaderUtil` trait is a home for many of the utility functions -* a particular Reader should implement. -* -* The default `Reader` trait is focused entirely on bytes. `ReaderUtil` is based -* on higher-level concepts like 'chars' and 'lines.' -* -* # Examples: -* -* None right now. -*/ -pub trait ReaderUtil { - - /** - * Reads `len` number of bytes, and gives you a new vector back. - * - * # Examples - * - * None right now. - */ - fn read_bytes(&self, len: uint) -> ~[u8]; - - /** - * Reads up until a specific byte is seen or EOF. - * - * The `include` parameter specifies if the character should be included - * in the returned string. - * - * # Examples - * - * None right now. - */ - fn read_until(&self, c: u8, include: bool) -> ~str; - - /** - * Reads up until the first '\n' or EOF. - * - * The '\n' is not included in the result. - * - * # Examples - * - * None right now. - */ - fn read_line(&self) -> ~str; - - /** - * Reads `n` chars. - * - * Assumes that those chars are UTF-8 encoded. - * - * The '\n' is not included in the result. - * - * # Examples - * - * None right now. - */ - fn read_chars(&self, n: uint) -> ~[char]; - - /** - * Reads a single UTF-8 encoded char. - * - * # Examples - * - * None right now. - */ - fn read_char(&self) -> char; - - /** - * Reads up until the first null byte or EOF. - * - * The null byte is not returned. - * - * # Examples - * - * None right now. - */ - fn read_c_str(&self) -> ~str; - - /** - * Reads all remaining data in the stream. - * - * # Examples - * - * None right now. - */ - fn read_whole_stream(&self) -> ~[u8]; - - /** - * Iterate over every byte until EOF or the iterator breaks. - * - * # Examples - * - * None right now. - */ - fn each_byte(&self, it: &fn(int) -> bool) -> bool; - - /** - * Iterate over every char until EOF or the iterator breaks. - * - * # Examples - * - * None right now. - */ - fn each_char(&self, it: &fn(char) -> bool) -> bool; - - /** - * Iterate over every line until EOF or the iterator breaks. - * - * # Examples - * - * None right now. - */ - fn each_line(&self, it: &fn(&str) -> bool) -> bool; - - /** - * Reads all of the lines in the stream. - * - * Returns a vector of those lines. - * - * # Examples - * - * None right now. - */ - fn read_lines(&self) -> ~[~str]; - - /** - * Reads `n` little-endian unsigned integer bytes. - * - * `n` must be between 1 and 8, inclusive. - * - * # Examples - * - * None right now. - */ - fn read_le_uint_n(&self, nbytes: uint) -> u64; - - /** - * Reads `n` little-endian signed integer bytes. - * - * `n` must be between 1 and 8, inclusive. - * - * # Examples - * - * None right now. - */ - fn read_le_int_n(&self, nbytes: uint) -> i64; - - /** - * Reads `n` big-endian unsigned integer bytes. - * - * `n` must be between 1 and 8, inclusive. - * - * # Examples - * - * None right now. - */ - fn read_be_uint_n(&self, nbytes: uint) -> u64; - - /** - * Reads `n` big-endian signed integer bytes. - * - * `n` must be between 1 and 8, inclusive. - * - * # Examples - * - * None right now. - */ - fn read_be_int_n(&self, nbytes: uint) -> i64; - - /** - * Reads a little-endian unsigned integer. - * - * The number of bytes returned is system-dependant. - * - * # Examples - * - * None right now. - */ - fn read_le_uint(&self) -> uint; - - /** - * Reads a little-endian integer. - * - * The number of bytes returned is system-dependant. - * - * # Examples - * - * None right now. - */ - fn read_le_int(&self) -> int; - - /** - * Reads a big-endian unsigned integer. - * - * The number of bytes returned is system-dependant. - * - * # Examples - * - * None right now. - */ - fn read_be_uint(&self) -> uint; - - /** - * Reads a big-endian integer. - * - * The number of bytes returned is system-dependant. - * - * # Examples - * - * None right now. - */ - fn read_be_int(&self) -> int; - - /** - * Reads a big-endian `u64`. - * - * `u64`s are 8 bytes long. - * - * # Examples - * - * None right now. - */ - fn read_be_u64(&self) -> u64; - - /** - * Reads a big-endian `u32`. - * - * `u32`s are 4 bytes long. - * - * # Examples - * - * None right now. - */ - fn read_be_u32(&self) -> u32; - - /** - * Reads a big-endian `u16`. - * - * `u16`s are 2 bytes long. - * - * # Examples - * - * None right now. - */ - fn read_be_u16(&self) -> u16; - - /** - * Reads a big-endian `i64`. - * - * `i64`s are 8 bytes long. - * - * # Examples - * - * None right now. - */ - fn read_be_i64(&self) -> i64; - - /** - * Reads a big-endian `i32`. - * - * `i32`s are 4 bytes long. - * - * # Examples - * - * None right now. - */ - fn read_be_i32(&self) -> i32; - - /** - * Reads a big-endian `i16`. - * - * `i16`s are 2 bytes long. - * - * # Examples - * - * None right now. - */ - fn read_be_i16(&self) -> i16; - - /** - * Reads a big-endian `f64`. - * - * `f64`s are 8 byte, IEEE754 double-precision floating point numbers. - * - * # Examples - * - * None right now. - */ - fn read_be_f64(&self) -> f64; - - /** - * Reads a big-endian `f32`. - * - * `f32`s are 4 byte, IEEE754 single-precision floating point numbers. - * - * # Examples - * - * None right now. - */ - fn read_be_f32(&self) -> f32; - - /** - * Reads a little-endian `u64`. - * - * `u64`s are 8 bytes long. - * - * # Examples - * - * None right now. - */ - fn read_le_u64(&self) -> u64; - - /** - * Reads a little-endian `u32`. - * - * `u32`s are 4 bytes long. - * - * # Examples - * - * None right now. - */ - fn read_le_u32(&self) -> u32; - - /** - * Reads a little-endian `u16`. - * - * `u16`s are 2 bytes long. - * - * # Examples - * - * None right now. - */ - fn read_le_u16(&self) -> u16; - - /** - * Reads a little-endian `i64`. - * - * `i64`s are 8 bytes long. - * - * # Examples - * - * None right now. - */ - fn read_le_i64(&self) -> i64; - - /** - * Reads a little-endian `i32`. - * - * `i32`s are 4 bytes long. - * - * # Examples - * - * None right now. - */ - fn read_le_i32(&self) -> i32; - - /** - * Reads a little-endian `i16`. - * - * `i16`s are 2 bytes long. - * - * # Examples - * - * None right now. - */ - fn read_le_i16(&self) -> i16; - - /** - * Reads a little-endian `f64`. - * - * `f64`s are 8 byte, IEEE754 double-precision floating point numbers. - * - * # Examples - * - * None right now. - */ - fn read_le_f64(&self) -> f64; - - /** - * Reads a little-endian `f32`. - * - * `f32`s are 4 byte, IEEE754 single-precision floating point numbers. - * - * # Examples - * - * None right now. - */ - fn read_le_f32(&self) -> f32; - - /** - * Read a u8. - * - * `u8`s are 1 byte. - * - * # Examples - * - * None right now. - */ - fn read_u8(&self) -> u8; - - /** - * Read an i8. - * - * `i8`s are 1 byte. - * - * # Examples - * - * None right now. - */ - fn read_i8(&self) -> i8; -} - -impl<T:Reader> ReaderUtil for T { - - fn read_bytes(&self, len: uint) -> ~[u8] { - let mut bytes = vec::with_capacity(len); - unsafe { vec::raw::set_len(&mut bytes, len); } - - let count = self.read(bytes, len); - - unsafe { vec::raw::set_len(&mut bytes, count); } - bytes - } - - fn read_until(&self, c: u8, include: bool) -> ~str { - let mut bytes = ~[]; - loop { - let ch = self.read_byte(); - if ch == -1 || ch == c as int { - if include && ch == c as int { - bytes.push(ch as u8); - } - break; - } - bytes.push(ch as u8); - } - str::from_utf8(bytes) - } - - fn read_line(&self) -> ~str { - self.read_until('\n' as u8, false) - } - - fn read_chars(&self, n: uint) -> ~[char] { - // returns the (consumed offset, n_req), appends characters to &chars - fn chars_from_utf8<T:Reader>(bytes: &~[u8], chars: &mut ~[char]) - -> (uint, uint) { - let mut i = 0; - let bytes_len = bytes.len(); - while i < bytes_len { - let b0 = bytes[i]; - let w = str::utf8_char_width(b0); - let end = i + w; - i += 1; - assert!((w > 0)); - if w == 1 { - unsafe { - chars.push(transmute(b0 as u32)); - } - continue; - } - // can't satisfy this char with the existing data - if end > bytes_len { - return (i - 1, end - bytes_len); - } - let mut val = 0; - while i < end { - let next = bytes[i] as int; - i += 1; - assert!((next > -1)); - assert_eq!(next & 192, 128); - val <<= 6; - val += (next & 63) as uint; - } - // See str::StrSlice::char_at - val += ((b0 << ((w + 1) as u8)) as uint) - << (w - 1) * 6 - w - 1u; - unsafe { - chars.push(transmute(val as u32)); - } - } - return (i, 0); - } - let mut bytes = ~[]; - let mut chars = ~[]; - // might need more bytes, but reading n will never over-read - let mut nbread = n; - while nbread > 0 { - let data = self.read_bytes(nbread); - if data.is_empty() { - // eof - FIXME (#2004): should we do something if - // we're split in a unicode char? - break; - } - bytes.push_all(data); - let (offset, nbreq) = chars_from_utf8::<T>(&bytes, &mut chars); - let ncreq = n - chars.len(); - // again we either know we need a certain number of bytes - // to complete a character, or we make sure we don't - // over-read by reading 1-byte per char needed - nbread = if ncreq > nbreq { ncreq } else { nbreq }; - if nbread > 0 { - bytes = bytes.slice(offset, bytes.len()).to_owned(); - } - } - chars - } - - fn read_char(&self) -> char { - let c = self.read_chars(1); - if c.len() == 0 { - return unsafe { transmute(-1u32) }; // FIXME: #8971: unsound - } - assert_eq!(c.len(), 1); - return c[0]; - } - - fn read_c_str(&self) -> ~str { - self.read_until(0u8, false) - } - - fn read_whole_stream(&self) -> ~[u8] { - let mut bytes: ~[u8] = ~[]; - while !self.eof() { bytes.push_all(self.read_bytes(2048u)); } - bytes - } - - fn each_byte(&self, it: &fn(int) -> bool) -> bool { - loop { - match self.read_byte() { - -1 => break, - ch => if !it(ch) { return false; } - } - } - return true; - } - - fn each_char(&self, it: &fn(char) -> bool) -> bool { - // FIXME: #8971: unsound - let eof: char = unsafe { transmute(-1u32) }; - loop { - match self.read_char() { - c if c == eof => break, - ch => if !it(ch) { return false; } - } - } - return true; - } - - fn each_line(&self, it: &fn(s: &str) -> bool) -> bool { - while !self.eof() { - // include the \n, so that we can distinguish an entirely empty - // line read after "...\n", and the trailing empty line in - // "...\n\n". - let mut line = self.read_until('\n' as u8, true); - - // blank line at the end of the reader is ignored - if self.eof() && line.is_empty() { break; } - - // trim the \n, so that each_line is consistent with read_line - let n = line.len(); - if line[n-1] == '\n' as u8 { - unsafe { str::raw::set_len(&mut line, n-1); } - } - - if !it(line) { return false; } - } - return true; - } - - fn read_lines(&self) -> ~[~str] { - do vec::build(None) |push| { - do self.each_line |line| { - push(line.to_owned()); - true - }; - } - } - - // FIXME int reading methods need to deal with eof - issue #2004 - - fn read_le_uint_n(&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(&self, nbytes: uint) -> i64 { - extend_sign(self.read_le_uint_n(nbytes), nbytes) - } - - fn read_be_uint_n(&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(&self, nbytes: uint) -> i64 { - extend_sign(self.read_be_uint_n(nbytes), nbytes) - } - - fn read_le_uint(&self) -> uint { - self.read_le_uint_n(uint::bytes) as uint - } - - fn read_le_int(&self) -> int { - self.read_le_int_n(int::bytes) as int - } - - fn read_be_uint(&self) -> uint { - self.read_be_uint_n(uint::bytes) as uint - } - - fn read_be_int(&self) -> int { - self.read_be_int_n(int::bytes) as int - } - - fn read_be_u64(&self) -> u64 { - self.read_be_uint_n(8) as u64 - } - - fn read_be_u32(&self) -> u32 { - self.read_be_uint_n(4) as u32 - } - - fn read_be_u16(&self) -> u16 { - self.read_be_uint_n(2) as u16 - } - - fn read_be_i64(&self) -> i64 { - self.read_be_int_n(8) as i64 - } - - fn read_be_i32(&self) -> i32 { - self.read_be_int_n(4) as i32 - } - - fn read_be_i16(&self) -> i16 { - self.read_be_int_n(2) as i16 - } - - fn read_be_f64(&self) -> f64 { - unsafe { - cast::transmute::<u64, f64>(self.read_be_u64()) - } - } - - fn read_be_f32(&self) -> f32 { - unsafe { - cast::transmute::<u32, f32>(self.read_be_u32()) - } - } - - fn read_le_u64(&self) -> u64 { - self.read_le_uint_n(8) as u64 - } - - fn read_le_u32(&self) -> u32 { - self.read_le_uint_n(4) as u32 - } - - fn read_le_u16(&self) -> u16 { - self.read_le_uint_n(2) as u16 - } - - fn read_le_i64(&self) -> i64 { - self.read_le_int_n(8) as i64 - } - - fn read_le_i32(&self) -> i32 { - self.read_le_int_n(4) as i32 - } - - fn read_le_i16(&self) -> i16 { - self.read_le_int_n(2) as i16 - } - - fn read_le_f64(&self) -> f64 { - unsafe { - cast::transmute::<u64, f64>(self.read_le_u64()) - } - } - - fn read_le_f32(&self) -> f32 { - unsafe { - cast::transmute::<u32, f32>(self.read_le_u32()) - } - } - - fn read_u8(&self) -> u8 { - self.read_byte() as u8 - } - - fn read_i8(&self) -> i8 { - self.read_byte() as i8 - } -} - -fn extend_sign(val: u64, nbytes: uint) -> i64 { - let shift = (8 - nbytes) * 8; - (val << shift) as i64 >> shift -} - -// Reader implementations - -fn convert_whence(whence: SeekStyle) -> i32 { - return match whence { - SeekSet => 0i32, - SeekCur => 1i32, - SeekEnd => 2i32 - }; -} - -impl Reader for *libc::FILE { - fn read(&self, bytes: &mut [u8], len: uint) -> uint { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - do bytes.as_mut_buf |buf_p, buf_len| { - assert!(buf_len >= len); - - let count = libc::fread(buf_p as *mut c_void, 1u as size_t, - len as size_t, *self) as uint; - if count < len { - match libc::ferror(*self) { - 0 => (), - _ => { - error!("error reading buffer: {}", os::last_os_error()); - fail!(); - } - } - } - - count - } - } - } - fn read_byte(&self) -> int { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - libc::fgetc(*self) as int - } - } - fn eof(&self) -> bool { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - return libc::feof(*self) != 0 as c_int; - } - } - fn seek(&self, offset: int, whence: SeekStyle) { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - assert!(libc::fseek(*self, - offset as libc::c_long, - convert_whence(whence)) == 0 as c_int); - } - } - fn tell(&self) -> uint { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - return libc::ftell(*self) as uint; - } - } -} - -struct Wrapper<T, C> { - base: T, - cleanup: C, -} - -// A forwarding impl of reader that also holds on to a resource for the -// duration of its lifetime. -// FIXME there really should be a better way to do this // #2004 -impl<R:Reader,C> Reader for Wrapper<R, C> { - fn read(&self, bytes: &mut [u8], len: uint) -> uint { - self.base.read(bytes, len) - } - fn read_byte(&self) -> int { self.base.read_byte() } - fn eof(&self) -> bool { self.base.eof() } - fn seek(&self, off: int, whence: SeekStyle) { - self.base.seek(off, whence) - } - fn tell(&self) -> uint { self.base.tell() } -} - -pub struct FILERes { - priv f: *libc::FILE, -} - -impl FILERes { - fn new(f: *libc::FILE) -> FILERes { - FILERes { f: f } - } -} - -impl Drop for FILERes { - fn drop(&mut self) { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - libc::fclose(self.f); - } - } -} - -pub fn file_reader(path: &Path) -> Result<@Reader, ~str> { - #[fixed_stack_segment]; #[inline(never)]; - - let f = do path.with_c_str |pathbuf| { - do "rb".with_c_str |modebuf| { - unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) } - } - }; - - if f as uint == 0u { - do path.display().with_str |p| { - Err(~"error opening " + p) - } - } else { - Ok(@Wrapper { base: f, cleanup: FILERes::new(f) } as @Reader) - } -} - -// Writing -pub enum FileFlag { Append, Create, Truncate, NoFlag, } - -// What type of writer are we? -#[deriving(Eq)] -pub enum WriterType { Screen, File } - -// FIXME (#2004): Seekable really should be orthogonal. -// FIXME (#2004): eventually u64 -/// The raw underlying writer trait. All writers must implement this. -pub trait Writer { - - /// Write all of the given bytes. - fn write(&self, v: &[u8]); - - /// Move the current position within the stream. The second parameter - /// determines the position that the first parameter is relative to. - fn seek(&self, int, SeekStyle); - - /// Return the current position within the stream. - fn tell(&self) -> uint; - - /// Flush the output buffer for this stream (if there is one). - fn flush(&self) -> int; - - /// Determine if this Writer is writing to a file or not. - fn get_type(&self) -> WriterType; -} - -impl Writer for @Writer { - fn write(&self, v: &[u8]) { self.write(v) } - fn seek(&self, a: int, b: SeekStyle) { self.seek(a, b) } - fn tell(&self) -> uint { self.tell() } - fn flush(&self) -> int { self.flush() } - fn get_type(&self) -> WriterType { self.get_type() } -} - -impl<W:Writer,C> Writer for Wrapper<W, C> { - fn write(&self, bs: &[u8]) { self.base.write(bs); } - fn seek(&self, off: int, style: SeekStyle) { self.base.seek(off, style); } - fn tell(&self) -> uint { self.base.tell() } - fn flush(&self) -> int { self.base.flush() } - fn get_type(&self) -> WriterType { File } -} - -impl Writer for *libc::FILE { - fn write(&self, v: &[u8]) { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - do v.as_imm_buf |vbuf, len| { - let nout = libc::fwrite(vbuf as *c_void, - 1, - len as size_t, - *self); - if nout != len as size_t { - error!("error writing buffer: {}", os::last_os_error()); - fail!(); - } - } - } - } - fn seek(&self, offset: int, whence: SeekStyle) { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - assert!(libc::fseek(*self, - offset as libc::c_long, - convert_whence(whence)) == 0 as c_int); - } - } - fn tell(&self) -> uint { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - libc::ftell(*self) as uint - } - } - fn flush(&self) -> int { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - libc::fflush(*self) as int - } - } - fn get_type(&self) -> WriterType { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - let fd = libc::fileno(*self); - if libc::isatty(fd) == 0 { File } - else { Screen } - } - } -} - -impl Writer for fd_t { - fn write(&self, v: &[u8]) { - #[fixed_stack_segment]; #[inline(never)]; - - #[cfg(windows)] - type IoSize = libc::c_uint; - #[cfg(windows)] - type IoRet = c_int; - - #[cfg(unix)] - type IoSize = size_t; - #[cfg(unix)] - type IoRet = libc::ssize_t; - - unsafe { - let mut count = 0u; - do v.as_imm_buf |vbuf, len| { - while count < len { - let vb = ptr::offset(vbuf, count as int) as *c_void; - let nout = libc::write(*self, vb, len as IoSize); - if nout < 0 as IoRet { - error!("error writing buffer: {}", os::last_os_error()); - fail!(); - } - count += nout as uint; - } - } - } - } - fn seek(&self, _offset: int, _whence: SeekStyle) { - error!("need 64-bit foreign calls for seek, sorry"); - fail!(); - } - fn tell(&self) -> uint { - error!("need 64-bit foreign calls for tell, sorry"); - fail!(); - } - fn flush(&self) -> int { 0 } - fn get_type(&self) -> WriterType { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - if libc::isatty(*self) == 0 { File } else { Screen } - } - } -} - -pub struct FdRes { - priv fd: fd_t, -} - -impl FdRes { - fn new(fd: fd_t) -> FdRes { - FdRes { fd: fd } - } -} - -impl Drop for FdRes { - fn drop(&mut self) { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { - libc::close(self.fd); - } - } -} - -pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) - -> Result<@Writer, ~str> { - #[fixed_stack_segment]; #[inline(never)]; - - #[cfg(windows)] - fn wb() -> c_int { - (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int - } - - #[cfg(unix)] - fn wb() -> c_int { O_WRONLY as c_int } - - let mut fflags: c_int = wb(); - for f in flags.iter() { - match *f { - Append => fflags |= O_APPEND as c_int, - Create => fflags |= O_CREAT as c_int, - Truncate => fflags |= O_TRUNC as c_int, - NoFlag => () - } - } - let fd = unsafe { - do path.with_c_str |pathbuf| { - libc::open(pathbuf, fflags, (S_IRUSR | S_IWUSR) as c_int) - } - }; - if fd < (0 as c_int) { - Err(format!("error opening {}: {}", path.display(), os::last_os_error())) - } else { - Ok(@Wrapper { base: fd, cleanup: FdRes::new(fd) } as @Writer) - } -} - -pub fn u64_to_le_bytes<T>(n: u64, size: uint, - f: &fn(v: &[u8]) -> T) -> T { - assert!(size <= 8u); - match size { - 1u => f(&[n as u8]), - 2u => f(&[n as u8, - (n >> 8) as u8]), - 4u => f(&[n as u8, - (n >> 8) as u8, - (n >> 16) as u8, - (n >> 24) as u8]), - 8u => f(&[n as u8, - (n >> 8) as u8, - (n >> 16) as u8, - (n >> 24) as u8, - (n >> 32) as u8, - (n >> 40) as u8, - (n >> 48) as u8, - (n >> 56) as u8]), - _ => { - - let mut bytes: ~[u8] = ~[]; - let mut i = size; - let mut n = n; - while i > 0u { - bytes.push((n & 255_u64) as u8); - n >>= 8_u64; - i -= 1u; - } - f(bytes) - } - } -} - -pub fn u64_to_be_bytes<T>(n: u64, size: uint, - f: &fn(v: &[u8]) -> T) -> T { - assert!(size <= 8u); - match size { - 1u => f(&[n as u8]), - 2u => f(&[(n >> 8) as u8, - n as u8]), - 4u => f(&[(n >> 24) as u8, - (n >> 16) as u8, - (n >> 8) as u8, - n as u8]), - 8u => f(&[(n >> 56) as u8, - (n >> 48) as u8, - (n >> 40) as u8, - (n >> 32) as u8, - (n >> 24) as u8, - (n >> 16) as u8, - (n >> 8) as u8, - n as u8]), - _ => { - let mut bytes: ~[u8] = ~[]; - let mut i = size; - while i > 0u { - let shift = ((i - 1u) * 8u) as u64; - bytes.push((n >> shift) as u8); - i -= 1u; - } - f(bytes) - } - } -} - -pub fn u64_from_be_bytes(data: &[u8], - start: uint, - size: uint) - -> u64 { - let mut sz = size; - assert!((sz <= 8u)); - let mut val = 0_u64; - let mut pos = start; - while sz > 0u { - sz -= 1u; - val += (data[pos] as u64) << ((sz * 8u) as u64); - pos += 1u; - } - return val; -} - -// FIXME: #3048 combine trait+impl (or just move these to -// default methods on writer) -/// Generic utility functions defined on writers. -pub trait WriterUtil { - - /// Write a single utf-8 encoded char. - fn write_char(&self, ch: char); - - /// Write every char in the given str, encoded as utf-8. - fn write_str(&self, s: &str); - - /// Write the given str, as utf-8, followed by '\n'. - fn write_line(&self, s: &str); - - /// Write the result of passing n through `int::to_str_bytes`. - fn write_int(&self, n: int); - - /// Write the result of passing n through `uint::to_str_bytes`. - fn write_uint(&self, n: uint); - - /// Write a little-endian uint (number of bytes depends on system). - fn write_le_uint(&self, n: uint); - - /// Write a little-endian int (number of bytes depends on system). - fn write_le_int(&self, n: int); - - /// Write a big-endian uint (number of bytes depends on system). - fn write_be_uint(&self, n: uint); - - /// Write a big-endian int (number of bytes depends on system). - fn write_be_int(&self, n: int); - - /// Write a big-endian u64 (8 bytes). - fn write_be_u64(&self, n: u64); - - /// Write a big-endian u32 (4 bytes). - fn write_be_u32(&self, n: u32); - - /// Write a big-endian u16 (2 bytes). - fn write_be_u16(&self, n: u16); - - /// Write a big-endian i64 (8 bytes). - fn write_be_i64(&self, n: i64); - - /// Write a big-endian i32 (4 bytes). - fn write_be_i32(&self, n: i32); - - /// Write a big-endian i16 (2 bytes). - fn write_be_i16(&self, n: i16); - - /// Write a big-endian IEEE754 double-precision floating-point (8 bytes). - fn write_be_f64(&self, f: f64); - - /// Write a big-endian IEEE754 single-precision floating-point (4 bytes). - fn write_be_f32(&self, f: f32); - - /// Write a little-endian u64 (8 bytes). - fn write_le_u64(&self, n: u64); - - /// Write a little-endian u32 (4 bytes). - fn write_le_u32(&self, n: u32); - - /// Write a little-endian u16 (2 bytes). - fn write_le_u16(&self, n: u16); - - /// Write a little-endian i64 (8 bytes). - fn write_le_i64(&self, n: i64); - - /// Write a little-endian i32 (4 bytes). - fn write_le_i32(&self, n: i32); - - /// Write a little-endian i16 (2 bytes). - fn write_le_i16(&self, n: i16); - - /// Write a little-endian IEEE754 double-precision floating-point - /// (8 bytes). - fn write_le_f64(&self, f: f64); - - /// Write a little-endian IEEE754 single-precision floating-point - /// (4 bytes). - fn write_le_f32(&self, f: f32); - - /// Write a u8 (1 byte). - fn write_u8(&self, n: u8); - - /// Write a i8 (1 byte). - fn write_i8(&self, n: i8); -} - -impl<T:Writer> WriterUtil for T { - fn write_char(&self, ch: char) { - if (ch as uint) < 128u { - self.write(&[ch as u8]); - } else { - self.write_str(str::from_char(ch)); - } - } - fn write_str(&self, s: &str) { self.write(s.as_bytes()) } - fn write_line(&self, s: &str) { - self.write_str(s); - self.write_str(&"\n"); - } - fn write_int(&self, n: int) { - int::to_str_bytes(n, 10u, |bytes| self.write(bytes)) - } - fn write_uint(&self, n: uint) { - uint::to_str_bytes(n, 10u, |bytes| self.write(bytes)) - } - fn write_le_uint(&self, n: uint) { - u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v)) - } - fn write_le_int(&self, n: int) { - u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v)) - } - fn write_be_uint(&self, n: uint) { - u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v)) - } - fn write_be_int(&self, n: int) { - u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v)) - } - fn write_be_u64(&self, n: u64) { - u64_to_be_bytes(n, 8u, |v| self.write(v)) - } - fn write_be_u32(&self, n: u32) { - u64_to_be_bytes(n as u64, 4u, |v| self.write(v)) - } - fn write_be_u16(&self, n: u16) { - u64_to_be_bytes(n as u64, 2u, |v| self.write(v)) - } - fn write_be_i64(&self, n: i64) { - u64_to_be_bytes(n as u64, 8u, |v| self.write(v)) - } - fn write_be_i32(&self, n: i32) { - u64_to_be_bytes(n as u64, 4u, |v| self.write(v)) - } - fn write_be_i16(&self, n: i16) { - u64_to_be_bytes(n as u64, 2u, |v| self.write(v)) - } - fn write_be_f64(&self, f:f64) { - unsafe { - self.write_be_u64(cast::transmute(f)) - } - } - fn write_be_f32(&self, f:f32) { - unsafe { - self.write_be_u32(cast::transmute(f)) - } - } - fn write_le_u64(&self, n: u64) { - u64_to_le_bytes(n, 8u, |v| self.write(v)) - } - fn write_le_u32(&self, n: u32) { - u64_to_le_bytes(n as u64, 4u, |v| self.write(v)) - } - fn write_le_u16(&self, n: u16) { - u64_to_le_bytes(n as u64, 2u, |v| self.write(v)) - } - fn write_le_i64(&self, n: i64) { - u64_to_le_bytes(n as u64, 8u, |v| self.write(v)) - } - fn write_le_i32(&self, n: i32) { - u64_to_le_bytes(n as u64, 4u, |v| self.write(v)) - } - fn write_le_i16(&self, n: i16) { - u64_to_le_bytes(n as u64, 2u, |v| self.write(v)) - } - fn write_le_f64(&self, f:f64) { - unsafe { - self.write_le_u64(cast::transmute(f)) - } - } - fn write_le_f32(&self, f:f32) { - unsafe { - self.write_le_u32(cast::transmute(f)) - } - } - - fn write_u8(&self, n: u8) { self.write([n]) } - fn write_i8(&self, n: i8) { self.write([n as u8]) } - -} - -pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> { - mk_file_writer(path, flags).and_then(|w| Ok(w)) -} - -// FIXME (#2004) it would be great if this could be a const -// FIXME (#2004) why are these different from the way stdin() is -// implemented? - -pub struct BytesWriter { - bytes: @mut ~[u8], - pos: @mut uint, -} - -impl BytesWriter { - pub fn new() -> BytesWriter { - BytesWriter { - bytes: @mut ~[], - pos: @mut 0 - } - } -} - -impl Writer for BytesWriter { - fn write(&self, v: &[u8]) { - let v_len = v.len(); - - let bytes = &mut *self.bytes; - let count = num::max(bytes.len(), *self.pos + v_len); - bytes.reserve(count); - - unsafe { - vec::raw::set_len(bytes, count); - - let view = bytes.mut_slice(*self.pos, count); - vec::bytes::copy_memory(view, v, v_len); - } - - *self.pos += v_len; - } - - fn seek(&self, offset: int, whence: SeekStyle) { - let pos = *self.pos; - let len = self.bytes.len(); - *self.pos = seek_in_buf(offset, pos, len, whence); - } - - fn tell(&self) -> uint { - *self.pos - } - - fn flush(&self) -> int { - 0 - } - - fn get_type(&self) -> WriterType { - File - } -} - -pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] { - let wr = @BytesWriter::new(); - f(wr as @Writer); - let @BytesWriter { bytes, _ } = wr; - (*bytes).clone() -} - -pub fn with_str_writer(f: &fn(@Writer)) -> ~str { - str::from_utf8(with_bytes_writer(f)) -} - -// Utility functions -fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) -> - uint { - let mut bpos = pos as int; - let blen = len as int; - match whence { - SeekSet => bpos = offset, - SeekCur => bpos += offset, - SeekEnd => bpos = blen + offset - } - if bpos < 0 { bpos = 0; } else if bpos > blen { bpos = blen; } - return bpos as uint; -} - -#[cfg(test)] -mod tests { - use prelude::*; - use i32; - use io::{BytesWriter, SeekCur, SeekEnd, SeekSet}; - use io; - use path::Path; - use result::{Ok, Err}; - use u64; - use vec; - use cast::transmute; - - #[test] - fn test_simple() { - let tmpfile = &Path::new("tmp/lib-io-test-simple.tmp"); - debug!("{}", tmpfile.display()); - let frood: ~str = - ~"A hoopy frood who really knows where his towel is."; - debug!("{}", frood.clone()); - { - let out = io::file_writer(tmpfile, [io::Create, io::Truncate]).unwrap(); - out.write_str(frood); - } - let inp = io::file_reader(tmpfile).unwrap(); - let frood2: ~str = inp.read_c_str(); - debug!("{}", frood2.clone()); - assert_eq!(frood, frood2); - } - - #[test] - fn test_each_byte_each_char_file() { - // Issue #5056 -- shouldn't include trailing EOF. - let path = Path::new("tmp/lib-io-test-each-byte-each-char-file.tmp"); - - { - // create empty, enough to reproduce a problem - io::file_writer(&path, [io::Create]).unwrap(); - } - - { - let file = io::file_reader(&path).unwrap(); - do file.each_byte() |_| { - fail!("must be empty") - }; - } - - { - let file = io::file_reader(&path).unwrap(); - do file.each_char() |_| { - fail!("must be empty") - }; - } - } - - #[test] - fn file_reader_not_exist() { - match io::file_reader(&Path::new("not a file")) { - Err(e) => { - assert_eq!(e, ~"error opening not a file"); - } - Ok(_) => fail!() - } - } - - #[test] - #[should_fail] - fn test_read_buffer_too_small() { - let path = &Path::new("tmp/lib-io-test-read-buffer-too-small.tmp"); - // ensure the file exists - io::file_writer(path, [io::Create]).unwrap(); - - let file = io::file_reader(path).unwrap(); - let mut buf = vec::from_elem(5, 0u8); - file.read(buf, 6); // this should fail because buf is too small - } - - #[test] - fn test_read_buffer_big_enough() { - let path = &Path::new("tmp/lib-io-test-read-buffer-big-enough.tmp"); - // ensure the file exists - io::file_writer(path, [io::Create]).unwrap(); - - let file = io::file_reader(path).unwrap(); - let mut buf = vec::from_elem(5, 0u8); - file.read(buf, 4); // this should succeed because buf is big enough - } - - #[test] - fn test_write_empty() { - let file = io::file_writer(&Path::new("tmp/lib-io-test-write-empty.tmp"), - [io::Create]).unwrap(); - file.write([]); - } - - #[test] - fn file_writer_bad_name() { - match io::file_writer(&Path::new("?/?"), []) { - Err(e) => { - assert!(e.starts_with("error opening")); - } - Ok(_) => fail!() - } - } - - #[test] - fn bytes_buffer_overwrite() { - let wr = BytesWriter::new(); - wr.write([0u8, 1u8, 2u8, 3u8]); - assert!(*wr.bytes == ~[0u8, 1u8, 2u8, 3u8]); - wr.seek(-2, SeekCur); - wr.write([4u8, 5u8, 6u8, 7u8]); - assert!(*wr.bytes == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]); - wr.seek(-2, SeekEnd); - wr.write([8u8]); - wr.seek(1, SeekSet); - wr.write([9u8]); - assert!(*wr.bytes == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]); - } - - #[test] - fn test_read_write_le() { - let path = Path::new("tmp/lib-io-test-read-write-le.tmp"); - let uints = [0, 1, 2, 42, 10_123, 100_123_456, u64::max_value]; - - // write the ints to the file - { - let file = io::file_writer(&path, [io::Create]).unwrap(); - for i in uints.iter() { - file.write_le_u64(*i); - } - } - - // then read them back and check that they are the same - { - let file = io::file_reader(&path).unwrap(); - for i in uints.iter() { - assert_eq!(file.read_le_u64(), *i); - } - } - } - - #[test] - fn test_read_write_be() { - let path = Path::new("tmp/lib-io-test-read-write-be.tmp"); - let uints = [0, 1, 2, 42, 10_123, 100_123_456, u64::max_value]; - - // write the ints to the file - { - let file = io::file_writer(&path, [io::Create]).unwrap(); - for i in uints.iter() { - file.write_be_u64(*i); - } - } - - // then read them back and check that they are the same - { - let file = io::file_reader(&path).unwrap(); - for i in uints.iter() { - assert_eq!(file.read_be_u64(), *i); - } - } - } - - #[test] - fn test_read_be_int_n() { - let path = Path::new("tmp/lib-io-test-read-be-int-n.tmp"); - let ints = [i32::min_value, -123456, -42, -5, 0, 1, i32::max_value]; - - // write the ints to the file - { - let file = io::file_writer(&path, [io::Create]).unwrap(); - for i in ints.iter() { - file.write_be_i32(*i); - } - } - - // then read them back and check that they are the same - { - let file = io::file_reader(&path).unwrap(); - for i in ints.iter() { - // this tests that the sign extension is working - // (comparing the values as i32 would not test this) - assert_eq!(file.read_be_int_n(4), *i as i64); - } - } - } - - #[test] - fn test_read_f32() { - let path = Path::new("tmp/lib-io-test-read-f32.tmp"); - //big-endian floating-point 8.1250 - let buf = ~[0x41, 0x02, 0x00, 0x00]; - - { - let file = io::file_writer(&path, [io::Create]).unwrap(); - file.write(buf); - } - - { - let file = io::file_reader(&path).unwrap(); - let f = file.read_be_f32(); - assert_eq!(f, 8.1250); - } - } - - #[test] - fn test_read_write_f32() { - let path = Path::new("tmp/lib-io-test-read-write-f32.tmp"); - let f:f32 = 8.1250; - - { - let file = io::file_writer(&path, [io::Create]).unwrap(); - file.write_be_f32(f); - file.write_le_f32(f); - } - - { - let file = io::file_reader(&path).unwrap(); - assert_eq!(file.read_be_f32(), 8.1250); - assert_eq!(file.read_le_f32(), 8.1250); - } - } -} diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 886ad9995a1..bb8e6674b46 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -53,7 +53,6 @@ pub use container::{Container, Mutable, Map, MutableMap, Set, MutableSet}; pub use default::Default; pub use from_str::FromStr; pub use hash::Hash; -pub use io::{Reader, ReaderUtil, Writer, WriterUtil}; pub use iter::{FromIterator, Extendable}; pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, ClonableIterator}; pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize}; diff --git a/src/libstd/rt/io/extensions.rs b/src/libstd/rt/io/extensions.rs index c77e3b91609..4b16f0bc0e1 100644 --- a/src/libstd/rt/io/extensions.rs +++ b/src/libstd/rt/io/extensions.rs @@ -22,7 +22,6 @@ use rt::io::{io_error, standard_error, EndOfFile, DEFAULT_BUF_SIZE}; use option::{Option, Some, None}; use unstable::finally::Finally; use cast; -use io::{u64_to_le_bytes, u64_to_be_bytes}; pub trait ReaderUtil { @@ -634,6 +633,88 @@ fn extend_sign(val: u64, nbytes: uint) -> i64 { (val << shift) as i64 >> shift } +pub fn u64_to_le_bytes<T>(n: u64, size: uint, + f: &fn(v: &[u8]) -> T) -> T { + assert!(size <= 8u); + match size { + 1u => f(&[n as u8]), + 2u => f(&[n as u8, + (n >> 8) as u8]), + 4u => f(&[n as u8, + (n >> 8) as u8, + (n >> 16) as u8, + (n >> 24) as u8]), + 8u => f(&[n as u8, + (n >> 8) as u8, + (n >> 16) as u8, + (n >> 24) as u8, + (n >> 32) as u8, + (n >> 40) as u8, + (n >> 48) as u8, + (n >> 56) as u8]), + _ => { + + let mut bytes: ~[u8] = ~[]; + let mut i = size; + let mut n = n; + while i > 0u { + bytes.push((n & 255_u64) as u8); + n >>= 8_u64; + i -= 1u; + } + f(bytes) + } + } +} + +pub fn u64_to_be_bytes<T>(n: u64, size: uint, + f: &fn(v: &[u8]) -> T) -> T { + assert!(size <= 8u); + match size { + 1u => f(&[n as u8]), + 2u => f(&[(n >> 8) as u8, + n as u8]), + 4u => f(&[(n >> 24) as u8, + (n >> 16) as u8, + (n >> 8) as u8, + n as u8]), + 8u => f(&[(n >> 56) as u8, + (n >> 48) as u8, + (n >> 40) as u8, + (n >> 32) as u8, + (n >> 24) as u8, + (n >> 16) as u8, + (n >> 8) as u8, + n as u8]), + _ => { + let mut bytes: ~[u8] = ~[]; + let mut i = size; + while i > 0u { + let shift = ((i - 1u) * 8u) as u64; + bytes.push((n >> shift) as u8); + i -= 1u; + } + f(bytes) + } + } +} + +pub fn u64_from_be_bytes(data: &[u8], + start: uint, + size: uint) + -> u64 { + let mut sz = size; + assert!((sz <= 8u)); + let mut val = 0_u64; + let mut pos = start; + while sz > 0u { + sz -= 1u; + val += (data[pos] as u64) << ((sz * 8u) as u64); + pos += 1u; + } + return val; +} + #[cfg(test)] mod test { use super::ReaderUtil; diff --git a/src/libstd/std.rs b/src/libstd/std.rs index 8c72e083f88..12316cb5ead 100644 --- a/src/libstd/std.rs +++ b/src/libstd/std.rs @@ -148,7 +148,6 @@ pub mod iter; pub mod to_str; pub mod to_bytes; pub mod clone; -pub mod io; pub mod hash; pub mod container; pub mod default; diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index 4d5da19dafd..8c78e34528b 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -16,8 +16,6 @@ The `ToBytes` and `IterBytes` traits use cast; use container::Container; -use io; -use io::Writer; use iter::Iterator; use option::{None, Option, Some}; use str::{Str, StrSlice}; @@ -360,7 +358,10 @@ pub trait ToBytes { impl<A:IterBytes> ToBytes for A { fn to_bytes(&self, lsb0: bool) -> ~[u8] { - do io::with_bytes_writer |wr| { + use rt::io::mem; + use rt::io::Writer; + + do mem::with_mem_writer |wr| { do self.iter_bytes(lsb0) |bytes| { wr.write(bytes); true |
