1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 The `io` module contains basic input and output routines.
17 ## `Reader` and `Writer` traits
19 These traits define the minimal set of methods that anything that can do
20 input and output should implement.
22 ## `ReaderUtil` and `WriterUtil` traits
24 Richer methods that allow you to do more. `Reader` only lets you read a certain
25 number of bytes into a buffer, while `ReaderUtil` allows you to read a whole
28 Generally, these richer methods are probably the ones you want to actually
29 use in day-to-day Rust.
31 Furthermore, because there is an implementation of `ReaderUtil` for
32 `<T: Reader>`, when your input or output code implements `Reader`, you get
33 all of these methods for free.
35 ## `print` and `println`
37 These very useful functions are defined here. You generally don't need to
38 import them, though, as the prelude already does.
40 ## `stdin`, `stdout`, and `stderr`
42 These functions return references to the classic three file descriptors. They
43 implement `Reader` and `Writer`, where appropriate.
47 #[allow(missing_doc)];
53 use container::Container;
56 use libc::consts::os::posix88::*;
57 use libc::{c_int, c_void, size_t};
61 use option::{Some, None};
65 use result::{Result, Ok, Err};
66 use str::{StrSlice, OwnedStr};
70 use vec::{MutableVector, ImmutableVector, OwnedVector, OwnedCopyableVector, CopyableVector};
73 #[allow(non_camel_case_types)] // not sure what to do about this
74 pub type fd_t = c_int;
80 #[link_name = "rustrt"]
82 pub fn rust_get_stdin() -> *libc::FILE;
83 pub fn rust_get_stdout() -> *libc::FILE;
84 pub fn rust_get_stderr() -> *libc::FILE;
90 // FIXME (#2004): This is all buffered. We might need an unbuffered variant
93 * The SeekStyle enum describes the relationship between the position
94 * we'd like to seek to from our current position. It's used as an argument
95 * to the `seek` method defined on the `Reader` trait.
97 * There are three seek styles:
99 * 1. `SeekSet` means that the new position should become our position.
100 * 2. `SeekCur` means that we should seek from the current position.
101 * 3. `SeekEnd` means that we should seek from the end.
107 pub enum SeekStyle { SeekSet, SeekEnd, SeekCur, }
111 * The core Reader trait. All readers must implement this trait.
118 // FIXME (#2004): Seekable really should be orthogonal.
120 // FIXME (#2982): This should probably return an error.
122 * Reads bytes and puts them into `bytes`, advancing the cursor. Returns the
123 * number of bytes read.
125 * The number of bytes to be read is `len` or the end of the file,
126 * whichever comes first.
128 * The buffer must be at least `len` bytes long.
130 * `read` is conceptually similar to C's `fread` function.
136 fn read(&self, bytes: &mut [u8], len: uint) -> uint;
139 * Reads a single byte, advancing the cursor.
141 * In the case of an EOF or an error, returns a negative value.
143 * `read_byte` is conceptually similar to C's `getc` function.
149 fn read_byte(&self) -> int;
152 * Returns a boolean value: are we currently at EOF?
154 * Note that stream position may be already at the end-of-file point,
155 * but `eof` returns false until an attempt to read at that position.
157 * `eof` is conceptually similar to C's `feof` function.
163 fn eof(&self) -> bool;
166 * Seek to a given `position` in the stream.
168 * Takes an optional SeekStyle, which affects how we seek from the
169 * position. See `SeekStyle` docs for more details.
171 * `seek` is conceptually similar to C's `fseek` function.
177 fn seek(&self, position: int, style: SeekStyle);
180 * Returns the current position within the stream.
182 * `tell` is conceptually similar to C's `ftell` function.
188 fn tell(&self) -> uint;
191 impl Reader for @Reader {
192 fn read(&self, bytes: &mut [u8], len: uint) -> uint {
193 self.read(bytes, len)
195 fn read_byte(&self) -> int {
198 fn eof(&self) -> bool {
201 fn seek(&self, position: int, style: SeekStyle) {
202 self.seek(position, style)
204 fn tell(&self) -> uint {
210 * The `ReaderUtil` trait is a home for many of the utility functions
211 * a particular Reader should implement.
213 * The default `Reader` trait is focused entirely on bytes. `ReaderUtil` is based
214 * on higher-level concepts like 'chars' and 'lines.'
220 pub trait ReaderUtil {
223 * Reads `len` number of bytes, and gives you a new vector back.
229 fn read_bytes(&self, len: uint) -> ~[u8];
232 * Reads up until a specific byte is seen or EOF.
234 * The `include` parameter specifies if the character should be included
235 * in the returned string.
241 fn read_until(&self, c: u8, include: bool) -> ~str;
244 * Reads up until the first '\n' or EOF.
246 * The '\n' is not included in the result.
252 fn read_line(&self) -> ~str;
257 * Assumes that those chars are UTF-8 encoded.
259 * The '\n' is not included in the result.
265 fn read_chars(&self, n: uint) -> ~[char];
268 * Reads a single UTF-8 encoded char.
274 fn read_char(&self) -> char;
277 * Reads up until the first null byte or EOF.
279 * The null byte is not returned.
285 fn read_c_str(&self) -> ~str;
288 * Reads all remaining data in the stream.
294 fn read_whole_stream(&self) -> ~[u8];
297 * Iterate over every byte until EOF or the iterator breaks.
303 fn each_byte(&self, it: &fn(int) -> bool) -> bool;
306 * Iterate over every char until EOF or the iterator breaks.
312 fn each_char(&self, it: &fn(char) -> bool) -> bool;
315 * Iterate over every line until EOF or the iterator breaks.
321 fn each_line(&self, it: &fn(&str) -> bool) -> bool;
324 * Reads all of the lines in the stream.
326 * Returns a vector of those lines.
332 fn read_lines(&self) -> ~[~str];
335 * Reads `n` little-endian unsigned integer bytes.
337 * `n` must be between 1 and 8, inclusive.
343 fn read_le_uint_n(&self, nbytes: uint) -> u64;
346 * Reads `n` little-endian signed integer bytes.
348 * `n` must be between 1 and 8, inclusive.
354 fn read_le_int_n(&self, nbytes: uint) -> i64;
357 * Reads `n` big-endian unsigned integer bytes.
359 * `n` must be between 1 and 8, inclusive.
365 fn read_be_uint_n(&self, nbytes: uint) -> u64;
368 * Reads `n` big-endian signed integer bytes.
370 * `n` must be between 1 and 8, inclusive.
376 fn read_be_int_n(&self, nbytes: uint) -> i64;
379 * Reads a little-endian unsigned integer.
381 * The number of bytes returned is system-dependant.
387 fn read_le_uint(&self) -> uint;
390 * Reads a little-endian integer.
392 * The number of bytes returned is system-dependant.
398 fn read_le_int(&self) -> int;
401 * Reads a big-endian unsigned integer.
403 * The number of bytes returned is system-dependant.
409 fn read_be_uint(&self) -> uint;
412 * Reads a big-endian integer.
414 * The number of bytes returned is system-dependant.
420 fn read_be_int(&self) -> int;
423 * Reads a big-endian `u64`.
425 * `u64`s are 8 bytes long.
431 fn read_be_u64(&self) -> u64;
434 * Reads a big-endian `u32`.
436 * `u32`s are 4 bytes long.
442 fn read_be_u32(&self) -> u32;
445 * Reads a big-endian `u16`.
447 * `u16`s are 2 bytes long.
453 fn read_be_u16(&self) -> u16;
456 * Reads a big-endian `i64`.
458 * `i64`s are 8 bytes long.
464 fn read_be_i64(&self) -> i64;
467 * Reads a big-endian `i32`.
469 * `i32`s are 4 bytes long.
475 fn read_be_i32(&self) -> i32;
478 * Reads a big-endian `i16`.
480 * `i16`s are 2 bytes long.
486 fn read_be_i16(&self) -> i16;
489 * Reads a big-endian `f64`.
491 * `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
497 fn read_be_f64(&self) -> f64;
500 * Reads a big-endian `f32`.
502 * `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
508 fn read_be_f32(&self) -> f32;
511 * Reads a little-endian `u64`.
513 * `u64`s are 8 bytes long.
519 fn read_le_u64(&self) -> u64;
522 * Reads a little-endian `u32`.
524 * `u32`s are 4 bytes long.
530 fn read_le_u32(&self) -> u32;
533 * Reads a little-endian `u16`.
535 * `u16`s are 2 bytes long.
541 fn read_le_u16(&self) -> u16;
544 * Reads a little-endian `i64`.
546 * `i64`s are 8 bytes long.
552 fn read_le_i64(&self) -> i64;
555 * Reads a little-endian `i32`.
557 * `i32`s are 4 bytes long.
563 fn read_le_i32(&self) -> i32;
566 * Reads a little-endian `i16`.
568 * `i16`s are 2 bytes long.
574 fn read_le_i16(&self) -> i16;
577 * Reads a little-endian `f64`.
579 * `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
585 fn read_le_f64(&self) -> f64;
588 * Reads a little-endian `f32`.
590 * `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
596 fn read_le_f32(&self) -> f32;
607 fn read_u8(&self) -> u8;
618 fn read_i8(&self) -> i8;
621 impl<T:Reader> ReaderUtil for T {
623 fn read_bytes(&self, len: uint) -> ~[u8] {
624 let mut bytes = vec::with_capacity(len);
625 unsafe { vec::raw::set_len(&mut bytes, len); }
627 let count = self.read(bytes, len);
629 unsafe { vec::raw::set_len(&mut bytes, count); }
633 fn read_until(&self, c: u8, include: bool) -> ~str {
636 let ch = self.read_byte();
637 if ch == -1 || ch == c as int {
638 if include && ch == c as int {
639 bytes.push(ch as u8);
643 bytes.push(ch as u8);
645 str::from_utf8(bytes)
648 fn read_line(&self) -> ~str {
649 self.read_until('\n' as u8, false)
652 fn read_chars(&self, n: uint) -> ~[char] {
653 // returns the (consumed offset, n_req), appends characters to &chars
654 fn chars_from_utf8<T:Reader>(bytes: &~[u8], chars: &mut ~[char])
657 let bytes_len = bytes.len();
658 while i < bytes_len {
660 let w = str::utf8_char_width(b0);
666 chars.push(transmute(b0 as u32));
670 // can't satisfy this char with the existing data
672 return (i - 1, end - bytes_len);
676 let next = bytes[i] as int;
678 assert!((next > -1));
679 assert_eq!(next & 192, 128);
681 val += (next & 63) as uint;
683 // See str::StrSlice::char_at
684 val += ((b0 << ((w + 1) as u8)) as uint)
685 << (w - 1) * 6 - w - 1u;
687 chars.push(transmute(val as u32));
694 // might need more bytes, but reading n will never over-read
697 let data = self.read_bytes(nbread);
699 // eof - FIXME (#2004): should we do something if
700 // we're split in a unicode char?
703 bytes.push_all(data);
704 let (offset, nbreq) = chars_from_utf8::<T>(&bytes, &mut chars);
705 let ncreq = n - chars.len();
706 // again we either know we need a certain number of bytes
707 // to complete a character, or we make sure we don't
708 // over-read by reading 1-byte per char needed
709 nbread = if ncreq > nbreq { ncreq } else { nbreq };
711 bytes = bytes.slice(offset, bytes.len()).to_owned();
717 fn read_char(&self) -> char {
718 let c = self.read_chars(1);
720 return unsafe { transmute(-1u32) }; // FIXME: #8971: unsound
722 assert_eq!(c.len(), 1);
726 fn read_c_str(&self) -> ~str {
727 self.read_until(0u8, false)
730 fn read_whole_stream(&self) -> ~[u8] {
731 let mut bytes: ~[u8] = ~[];
732 while !self.eof() { bytes.push_all(self.read_bytes(2048u)); }
736 fn each_byte(&self, it: &fn(int) -> bool) -> bool {
738 match self.read_byte() {
740 ch => if !it(ch) { return false; }
746 fn each_char(&self, it: &fn(char) -> bool) -> bool {
747 // FIXME: #8971: unsound
748 let eof: char = unsafe { transmute(-1u32) };
750 match self.read_char() {
751 c if c == eof => break,
752 ch => if !it(ch) { return false; }
758 fn each_line(&self, it: &fn(s: &str) -> bool) -> bool {
760 // include the \n, so that we can distinguish an entirely empty
761 // line read after "...\n", and the trailing empty line in
763 let mut line = self.read_until('\n' as u8, true);
765 // blank line at the end of the reader is ignored
766 if self.eof() && line.is_empty() { break; }
768 // trim the \n, so that each_line is consistent with read_line
770 if line[n-1] == '\n' as u8 {
771 unsafe { str::raw::set_len(&mut line, n-1); }
774 if !it(line) { return false; }
779 fn read_lines(&self) -> ~[~str] {
780 do vec::build(None) |push| {
781 do self.each_line |line| {
782 push(line.to_owned());
788 // FIXME int reading methods need to deal with eof - issue #2004
790 fn read_le_uint_n(&self, nbytes: uint) -> u64 {
791 assert!(nbytes > 0 && nbytes <= 8);
797 val += (self.read_u8() as u64) << pos;
804 fn read_le_int_n(&self, nbytes: uint) -> i64 {
805 extend_sign(self.read_le_uint_n(nbytes), nbytes)
808 fn read_be_uint_n(&self, nbytes: uint) -> u64 {
809 assert!(nbytes > 0 && nbytes <= 8);
815 val += (self.read_u8() as u64) << i * 8;
820 fn read_be_int_n(&self, nbytes: uint) -> i64 {
821 extend_sign(self.read_be_uint_n(nbytes), nbytes)
824 fn read_le_uint(&self) -> uint {
825 self.read_le_uint_n(uint::bytes) as uint
828 fn read_le_int(&self) -> int {
829 self.read_le_int_n(int::bytes) as int
832 fn read_be_uint(&self) -> uint {
833 self.read_be_uint_n(uint::bytes) as uint
836 fn read_be_int(&self) -> int {
837 self.read_be_int_n(int::bytes) as int
840 fn read_be_u64(&self) -> u64 {
841 self.read_be_uint_n(8) as u64
844 fn read_be_u32(&self) -> u32 {
845 self.read_be_uint_n(4) as u32
848 fn read_be_u16(&self) -> u16 {
849 self.read_be_uint_n(2) as u16
852 fn read_be_i64(&self) -> i64 {
853 self.read_be_int_n(8) as i64
856 fn read_be_i32(&self) -> i32 {
857 self.read_be_int_n(4) as i32
860 fn read_be_i16(&self) -> i16 {
861 self.read_be_int_n(2) as i16
864 fn read_be_f64(&self) -> f64 {
866 cast::transmute::<u64, f64>(self.read_be_u64())
870 fn read_be_f32(&self) -> f32 {
872 cast::transmute::<u32, f32>(self.read_be_u32())
876 fn read_le_u64(&self) -> u64 {
877 self.read_le_uint_n(8) as u64
880 fn read_le_u32(&self) -> u32 {
881 self.read_le_uint_n(4) as u32
884 fn read_le_u16(&self) -> u16 {
885 self.read_le_uint_n(2) as u16
888 fn read_le_i64(&self) -> i64 {
889 self.read_le_int_n(8) as i64
892 fn read_le_i32(&self) -> i32 {
893 self.read_le_int_n(4) as i32
896 fn read_le_i16(&self) -> i16 {
897 self.read_le_int_n(2) as i16
900 fn read_le_f64(&self) -> f64 {
902 cast::transmute::<u64, f64>(self.read_le_u64())
906 fn read_le_f32(&self) -> f32 {
908 cast::transmute::<u32, f32>(self.read_le_u32())
912 fn read_u8(&self) -> u8 {
913 self.read_byte() as u8
916 fn read_i8(&self) -> i8 {
917 self.read_byte() as i8
921 fn extend_sign(val: u64, nbytes: uint) -> i64 {
922 let shift = (8 - nbytes) * 8;
923 (val << shift) as i64 >> shift
926 // Reader implementations
928 fn convert_whence(whence: SeekStyle) -> i32 {
929 return match whence {
936 impl Reader for *libc::FILE {
937 fn read(&self, bytes: &mut [u8], len: uint) -> uint {
938 #[fixed_stack_segment]; #[inline(never)];
941 do bytes.as_mut_buf |buf_p, buf_len| {
942 assert!(buf_len >= len);
944 let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
945 len as size_t, *self) as uint;
947 match libc::ferror(*self) {
950 error!("error reading buffer");
951 error!("%s", os::last_os_error());
961 fn read_byte(&self) -> int {
962 #[fixed_stack_segment]; #[inline(never)];
965 libc::fgetc(*self) as int
968 fn eof(&self) -> bool {
969 #[fixed_stack_segment]; #[inline(never)];
972 return libc::feof(*self) != 0 as c_int;
975 fn seek(&self, offset: int, whence: SeekStyle) {
976 #[fixed_stack_segment]; #[inline(never)];
979 assert!(libc::fseek(*self,
980 offset as libc::c_long,
981 convert_whence(whence)) == 0 as c_int);
984 fn tell(&self) -> uint {
985 #[fixed_stack_segment]; #[inline(never)];
988 return libc::ftell(*self) as uint;
993 struct Wrapper<T, C> {
998 // A forwarding impl of reader that also holds on to a resource for the
999 // duration of its lifetime.
1000 // FIXME there really should be a better way to do this // #2004
1001 impl<R:Reader,C> Reader for Wrapper<R, C> {
1002 fn read(&self, bytes: &mut [u8], len: uint) -> uint {
1003 self.base.read(bytes, len)
1005 fn read_byte(&self) -> int { self.base.read_byte() }
1006 fn eof(&self) -> bool { self.base.eof() }
1007 fn seek(&self, off: int, whence: SeekStyle) {
1008 self.base.seek(off, whence)
1010 fn tell(&self) -> uint { self.base.tell() }
1013 pub struct FILERes {
1018 pub fn new(f: *libc::FILE) -> FILERes {
1023 impl Drop for FILERes {
1024 fn drop(&mut self) {
1025 #[fixed_stack_segment]; #[inline(never)];
1028 libc::fclose(self.f);
1033 pub fn FILE_reader(f: *libc::FILE, cleanup: bool) -> @Reader {
1035 @Wrapper { base: f, cleanup: FILERes::new(f) } as @Reader
1041 // FIXME (#2004): this should either be an trait-less impl, a set of
1042 // top-level functions that take a reader, or a set of default methods on
1043 // reader (which can then be called reader)
1046 * Gives a `Reader` that allows you to read values from standard input.
1051 * let stdin = std::io::stdin();
1052 * let line = stdin.read_line();
1053 * std::io::print(line);
1056 pub fn stdin() -> @Reader {
1057 #[fixed_stack_segment]; #[inline(never)];
1060 @rustrt::rust_get_stdin() as @Reader
1064 pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
1065 #[fixed_stack_segment]; #[inline(never)];
1067 let f = do path.with_c_str |pathbuf| {
1068 do "rb".with_c_str |modebuf| {
1069 unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) }
1073 if f as uint == 0u {
1074 Err(~"error opening " + path.to_str())
1076 Ok(FILE_reader(f, true))
1082 pub struct BytesReader {
1083 // FIXME(#5723) see other FIXME below
1084 // FIXME(#7268) this should also be parameterized over <'self>
1085 bytes: &'static [u8],
1089 impl Reader for BytesReader {
1090 fn read(&self, bytes: &mut [u8], len: uint) -> uint {
1091 let count = num::min(len, self.bytes.len() - *self.pos);
1093 let view = self.bytes.slice(*self.pos, self.bytes.len());
1094 vec::bytes::copy_memory(bytes, view, count);
1101 fn read_byte(&self) -> int {
1102 if *self.pos == self.bytes.len() {
1106 let b = self.bytes[*self.pos];
1111 fn eof(&self) -> bool {
1112 *self.pos == self.bytes.len()
1115 fn seek(&self, offset: int, whence: SeekStyle) {
1116 let pos = *self.pos;
1117 *self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence);
1120 fn tell(&self) -> uint {
1125 pub fn with_bytes_reader<T>(bytes: &[u8], f: &fn(@Reader) -> T) -> T {
1126 // XXX XXX XXX this is glaringly unsound
1127 // FIXME(#5723) Use a &Reader for the callback's argument. Should be:
1128 // fn with_bytes_reader<'r, T>(bytes: &'r [u8], f: &fn(&'r Reader) -> T) -> T
1129 let bytes: &'static [u8] = unsafe { cast::transmute(bytes) };
1136 pub fn with_str_reader<T>(s: &str, f: &fn(@Reader) -> T) -> T {
1137 // FIXME(#5723): As above.
1138 with_bytes_reader(s.as_bytes(), f)
1142 pub enum FileFlag { Append, Create, Truncate, NoFlag, }
1144 // What type of writer are we?
1146 pub enum WriterType { Screen, File }
1148 // FIXME (#2004): Seekable really should be orthogonal.
1149 // FIXME (#2004): eventually u64
1150 /// The raw underlying writer trait. All writers must implement this.
1153 /// Write all of the given bytes.
1154 fn write(&self, v: &[u8]);
1156 /// Move the current position within the stream. The second parameter
1157 /// determines the position that the first parameter is relative to.
1158 fn seek(&self, int, SeekStyle);
1160 /// Return the current position within the stream.
1161 fn tell(&self) -> uint;
1163 /// Flush the output buffer for this stream (if there is one).
1164 fn flush(&self) -> int;
1166 /// Determine if this Writer is writing to a file or not.
1167 fn get_type(&self) -> WriterType;
1170 impl Writer for @Writer {
1171 fn write(&self, v: &[u8]) { self.write(v) }
1172 fn seek(&self, a: int, b: SeekStyle) { self.seek(a, b) }
1173 fn tell(&self) -> uint { self.tell() }
1174 fn flush(&self) -> int { self.flush() }
1175 fn get_type(&self) -> WriterType { self.get_type() }
1178 impl<W:Writer,C> Writer for Wrapper<W, C> {
1179 fn write(&self, bs: &[u8]) { self.base.write(bs); }
1180 fn seek(&self, off: int, style: SeekStyle) { self.base.seek(off, style); }
1181 fn tell(&self) -> uint { self.base.tell() }
1182 fn flush(&self) -> int { self.base.flush() }
1183 fn get_type(&self) -> WriterType { File }
1186 impl Writer for *libc::FILE {
1187 fn write(&self, v: &[u8]) {
1188 #[fixed_stack_segment]; #[inline(never)];
1191 do v.as_imm_buf |vbuf, len| {
1192 let nout = libc::fwrite(vbuf as *c_void,
1196 if nout != len as size_t {
1197 error!("error writing buffer");
1198 error!("%s", os::last_os_error());
1204 fn seek(&self, offset: int, whence: SeekStyle) {
1205 #[fixed_stack_segment]; #[inline(never)];
1208 assert!(libc::fseek(*self,
1209 offset as libc::c_long,
1210 convert_whence(whence)) == 0 as c_int);
1213 fn tell(&self) -> uint {
1214 #[fixed_stack_segment]; #[inline(never)];
1217 libc::ftell(*self) as uint
1220 fn flush(&self) -> int {
1221 #[fixed_stack_segment]; #[inline(never)];
1224 libc::fflush(*self) as int
1227 fn get_type(&self) -> WriterType {
1228 #[fixed_stack_segment]; #[inline(never)];
1231 let fd = libc::fileno(*self);
1232 if libc::isatty(fd) == 0 { File }
1238 pub fn FILE_writer(f: *libc::FILE, cleanup: bool) -> @Writer {
1240 @Wrapper { base: f, cleanup: FILERes::new(f) } as @Writer
1246 impl Writer for fd_t {
1247 fn write(&self, v: &[u8]) {
1248 #[fixed_stack_segment]; #[inline(never)];
1251 type IoSize = libc::c_uint;
1256 type IoSize = size_t;
1258 type IoRet = libc::ssize_t;
1262 do v.as_imm_buf |vbuf, len| {
1264 let vb = ptr::offset(vbuf, count as int) as *c_void;
1265 let nout = libc::write(*self, vb, len as IoSize);
1266 if nout < 0 as IoRet {
1267 error!("error writing buffer");
1268 error!("%s", os::last_os_error());
1271 count += nout as uint;
1276 fn seek(&self, _offset: int, _whence: SeekStyle) {
1277 error!("need 64-bit foreign calls for seek, sorry");
1280 fn tell(&self) -> uint {
1281 error!("need 64-bit foreign calls for tell, sorry");
1284 fn flush(&self) -> int { 0 }
1285 fn get_type(&self) -> WriterType {
1286 #[fixed_stack_segment]; #[inline(never)];
1289 if libc::isatty(*self) == 0 { File } else { Screen }
1299 pub fn new(fd: fd_t) -> FdRes {
1304 impl Drop for FdRes {
1305 fn drop(&mut self) {
1306 #[fixed_stack_segment]; #[inline(never)];
1309 libc::close(self.fd);
1314 pub fn fd_writer(fd: fd_t, cleanup: bool) -> @Writer {
1316 @Wrapper { base: fd, cleanup: FdRes::new(fd) } as @Writer
1323 pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
1324 -> Result<@Writer, ~str> {
1325 #[fixed_stack_segment]; #[inline(never)];
1329 (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int
1333 fn wb() -> c_int { O_WRONLY as c_int }
1335 let mut fflags: c_int = wb();
1336 for f in flags.iter() {
1338 Append => fflags |= O_APPEND as c_int,
1339 Create => fflags |= O_CREAT as c_int,
1340 Truncate => fflags |= O_TRUNC as c_int,
1345 do path.with_c_str |pathbuf| {
1346 libc::open(pathbuf, fflags, (S_IRUSR | S_IWUSR) as c_int)
1349 if fd < (0 as c_int) {
1350 Err(fmt!("error opening %s: %s", path.to_str(), os::last_os_error()))
1352 Ok(fd_writer(fd, true))
1356 pub fn u64_to_le_bytes<T>(n: u64, size: uint,
1357 f: &fn(v: &[u8]) -> T) -> T {
1358 assert!(size <= 8u);
1360 1u => f(&[n as u8]),
1377 let mut bytes: ~[u8] = ~[];
1381 bytes.push((n & 255_u64) as u8);
1390 pub fn u64_to_be_bytes<T>(n: u64, size: uint,
1391 f: &fn(v: &[u8]) -> T) -> T {
1392 assert!(size <= 8u);
1394 1u => f(&[n as u8]),
1395 2u => f(&[(n >> 8) as u8,
1397 4u => f(&[(n >> 24) as u8,
1401 8u => f(&[(n >> 56) as u8,
1410 let mut bytes: ~[u8] = ~[];
1413 let shift = ((i - 1u) * 8u) as u64;
1414 bytes.push((n >> shift) as u8);
1422 pub fn u64_from_be_bytes(data: &[u8],
1427 assert!((sz <= 8u));
1428 let mut val = 0_u64;
1429 let mut pos = start;
1432 val += (data[pos] as u64) << ((sz * 8u) as u64);
1438 // FIXME: #3048 combine trait+impl (or just move these to
1439 // default methods on writer)
1440 /// Generic utility functions defined on writers.
1441 pub trait WriterUtil {
1443 /// Write a single utf-8 encoded char.
1444 fn write_char(&self, ch: char);
1446 /// Write every char in the given str, encoded as utf-8.
1447 fn write_str(&self, s: &str);
1449 /// Write the given str, as utf-8, followed by '\n'.
1450 fn write_line(&self, s: &str);
1452 /// Write the result of passing n through `int::to_str_bytes`.
1453 fn write_int(&self, n: int);
1455 /// Write the result of passing n through `uint::to_str_bytes`.
1456 fn write_uint(&self, n: uint);
1458 /// Write a little-endian uint (number of bytes depends on system).
1459 fn write_le_uint(&self, n: uint);
1461 /// Write a little-endian int (number of bytes depends on system).
1462 fn write_le_int(&self, n: int);
1464 /// Write a big-endian uint (number of bytes depends on system).
1465 fn write_be_uint(&self, n: uint);
1467 /// Write a big-endian int (number of bytes depends on system).
1468 fn write_be_int(&self, n: int);
1470 /// Write a big-endian u64 (8 bytes).
1471 fn write_be_u64(&self, n: u64);
1473 /// Write a big-endian u32 (4 bytes).
1474 fn write_be_u32(&self, n: u32);
1476 /// Write a big-endian u16 (2 bytes).
1477 fn write_be_u16(&self, n: u16);
1479 /// Write a big-endian i64 (8 bytes).
1480 fn write_be_i64(&self, n: i64);
1482 /// Write a big-endian i32 (4 bytes).
1483 fn write_be_i32(&self, n: i32);
1485 /// Write a big-endian i16 (2 bytes).
1486 fn write_be_i16(&self, n: i16);
1488 /// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
1489 fn write_be_f64(&self, f: f64);
1491 /// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
1492 fn write_be_f32(&self, f: f32);
1494 /// Write a little-endian u64 (8 bytes).
1495 fn write_le_u64(&self, n: u64);
1497 /// Write a little-endian u32 (4 bytes).
1498 fn write_le_u32(&self, n: u32);
1500 /// Write a little-endian u16 (2 bytes).
1501 fn write_le_u16(&self, n: u16);
1503 /// Write a little-endian i64 (8 bytes).
1504 fn write_le_i64(&self, n: i64);
1506 /// Write a little-endian i32 (4 bytes).
1507 fn write_le_i32(&self, n: i32);
1509 /// Write a little-endian i16 (2 bytes).
1510 fn write_le_i16(&self, n: i16);
1512 /// Write a little-endian IEEE754 double-precision floating-point
1514 fn write_le_f64(&self, f: f64);
1516 /// Write a little-endian IEEE754 single-precision floating-point
1518 fn write_le_f32(&self, f: f32);
1520 /// Write a u8 (1 byte).
1521 fn write_u8(&self, n: u8);
1523 /// Write a i8 (1 byte).
1524 fn write_i8(&self, n: i8);
1527 impl<T:Writer> WriterUtil for T {
1528 fn write_char(&self, ch: char) {
1529 if (ch as uint) < 128u {
1530 self.write(&[ch as u8]);
1532 self.write_str(str::from_char(ch));
1535 fn write_str(&self, s: &str) { self.write(s.as_bytes()) }
1536 fn write_line(&self, s: &str) {
1538 self.write_str(&"\n");
1540 fn write_int(&self, n: int) {
1541 int::to_str_bytes(n, 10u, |bytes| self.write(bytes))
1543 fn write_uint(&self, n: uint) {
1544 uint::to_str_bytes(n, 10u, |bytes| self.write(bytes))
1546 fn write_le_uint(&self, n: uint) {
1547 u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v))
1549 fn write_le_int(&self, n: int) {
1550 u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v))
1552 fn write_be_uint(&self, n: uint) {
1553 u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v))
1555 fn write_be_int(&self, n: int) {
1556 u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v))
1558 fn write_be_u64(&self, n: u64) {
1559 u64_to_be_bytes(n, 8u, |v| self.write(v))
1561 fn write_be_u32(&self, n: u32) {
1562 u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
1564 fn write_be_u16(&self, n: u16) {
1565 u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
1567 fn write_be_i64(&self, n: i64) {
1568 u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
1570 fn write_be_i32(&self, n: i32) {
1571 u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
1573 fn write_be_i16(&self, n: i16) {
1574 u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
1576 fn write_be_f64(&self, f:f64) {
1578 self.write_be_u64(cast::transmute(f))
1581 fn write_be_f32(&self, f:f32) {
1583 self.write_be_u32(cast::transmute(f))
1586 fn write_le_u64(&self, n: u64) {
1587 u64_to_le_bytes(n, 8u, |v| self.write(v))
1589 fn write_le_u32(&self, n: u32) {
1590 u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
1592 fn write_le_u16(&self, n: u16) {
1593 u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
1595 fn write_le_i64(&self, n: i64) {
1596 u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
1598 fn write_le_i32(&self, n: i32) {
1599 u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
1601 fn write_le_i16(&self, n: i16) {
1602 u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
1604 fn write_le_f64(&self, f:f64) {
1606 self.write_le_u64(cast::transmute(f))
1609 fn write_le_f32(&self, f:f32) {
1611 self.write_le_u32(cast::transmute(f))
1615 fn write_u8(&self, n: u8) { self.write([n]) }
1616 fn write_i8(&self, n: i8) { self.write([n as u8]) }
1620 pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {
1621 mk_file_writer(path, flags).and_then(|w| Ok(w))
1625 // FIXME: fileflags // #2004
1626 pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
1627 #[fixed_stack_segment]; #[inline(never)];
1630 let f = do path.with_c_str |pathbuf| {
1631 do "w".with_c_str |modebuf| {
1632 libc::fopen(pathbuf, modebuf)
1635 return if f as uint == 0u {
1636 Err(~"error opening " + path.to_str())
1638 Ok(FILE_writer(f, true))
1643 // FIXME (#2004) it would be great if this could be a const
1644 // FIXME (#2004) why are these different from the way stdin() is
1649 * Gives a `Writer` which allows you to write to the standard output.
1654 * let stdout = std::io::stdout();
1655 * stdout.write_str("hello\n");
1658 pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
1661 * Gives a `Writer` which allows you to write to standard error.
1666 * let stderr = std::io::stderr();
1667 * stderr.write_str("hello\n");
1670 pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
1673 * Prints a string to standard output.
1675 * This string will not have an implicit newline at the end. If you want
1676 * an implicit newline, please see `println`.
1681 * // print is imported into the prelude, and so is always available.
1685 pub fn print(s: &str) {
1686 stdout().write_str(s);
1690 * Prints a string to standard output, followed by a newline.
1692 * If you do not want an implicit newline, please see `print`.
1697 * // println is imported into the prelude, and so is always available.
1701 pub fn println(s: &str) {
1702 stdout().write_line(s);
1705 pub struct BytesWriter {
1711 pub fn new() -> BytesWriter {
1719 impl Writer for BytesWriter {
1720 fn write(&self, v: &[u8]) {
1721 let v_len = v.len();
1723 let bytes = &mut *self.bytes;
1724 let count = num::max(bytes.len(), *self.pos + v_len);
1725 bytes.reserve(count);
1728 vec::raw::set_len(bytes, count);
1730 let view = bytes.mut_slice(*self.pos, count);
1731 vec::bytes::copy_memory(view, v, v_len);
1737 fn seek(&self, offset: int, whence: SeekStyle) {
1738 let pos = *self.pos;
1739 let len = self.bytes.len();
1740 *self.pos = seek_in_buf(offset, pos, len, whence);
1743 fn tell(&self) -> uint {
1747 fn flush(&self) -> int {
1751 fn get_type(&self) -> WriterType {
1756 pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] {
1757 let wr = @BytesWriter::new();
1759 let @BytesWriter { bytes, _ } = wr;
1763 pub fn with_str_writer(f: &fn(@Writer)) -> ~str {
1764 str::from_utf8(with_bytes_writer(f))
1767 // Utility functions
1768 pub fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
1770 let mut bpos = pos as int;
1771 let blen = len as int;
1773 SeekSet => bpos = offset,
1774 SeekCur => bpos += offset,
1775 SeekEnd => bpos = blen + offset
1777 if bpos < 0 { bpos = 0; } else if bpos > blen { bpos = blen; }
1778 return bpos as uint;
1781 pub fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
1782 do read_whole_file(file).and_then |bytes| {
1783 if str::is_utf8(bytes) {
1784 Ok(str::from_utf8(bytes))
1786 Err(file.to_str() + " is not UTF-8")
1791 // FIXME (#2004): implement this in a low-level way. Going through the
1792 // abstractions is pointless.
1793 pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
1794 do file_reader(file).and_then |rdr| {
1795 Ok(rdr.read_whole_stream())
1802 use io::{FILERes, FdRes, fd_t};
1805 use option::{None, Option, Some};
1809 // whatever fsync does on that platform
1812 // fdatasync on linux, similiar or more on other platforms
1817 // You must additionally sync the parent directory as well!
1822 // Artifacts that need to fsync on destruction
1828 pub fn new(arg: Arg<t>) -> Res<t> {
1833 #[unsafe_destructor]
1834 impl<T> Drop for Res<T> {
1835 fn drop(&mut self) {
1836 match self.arg.opt_level {
1839 // fail hard if not succesful
1840 assert!(((self.arg.fsync_fn)(&self.arg.val, level) != -1));
1848 opt_level: Option<Level>,
1849 fsync_fn: @fn(f: &t, Level) -> int,
1852 // fsync file after executing blk
1853 // FIXME (#2004) find better way to create resources within lifetime of
1855 pub fn FILE_res_sync(file: &FILERes, opt_level: Option<Level>,
1856 blk: &fn(v: Res<*libc::FILE>)) {
1858 val: file.f, opt_level: opt_level,
1859 fsync_fn: |file, l| fsync_fd(fileno(*file), l)
1862 fn fileno(stream: *libc::FILE) -> libc::c_int {
1863 #[fixed_stack_segment]; #[inline(never)];
1864 unsafe { libc::fileno(stream) }
1868 // fsync fd after executing blk
1869 pub fn fd_res_sync(fd: &FdRes, opt_level: Option<Level>,
1870 blk: &fn(v: Res<fd_t>)) {
1872 val: fd.fd, opt_level: opt_level,
1873 fsync_fn: |fd, l| fsync_fd(*fd, l)
1877 fn fsync_fd(fd: libc::c_int, level: Level) -> int {
1878 #[fixed_stack_segment]; #[inline(never)];
1880 os::fsync_fd(fd, level) as int
1883 // Type of objects that may want to fsync
1884 pub trait FSyncable { fn fsync(&self, l: Level) -> int; }
1886 // Call o.fsync after executing blk
1887 pub fn obj_sync(o: @FSyncable, opt_level: Option<Level>,
1888 blk: &fn(v: Res<@FSyncable>)) {
1890 val: o, opt_level: opt_level,
1891 fsync_fn: |o, l| (*o).fsync(l)
1900 use io::{BytesWriter, SeekCur, SeekEnd, SeekSet};
1903 use result::{Ok, Err};
1906 use cast::transmute;
1910 let tmpfile = &Path("tmp/lib-io-test-simple.tmp");
1913 ~"A hoopy frood who really knows where his towel is.";
1914 debug!(frood.clone());
1916 let out = io::file_writer(tmpfile, [io::Create, io::Truncate]).unwrap();
1917 out.write_str(frood);
1919 let inp = io::file_reader(tmpfile).unwrap();
1920 let frood2: ~str = inp.read_c_str();
1921 debug!(frood2.clone());
1922 assert_eq!(frood, frood2);
1926 fn test_each_byte_each_char_file() {
1927 // Issue #5056 -- shouldn't include trailing EOF.
1928 let path = Path("tmp/lib-io-test-each-byte-each-char-file.tmp");
1931 // create empty, enough to reproduce a problem
1932 io::file_writer(&path, [io::Create]).unwrap();
1936 let file = io::file_reader(&path).unwrap();
1937 do file.each_byte() |_| {
1938 fail!("must be empty")
1943 let file = io::file_reader(&path).unwrap();
1944 do file.each_char() |_| {
1945 fail!("must be empty")
1951 fn test_readchars_empty() {
1952 do io::with_str_reader("") |inp| {
1953 let res : ~[char] = inp.read_chars(128);
1954 assert_eq!(res.len(), 0);
1959 fn test_read_line_utf8() {
1960 do io::with_str_reader("生锈的汤匙切肉汤hello生锈的汤匙切肉汤") |inp| {
1961 let line = inp.read_line();
1962 assert_eq!(line, ~"生锈的汤匙切肉汤hello生锈的汤匙切肉汤");
1967 fn test_read_lines() {
1968 do io::with_str_reader("a\nb\nc\n") |inp| {
1969 assert_eq!(inp.read_lines(), ~[~"a", ~"b", ~"c"]);
1972 do io::with_str_reader("a\nb\nc") |inp| {
1973 assert_eq!(inp.read_lines(), ~[~"a", ~"b", ~"c"]);
1976 do io::with_str_reader("") |inp| {
1977 assert!(inp.read_lines().is_empty());
1982 fn test_readchars_wide() {
1983 let wide_test = ~"生锈的汤匙切肉汤hello生锈的汤匙切肉汤";
1984 let ivals : ~[int] = ~[
1985 29983, 38152, 30340, 27748,
1986 21273, 20999, 32905, 27748,
1987 104, 101, 108, 108, 111,
1988 29983, 38152, 30340, 27748,
1989 21273, 20999, 32905, 27748];
1990 fn check_read_ln(len : uint, s: &str, ivals: &[int]) {
1991 do io::with_str_reader(s) |inp| {
1992 let res : ~[char] = inp.read_chars(len);
1993 if len <= ivals.len() {
1994 assert_eq!(res.len(), len);
1996 for (iv, c) in ivals.iter().zip(res.iter()) {
1997 assert!(*iv == *c as int)
2003 check_read_ln(i, wide_test, ivals);
2006 // check a long read for good measure
2007 check_read_ln(128, wide_test, ivals);
2011 fn test_readchar() {
2012 do io::with_str_reader("生") |inp| {
2013 let res = inp.read_char();
2014 assert_eq!(res as int, 29983);
2019 fn test_readchar_empty() {
2020 do io::with_str_reader("") |inp| {
2021 let res = inp.read_char();
2022 assert_eq!(res, unsafe { transmute(-1u32) }); // FIXME: #8971: unsound
2027 fn file_reader_not_exist() {
2028 match io::file_reader(&Path("not a file")) {
2030 assert_eq!(e, ~"error opening not a file");
2038 fn test_read_buffer_too_small() {
2039 let path = &Path("tmp/lib-io-test-read-buffer-too-small.tmp");
2040 // ensure the file exists
2041 io::file_writer(path, [io::Create]).unwrap();
2043 let file = io::file_reader(path).unwrap();
2044 let mut buf = vec::from_elem(5, 0u8);
2045 file.read(buf, 6); // this should fail because buf is too small
2049 fn test_read_buffer_big_enough() {
2050 let path = &Path("tmp/lib-io-test-read-buffer-big-enough.tmp");
2051 // ensure the file exists
2052 io::file_writer(path, [io::Create]).unwrap();
2054 let file = io::file_reader(path).unwrap();
2055 let mut buf = vec::from_elem(5, 0u8);
2056 file.read(buf, 4); // this should succeed because buf is big enough
2060 fn test_write_empty() {
2061 let file = io::file_writer(&Path("tmp/lib-io-test-write-empty.tmp"),
2062 [io::Create]).unwrap();
2067 fn file_writer_bad_name() {
2068 match io::file_writer(&Path("?/?"), []) {
2070 assert!(e.starts_with("error opening"));
2077 fn buffered_file_writer_bad_name() {
2078 match io::buffered_file_writer(&Path("?/?")) {
2080 assert!(e.starts_with("error opening"));
2087 fn bytes_buffer_overwrite() {
2088 let wr = BytesWriter::new();
2089 wr.write([0u8, 1u8, 2u8, 3u8]);
2090 assert!(*wr.bytes == ~[0u8, 1u8, 2u8, 3u8]);
2091 wr.seek(-2, SeekCur);
2092 wr.write([4u8, 5u8, 6u8, 7u8]);
2093 assert!(*wr.bytes == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]);
2094 wr.seek(-2, SeekEnd);
2096 wr.seek(1, SeekSet);
2098 assert!(*wr.bytes == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]);
2102 fn test_read_write_le() {
2103 let path = Path("tmp/lib-io-test-read-write-le.tmp");
2104 let uints = [0, 1, 2, 42, 10_123, 100_123_456, u64::max_value];
2106 // write the ints to the file
2108 let file = io::file_writer(&path, [io::Create]).unwrap();
2109 for i in uints.iter() {
2110 file.write_le_u64(*i);
2114 // then read them back and check that they are the same
2116 let file = io::file_reader(&path).unwrap();
2117 for i in uints.iter() {
2118 assert_eq!(file.read_le_u64(), *i);
2124 fn test_read_write_be() {
2125 let path = Path("tmp/lib-io-test-read-write-be.tmp");
2126 let uints = [0, 1, 2, 42, 10_123, 100_123_456, u64::max_value];
2128 // write the ints to the file
2130 let file = io::file_writer(&path, [io::Create]).unwrap();
2131 for i in uints.iter() {
2132 file.write_be_u64(*i);
2136 // then read them back and check that they are the same
2138 let file = io::file_reader(&path).unwrap();
2139 for i in uints.iter() {
2140 assert_eq!(file.read_be_u64(), *i);
2146 fn test_read_be_int_n() {
2147 let path = Path("tmp/lib-io-test-read-be-int-n.tmp");
2148 let ints = [i32::min_value, -123456, -42, -5, 0, 1, i32::max_value];
2150 // write the ints to the file
2152 let file = io::file_writer(&path, [io::Create]).unwrap();
2153 for i in ints.iter() {
2154 file.write_be_i32(*i);
2158 // then read them back and check that they are the same
2160 let file = io::file_reader(&path).unwrap();
2161 for i in ints.iter() {
2162 // this tests that the sign extension is working
2163 // (comparing the values as i32 would not test this)
2164 assert_eq!(file.read_be_int_n(4), *i as i64);
2170 fn test_read_f32() {
2171 let path = Path("tmp/lib-io-test-read-f32.tmp");
2172 //big-endian floating-point 8.1250
2173 let buf = ~[0x41, 0x02, 0x00, 0x00];
2176 let file = io::file_writer(&path, [io::Create]).unwrap();
2181 let file = io::file_reader(&path).unwrap();
2182 let f = file.read_be_f32();
2183 assert_eq!(f, 8.1250);
2188 fn test_read_write_f32() {
2189 let path = Path("tmp/lib-io-test-read-write-f32.tmp");
2193 let file = io::file_writer(&path, [io::Create]).unwrap();
2194 file.write_be_f32(f);
2195 file.write_le_f32(f);
2199 let file = io::file_reader(&path).unwrap();
2200 assert_eq!(file.read_be_f32(), 8.1250);
2201 assert_eq!(file.read_le_f32(), 8.1250);