]> git.lizzy.rs Git - rust.git/blob - src/libstd/io.rs
6335588db503c8eebce57e0ccf5bb860292b933e
[rust.git] / src / libstd / io.rs
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.
4 //
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.
10
11 /*!
12
13 The `io` module contains basic input and output routines.
14
15 A quick summary:
16
17 ## `Reader` and `Writer` traits
18
19 These traits define the minimal set of methods that anything that can do
20 input and output should implement.
21
22 ## `ReaderUtil` and `WriterUtil` traits
23
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
26 line, for example.
27
28 Generally, these richer methods are probably the ones you want to actually
29 use in day-to-day Rust.
30
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.
34
35 ## `print` and `println`
36
37 These very useful functions are defined here. You generally don't need to
38 import them, though, as the prelude already does.
39
40 ## `stdin`, `stdout`, and `stderr`
41
42 These functions return references to the classic three file descriptors. They
43 implement `Reader` and `Writer`, where appropriate.
44
45 */
46
47 #[allow(missing_doc)];
48
49 use result::Result;
50
51 use clone::Clone;
52 use container::Container;
53 use int;
54 use libc;
55 use libc::{c_int, c_long, c_void, size_t, ssize_t};
56 use libc::consts::os::posix88::*;
57 use num;
58 use os;
59 use cast;
60 use path::Path;
61 use ops::Drop;
62 use iterator::IteratorUtil;
63 use ptr;
64 use result;
65 use str;
66 use str::{StrSlice, OwnedStr, StrUtil};
67 use to_str::ToStr;
68 use uint;
69 use vec;
70 use vec::{MutableVector, ImmutableVector, OwnedVector, OwnedCopyableVector, CopyableVector};
71
72 #[allow(non_camel_case_types)] // not sure what to do about this
73 pub type fd_t = c_int;
74
75 pub mod rustrt {
76     use libc;
77
78     #[abi = "cdecl"]
79     #[link_name = "rustrt"]
80     extern {
81         pub unsafe fn rust_get_stdin() -> *libc::FILE;
82         pub unsafe fn rust_get_stdout() -> *libc::FILE;
83         pub unsafe fn rust_get_stderr() -> *libc::FILE;
84     }
85 }
86
87 // Reading
88
89 // FIXME (#2004): This is all buffered. We might need an unbuffered variant
90 // as well
91 /**
92 * The SeekStyle enum describes the relationship between the position
93 * we'd like to seek to from our current position. It's used as an argument
94 * to the `seek` method defined on the `Reader` trait.
95 *
96 * There are three seek styles:
97 *
98 * 1. `SeekSet` means that the new position should become our position.
99 * 2. `SeekCur` means that we should seek from the current position.
100 * 3. `SeekEnd` means that we should seek from the end.
101 *
102 * # Examples
103 *
104 * None right now.
105 */
106 pub enum SeekStyle { SeekSet, SeekEnd, SeekCur, }
107
108
109 /**
110 * The core Reader trait. All readers must implement this trait.
111 *
112 * # Examples
113 *
114 * None right now.
115 */
116 pub trait Reader {
117     // FIXME (#2004): Seekable really should be orthogonal.
118
119     // FIXME (#2982): This should probably return an error.
120     /**
121     * Reads bytes and puts them into `bytes`, advancing the cursor. Returns the
122     * number of bytes read.
123     *
124     * The number of bytes to be read is `len` or the end of the file,
125     * whichever comes first.
126     *
127     * The buffer must be at least `len` bytes long.
128     *
129     * `read` is conceptually similar to C's `fread` function.
130     *
131     * # Examples
132     *
133     * None right now.
134     */
135     fn read(&self, bytes: &mut [u8], len: uint) -> uint;
136
137     /**
138     * Reads a single byte, advancing the cursor.
139     *
140     * In the case of an EOF or an error, returns a negative value.
141     *
142     * `read_byte` is conceptually similar to C's `getc` function.
143     *
144     * # Examples
145     *
146     * None right now.
147     */
148     fn read_byte(&self) -> int;
149
150     /**
151     * Returns a boolean value: are we currently at EOF?
152     *
153     * `eof` is conceptually similar to C's `feof` function.
154     *
155     * # Examples
156     *
157     * None right now.
158     */
159     fn eof(&self) -> bool;
160
161     /**
162     * Seek to a given `position` in the stream.
163     *
164     * Takes an optional SeekStyle, which affects how we seek from the
165     * position. See `SeekStyle` docs for more details.
166     *
167     * `seek` is conceptually similar to C's `fseek` function.
168     *
169     * # Examples
170     *
171     * None right now.
172     */
173     fn seek(&self, position: int, style: SeekStyle);
174
175     /**
176     * Returns the current position within the stream.
177     *
178     * `tell` is conceptually similar to C's `ftell` function.
179     *
180     * # Examples
181     *
182     * None right now.
183     */
184     fn tell(&self) -> uint;
185 }
186
187 impl Reader for @Reader {
188     fn read(&self, bytes: &mut [u8], len: uint) -> uint {
189         self.read(bytes, len)
190     }
191     fn read_byte(&self) -> int {
192         self.read_byte()
193     }
194     fn eof(&self) -> bool {
195         self.eof()
196     }
197     fn seek(&self, position: int, style: SeekStyle) {
198         self.seek(position, style)
199     }
200     fn tell(&self) -> uint {
201         self.tell()
202     }
203 }
204
205 /**
206 * The `ReaderUtil` trait is a home for many of the utility functions
207 * a particular Reader should implement.
208 *
209 * The default `Reader` trait is focused entirely on bytes. `ReaderUtil` is based
210 * on higher-level concepts like 'chars' and 'lines.'
211 *
212 * # Examples:
213 *
214 * None right now.
215 */
216 pub trait ReaderUtil {
217
218     /**
219     * Reads `len` number of bytes, and gives you a new vector back.
220     *
221     * # Examples
222     *
223     * None right now.
224     */
225     fn read_bytes(&self, len: uint) -> ~[u8];
226
227     /**
228     * Reads up until a specific byte is seen or EOF.
229     *
230     * The `include` parameter specifies if the character should be included
231     * in the returned string.
232     *
233     * # Examples
234     *
235     * None right now.
236     */
237     fn read_until(&self, c: u8, include: bool) -> ~str;
238
239     /**
240     * Reads up until the first '\n' or EOF.
241     *
242     * The '\n' is not included in the result.
243     *
244     * # Examples
245     *
246     * None right now.
247     */
248     fn read_line(&self) -> ~str;
249
250     /**
251     * Reads `n` chars.
252     *
253     * Assumes that those chars are UTF-8 encoded.
254     *
255     * The '\n' is not included in the result.
256     *
257     * # Examples
258     *
259     * None right now.
260     */
261     fn read_chars(&self, n: uint) -> ~[char];
262
263     /**
264     * Reads a single UTF-8 encoded char.
265     *
266     * # Examples
267     *
268     * None right now.
269     */
270     fn read_char(&self) -> char;
271
272     /**
273     * Reads up until the first null byte or EOF.
274     *
275     * The null byte is not returned.
276     *
277     * # Examples
278     *
279     * None right now.
280     */
281     fn read_c_str(&self) -> ~str;
282
283     /**
284     * Reads all remaining data in the stream.
285     *
286     * # Examples
287     *
288     * None right now.
289     */
290     fn read_whole_stream(&self) -> ~[u8];
291
292     /**
293     * Iterate over every byte until EOF or the iterator breaks.
294     *
295     * # Examples
296     *
297     * None right now.
298     */
299     fn each_byte(&self, it: &fn(int) -> bool) -> bool;
300
301     /**
302     * Iterate over every char until EOF or the iterator breaks.
303     *
304     * # Examples
305     *
306     * None right now.
307     */
308     fn each_char(&self, it: &fn(char) -> bool) -> bool;
309
310     /**
311     * Iterate over every line until EOF or the iterator breaks.
312     *
313     * # Examples
314     *
315     * None right now.
316     */
317     fn each_line(&self, it: &fn(&str) -> bool) -> bool;
318
319     /**
320     * Reads all of the lines in the stream.
321     *
322     * Returns a vector of those lines.
323     *
324     * # Examples
325     *
326     * None right now.
327     */
328     fn read_lines(&self) -> ~[~str];
329
330     /**
331     * Reads `n` little-endian unsigned integer bytes.
332     *
333     * `n` must be between 1 and 8, inclusive.
334     *
335     * # Examples
336     *
337     * None right now.
338     */
339     fn read_le_uint_n(&self, nbytes: uint) -> u64;
340
341     /**
342     * Reads `n` little-endian signed integer bytes.
343     *
344     * `n` must be between 1 and 8, inclusive.
345     *
346     * # Examples
347     *
348     * None right now.
349     */
350     fn read_le_int_n(&self, nbytes: uint) -> i64;
351
352     /**
353     * Reads `n` big-endian unsigned integer bytes.
354     *
355     * `n` must be between 1 and 8, inclusive.
356     *
357     * # Examples
358     *
359     * None right now.
360     */
361     fn read_be_uint_n(&self, nbytes: uint) -> u64;
362
363     /**
364     * Reads `n` big-endian signed integer bytes.
365     *
366     * `n` must be between 1 and 8, inclusive.
367     *
368     * # Examples
369     *
370     * None right now.
371     */
372     fn read_be_int_n(&self, nbytes: uint) -> i64;
373
374     /**
375     * Reads a little-endian unsigned integer.
376     *
377     * The number of bytes returned is system-dependant.
378     *
379     * # Examples
380     *
381     * None right now.
382     */
383     fn read_le_uint(&self) -> uint;
384
385     /**
386     * Reads a little-endian integer.
387     *
388     * The number of bytes returned is system-dependant.
389     *
390     * # Examples
391     *
392     * None right now.
393     */
394     fn read_le_int(&self) -> int;
395
396     /**
397     * Reads a big-endian unsigned integer.
398     *
399     * The number of bytes returned is system-dependant.
400     *
401     * # Examples
402     *
403     * None right now.
404     */
405     fn read_be_uint(&self) -> uint;
406
407     /**
408     * Reads a big-endian integer.
409     *
410     * The number of bytes returned is system-dependant.
411     *
412     * # Examples
413     *
414     * None right now.
415     */
416     fn read_be_int(&self) -> int;
417
418     /**
419     * Reads a big-endian `u64`.
420     *
421     * `u64`s are 8 bytes long.
422     *
423     * # Examples
424     *
425     * None right now.
426     */
427     fn read_be_u64(&self) -> u64;
428
429     /**
430     * Reads a big-endian `u32`.
431     *
432     * `u32`s are 4 bytes long.
433     *
434     * # Examples
435     *
436     * None right now.
437     */
438     fn read_be_u32(&self) -> u32;
439
440     /**
441     * Reads a big-endian `u16`.
442     *
443     * `u16`s are 2 bytes long.
444     *
445     * # Examples
446     *
447     * None right now.
448     */
449     fn read_be_u16(&self) -> u16;
450
451     /**
452     * Reads a big-endian `i64`.
453     *
454     * `i64`s are 8 bytes long.
455     *
456     * # Examples
457     *
458     * None right now.
459     */
460     fn read_be_i64(&self) -> i64;
461
462     /**
463     * Reads a big-endian `i32`.
464     *
465     * `i32`s are 4 bytes long.
466     *
467     * # Examples
468     *
469     * None right now.
470     */
471     fn read_be_i32(&self) -> i32;
472
473     /**
474     * Reads a big-endian `i16`.
475     *
476     * `i16`s are 2 bytes long.
477     *
478     * # Examples
479     *
480     * None right now.
481     */
482     fn read_be_i16(&self) -> i16;
483
484     /**
485     * Reads a big-endian `f64`.
486     *
487     * `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
488     *
489     * # Examples
490     *
491     * None right now.
492     */
493     fn read_be_f64(&self) -> f64;
494
495     /**
496     * Reads a big-endian `f32`.
497     *
498     * `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
499     *
500     * # Examples
501     *
502     * None right now.
503     */
504     fn read_be_f32(&self) -> f32;
505
506     /**
507     * Reads a little-endian `u64`.
508     *
509     * `u64`s are 8 bytes long.
510     *
511     * # Examples
512     *
513     * None right now.
514     */
515     fn read_le_u64(&self) -> u64;
516
517     /**
518     * Reads a little-endian `u32`.
519     *
520     * `u32`s are 4 bytes long.
521     *
522     * # Examples
523     *
524     * None right now.
525     */
526     fn read_le_u32(&self) -> u32;
527
528     /**
529     * Reads a little-endian `u16`.
530     *
531     * `u16`s are 2 bytes long.
532     *
533     * # Examples
534     *
535     * None right now.
536     */
537     fn read_le_u16(&self) -> u16;
538
539     /**
540     * Reads a little-endian `i64`.
541     *
542     * `i64`s are 8 bytes long.
543     *
544     * # Examples
545     *
546     * None right now.
547     */
548     fn read_le_i64(&self) -> i64;
549
550     /**
551     * Reads a little-endian `i32`.
552     *
553     * `i32`s are 4 bytes long.
554     *
555     * # Examples
556     *
557     * None right now.
558     */
559     fn read_le_i32(&self) -> i32;
560
561     /**
562     * Reads a little-endian `i16`.
563     *
564     * `i16`s are 2 bytes long.
565     *
566     * # Examples
567     *
568     * None right now.
569     */
570     fn read_le_i16(&self) -> i16;
571
572     /**
573     * Reads a little-endian `f64`.
574     *
575     * `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
576     *
577     * # Examples
578     *
579     * None right now.
580     */
581     fn read_le_f64(&self) -> f64;
582
583     /**
584     * Reads a little-endian `f32`.
585     *
586     * `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
587     *
588     * # Examples
589     *
590     * None right now.
591     */
592     fn read_le_f32(&self) -> f32;
593
594     /**
595     * Read a u8.
596     *
597     * `u8`s are 1 byte.
598     *
599     * # Examples
600     *
601     * None right now.
602     */
603     fn read_u8(&self) -> u8;
604
605     /**
606     * Read an i8.
607     *
608     * `i8`s are 1 byte.
609     *
610     * # Examples
611     *
612     * None right now.
613     */
614     fn read_i8(&self) -> i8;
615 }
616
617 impl<T:Reader> ReaderUtil for T {
618
619     fn read_bytes(&self,len: uint) -> ~[u8] {
620         let mut bytes = vec::with_capacity(len);
621         unsafe { vec::raw::set_len(&mut bytes, len); }
622
623         let count = self.read(bytes, len);
624
625         unsafe { vec::raw::set_len(&mut bytes, count); }
626         bytes
627     }
628
629     fn read_until(&self, c: u8, include: bool) -> ~str {
630         let mut bytes = ~[];
631         loop {
632             let ch = self.read_byte();
633             if ch == -1 || ch == c as int {
634                 if include && ch == c as int {
635                     bytes.push(ch as u8);
636                 }
637                 break;
638             }
639             bytes.push(ch as u8);
640         }
641         str::from_bytes(bytes)
642     }
643
644     fn read_line(&self) -> ~str {
645         self.read_until('\n' as u8, false)
646     }
647
648     fn read_chars(&self, n: uint) -> ~[char] {
649         // returns the (consumed offset, n_req), appends characters to &chars
650         fn chars_from_bytes<T:Reader>(bytes: &~[u8], chars: &mut ~[char])
651             -> (uint, uint) {
652             let mut i = 0;
653             let bytes_len = bytes.len();
654             while i < bytes_len {
655                 let b0 = bytes[i];
656                 let w = str::utf8_char_width(b0);
657                 let end = i + w;
658                 i += 1;
659                 assert!((w > 0));
660                 if w == 1 {
661                     chars.push(b0 as char);
662                     loop;
663                 }
664                 // can't satisfy this char with the existing data
665                 if end > bytes_len {
666                     return (i - 1, end - bytes_len);
667                 }
668                 let mut val = 0;
669                 while i < end {
670                     let next = bytes[i] as int;
671                     i += 1;
672                     assert!((next > -1));
673                     assert_eq!(next & 192, 128);
674                     val <<= 6;
675                     val += (next & 63) as uint;
676                 }
677                 // See str::StrSlice::char_at
678                 val += ((b0 << ((w + 1) as u8)) as uint)
679                     << (w - 1) * 6 - w - 1u;
680                 chars.push(val as char);
681             }
682             return (i, 0);
683         }
684         let mut bytes = ~[];
685         let mut chars = ~[];
686         // might need more bytes, but reading n will never over-read
687         let mut nbread = n;
688         while nbread > 0 {
689             let data = self.read_bytes(nbread);
690             if data.is_empty() {
691                 // eof - FIXME (#2004): should we do something if
692                 // we're split in a unicode char?
693                 break;
694             }
695             bytes.push_all(data);
696             let (offset, nbreq) = chars_from_bytes::<T>(&bytes, &mut chars);
697             let ncreq = n - chars.len();
698             // again we either know we need a certain number of bytes
699             // to complete a character, or we make sure we don't
700             // over-read by reading 1-byte per char needed
701             nbread = if ncreq > nbreq { ncreq } else { nbreq };
702             if nbread > 0 {
703                 bytes = bytes.slice(offset, bytes.len()).to_owned();
704             }
705         }
706         chars
707     }
708
709     fn read_char(&self) -> char {
710         let c = self.read_chars(1);
711         if c.len() == 0 {
712             return -1 as char; // FIXME will this stay valid? // #2004
713         }
714         assert_eq!(c.len(), 1);
715         return c[0];
716     }
717
718     fn read_c_str(&self) -> ~str {
719         self.read_until(0u8, false)
720     }
721
722     fn read_whole_stream(&self) -> ~[u8] {
723         let mut bytes: ~[u8] = ~[];
724         while !self.eof() { bytes.push_all(self.read_bytes(2048u)); }
725         bytes
726     }
727
728     fn each_byte(&self, it: &fn(int) -> bool) -> bool {
729         while !self.eof() {
730             if !it(self.read_byte()) { return false; }
731         }
732         return true;
733     }
734
735     fn each_char(&self, it: &fn(char) -> bool) -> bool {
736         while !self.eof() {
737             if !it(self.read_char()) { return false; }
738         }
739         return true;
740     }
741
742     fn each_line(&self, it: &fn(s: &str) -> bool) -> bool {
743         while !self.eof() {
744             // include the \n, so that we can distinguish an entirely empty
745             // line read after "...\n", and the trailing empty line in
746             // "...\n\n".
747             let mut line = self.read_until('\n' as u8, true);
748
749             // blank line at the end of the reader is ignored
750             if self.eof() && line.is_empty() { break; }
751
752             // trim the \n, so that each_line is consistent with read_line
753             let n = line.len();
754             if line[n-1] == '\n' as u8 {
755                 unsafe { str::raw::set_len(&mut line, n-1); }
756             }
757
758             if !it(line) { return false; }
759         }
760         return true;
761     }
762
763     fn read_lines(&self) -> ~[~str] {
764         do vec::build |push| {
765             for self.each_line |line| {
766                 push(str::to_owned(line));
767             }
768         }
769     }
770
771     // FIXME int reading methods need to deal with eof - issue #2004
772
773     fn read_le_uint_n(&self, nbytes: uint) -> u64 {
774         assert!(nbytes > 0 && nbytes <= 8);
775
776         let mut val = 0u64;
777         let mut pos = 0;
778         let mut i = nbytes;
779         while i > 0 {
780             val += (self.read_u8() as u64) << pos;
781             pos += 8;
782             i -= 1;
783         }
784         val
785     }
786
787     fn read_le_int_n(&self, nbytes: uint) -> i64 {
788         extend_sign(self.read_le_uint_n(nbytes), nbytes)
789     }
790
791     fn read_be_uint_n(&self, nbytes: uint) -> u64 {
792         assert!(nbytes > 0 && nbytes <= 8);
793
794         let mut val = 0u64;
795         let mut i = nbytes;
796         while i > 0 {
797             i -= 1;
798             val += (self.read_u8() as u64) << i * 8;
799         }
800         val
801     }
802
803     fn read_be_int_n(&self, nbytes: uint) -> i64 {
804         extend_sign(self.read_be_uint_n(nbytes), nbytes)
805     }
806
807     fn read_le_uint(&self) -> uint {
808         self.read_le_uint_n(uint::bytes) as uint
809     }
810
811     fn read_le_int(&self) -> int {
812         self.read_le_int_n(int::bytes) as int
813     }
814
815     fn read_be_uint(&self) -> uint {
816         self.read_be_uint_n(uint::bytes) as uint
817     }
818
819     fn read_be_int(&self) -> int {
820         self.read_be_int_n(int::bytes) as int
821     }
822
823     fn read_be_u64(&self) -> u64 {
824         self.read_be_uint_n(8) as u64
825     }
826
827     fn read_be_u32(&self) -> u32 {
828         self.read_be_uint_n(4) as u32
829     }
830
831     fn read_be_u16(&self) -> u16 {
832         self.read_be_uint_n(2) as u16
833     }
834
835     fn read_be_i64(&self) -> i64 {
836         self.read_be_int_n(8) as i64
837     }
838
839     fn read_be_i32(&self) -> i32 {
840         self.read_be_int_n(4) as i32
841     }
842
843     fn read_be_i16(&self) -> i16 {
844         self.read_be_int_n(2) as i16
845     }
846
847     fn read_be_f64(&self) -> f64 {
848         unsafe {
849             cast::transmute::<u64, f64>(self.read_be_u64())
850         }
851     }
852
853     fn read_be_f32(&self) -> f32 {
854         unsafe {
855             cast::transmute::<u32, f32>(self.read_be_u32())
856         }
857     }
858
859     fn read_le_u64(&self) -> u64 {
860         self.read_le_uint_n(8) as u64
861     }
862
863     fn read_le_u32(&self) -> u32 {
864         self.read_le_uint_n(4) as u32
865     }
866
867     fn read_le_u16(&self) -> u16 {
868         self.read_le_uint_n(2) as u16
869     }
870
871     fn read_le_i64(&self) -> i64 {
872         self.read_le_int_n(8) as i64
873     }
874
875     fn read_le_i32(&self) -> i32 {
876         self.read_le_int_n(4) as i32
877     }
878
879     fn read_le_i16(&self) -> i16 {
880         self.read_le_int_n(2) as i16
881     }
882
883     fn read_le_f64(&self) -> f64 {
884         unsafe {
885             cast::transmute::<u64, f64>(self.read_le_u64())
886         }
887     }
888
889     fn read_le_f32(&self) -> f32 {
890         unsafe {
891             cast::transmute::<u32, f32>(self.read_le_u32())
892         }
893     }
894
895     fn read_u8(&self) -> u8 {
896         self.read_byte() as u8
897     }
898
899     fn read_i8(&self) -> i8 {
900         self.read_byte() as i8
901     }
902 }
903
904 fn extend_sign(val: u64, nbytes: uint) -> i64 {
905     let shift = (8 - nbytes) * 8;
906     (val << shift) as i64 >> shift
907 }
908
909 // Reader implementations
910
911 fn convert_whence(whence: SeekStyle) -> i32 {
912     return match whence {
913       SeekSet => 0i32,
914       SeekCur => 1i32,
915       SeekEnd => 2i32
916     };
917 }
918
919 impl Reader for *libc::FILE {
920     fn read(&self, bytes: &mut [u8], len: uint) -> uint {
921         unsafe {
922             do bytes.as_mut_buf |buf_p, buf_len| {
923                 assert!(buf_len >= len);
924
925                 let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
926                                         len as size_t, *self) as uint;
927                 if count < len {
928                   match libc::ferror(*self) {
929                     0 => (),
930                     _ => {
931                       error!("error reading buffer");
932                       error!("%s", os::last_os_error());
933                       fail!();
934                     }
935                   }
936                 }
937
938                 count
939             }
940         }
941     }
942     fn read_byte(&self) -> int {
943         unsafe {
944             libc::fgetc(*self) as int
945         }
946     }
947     fn eof(&self) -> bool {
948         unsafe {
949             return libc::feof(*self) != 0 as c_int;
950         }
951     }
952     fn seek(&self, offset: int, whence: SeekStyle) {
953         unsafe {
954             assert!(libc::fseek(*self,
955                                      offset as c_long,
956                                      convert_whence(whence)) == 0 as c_int);
957         }
958     }
959     fn tell(&self) -> uint {
960         unsafe {
961             return libc::ftell(*self) as uint;
962         }
963     }
964 }
965
966 struct Wrapper<T, C> {
967     base: T,
968     cleanup: C,
969 }
970
971 // A forwarding impl of reader that also holds on to a resource for the
972 // duration of its lifetime.
973 // FIXME there really should be a better way to do this // #2004
974 impl<R:Reader,C> Reader for Wrapper<R, C> {
975     fn read(&self, bytes: &mut [u8], len: uint) -> uint {
976         self.base.read(bytes, len)
977     }
978     fn read_byte(&self) -> int { self.base.read_byte() }
979     fn eof(&self) -> bool { self.base.eof() }
980     fn seek(&self, off: int, whence: SeekStyle) {
981         self.base.seek(off, whence)
982     }
983     fn tell(&self) -> uint { self.base.tell() }
984 }
985
986 pub struct FILERes {
987     f: *libc::FILE,
988 }
989
990 impl FILERes {
991     pub fn new(f: *libc::FILE) -> FILERes {
992         FILERes { f: f }
993     }
994 }
995
996 impl Drop for FILERes {
997     fn drop(&self) {
998         unsafe {
999             libc::fclose(self.f);
1000         }
1001     }
1002 }
1003
1004 pub fn FILE_reader(f: *libc::FILE, cleanup: bool) -> @Reader {
1005     if cleanup {
1006         @Wrapper { base: f, cleanup: FILERes::new(f) } as @Reader
1007     } else {
1008         @f as @Reader
1009     }
1010 }
1011
1012 // FIXME (#2004): this should either be an trait-less impl, a set of
1013 // top-level functions that take a reader, or a set of default methods on
1014 // reader (which can then be called reader)
1015
1016 /**
1017 * Gives a `Reader` that allows you to read values from standard input.
1018 *
1019 * # Example
1020 *
1021 * ~~~ {.rust}
1022 * let stdin = core::io::stdin();
1023 * let line = stdin.read_line();
1024 * core::io::print(line);
1025 * ~~~
1026 */
1027 pub fn stdin() -> @Reader {
1028     unsafe {
1029         @rustrt::rust_get_stdin() as @Reader
1030     }
1031 }
1032
1033 pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
1034     let f = do path.to_str().as_c_str |pathbuf| {
1035         do "r".as_c_str |modebuf| {
1036             unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) }
1037         }
1038     };
1039
1040     if f as uint == 0u {
1041         result::Err(~"error opening " + path.to_str())
1042     } else {
1043         result::Ok(FILE_reader(f, true))
1044     }
1045 }
1046
1047
1048 // Byte readers
1049 pub struct BytesReader {
1050     // FIXME(#5723) see other FIXME below
1051     // FIXME(#7268) this should also be parameterized over <'self>
1052     bytes: &'static [u8],
1053     pos: @mut uint
1054 }
1055
1056 impl Reader for BytesReader {
1057     fn read(&self, bytes: &mut [u8], len: uint) -> uint {
1058         let count = num::min(len, self.bytes.len() - *self.pos);
1059
1060         let view = self.bytes.slice(*self.pos, self.bytes.len());
1061         vec::bytes::copy_memory(bytes, view, count);
1062
1063         *self.pos += count;
1064
1065         count
1066     }
1067
1068     fn read_byte(&self) -> int {
1069         if *self.pos == self.bytes.len() {
1070             return -1;
1071         }
1072
1073         let b = self.bytes[*self.pos];
1074         *self.pos += 1u;
1075         b as int
1076     }
1077
1078     fn eof(&self) -> bool {
1079         *self.pos == self.bytes.len()
1080     }
1081
1082     fn seek(&self, offset: int, whence: SeekStyle) {
1083         let pos = *self.pos;
1084         *self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence);
1085     }
1086
1087     fn tell(&self) -> uint {
1088         *self.pos
1089     }
1090 }
1091
1092 pub fn with_bytes_reader<T>(bytes: &[u8], f: &fn(@Reader) -> T) -> T {
1093     // XXX XXX XXX this is glaringly unsound
1094     // FIXME(#5723) Use a &Reader for the callback's argument. Should be:
1095     // fn with_bytes_reader<'r, T>(bytes: &'r [u8], f: &fn(&'r Reader) -> T) -> T
1096     let bytes: &'static [u8] = unsafe { cast::transmute(bytes) };
1097     f(@BytesReader {
1098         bytes: bytes,
1099         pos: @mut 0
1100     } as @Reader)
1101 }
1102
1103 pub fn with_str_reader<T>(s: &str, f: &fn(@Reader) -> T) -> T {
1104     // FIXME(#5723): As above.
1105     with_bytes_reader(s.as_bytes(), f)
1106 }
1107
1108 // Writing
1109 pub enum FileFlag { Append, Create, Truncate, NoFlag, }
1110
1111 // What type of writer are we?
1112 #[deriving(Eq)]
1113 pub enum WriterType { Screen, File }
1114
1115 // FIXME (#2004): Seekable really should be orthogonal.
1116 // FIXME (#2004): eventually u64
1117 /// The raw underlying writer trait. All writers must implement this.
1118 pub trait Writer {
1119
1120     /// Write all of the given bytes.
1121     fn write(&self, v: &[u8]);
1122
1123     /// Move the current position within the stream. The second parameter
1124     /// determines the position that the first parameter is relative to.
1125     fn seek(&self, int, SeekStyle);
1126
1127     /// Return the current position within the stream.
1128     fn tell(&self) -> uint;
1129
1130     /// Flush the output buffer for this stream (if there is one).
1131     fn flush(&self) -> int;
1132
1133     /// Determine if this Writer is writing to a file or not.
1134     fn get_type(&self) -> WriterType;
1135 }
1136
1137 impl Writer for @Writer {
1138     fn write(&self, v: &[u8]) { self.write(v) }
1139     fn seek(&self, a: int, b: SeekStyle) { self.seek(a, b) }
1140     fn tell(&self) -> uint { self.tell() }
1141     fn flush(&self) -> int { self.flush() }
1142     fn get_type(&self) -> WriterType { self.get_type() }
1143 }
1144
1145 impl<W:Writer,C> Writer for Wrapper<W, C> {
1146     fn write(&self, bs: &[u8]) { self.base.write(bs); }
1147     fn seek(&self, off: int, style: SeekStyle) { self.base.seek(off, style); }
1148     fn tell(&self) -> uint { self.base.tell() }
1149     fn flush(&self) -> int { self.base.flush() }
1150     fn get_type(&self) -> WriterType { File }
1151 }
1152
1153 impl Writer for *libc::FILE {
1154     fn write(&self, v: &[u8]) {
1155         unsafe {
1156             do v.as_imm_buf |vbuf, len| {
1157                 let nout = libc::fwrite(vbuf as *c_void,
1158                                         1,
1159                                         len as size_t,
1160                                         *self);
1161                 if nout != len as size_t {
1162                     error!("error writing buffer");
1163                     error!("%s", os::last_os_error());
1164                     fail!();
1165                 }
1166             }
1167         }
1168     }
1169     fn seek(&self, offset: int, whence: SeekStyle) {
1170         unsafe {
1171             assert!(libc::fseek(*self,
1172                                      offset as c_long,
1173                                      convert_whence(whence)) == 0 as c_int);
1174         }
1175     }
1176     fn tell(&self) -> uint {
1177         unsafe {
1178             libc::ftell(*self) as uint
1179         }
1180     }
1181     fn flush(&self) -> int {
1182         unsafe {
1183             libc::fflush(*self) as int
1184         }
1185     }
1186     fn get_type(&self) -> WriterType {
1187         unsafe {
1188             let fd = libc::fileno(*self);
1189             if libc::isatty(fd) == 0 { File   }
1190             else                     { Screen }
1191         }
1192     }
1193 }
1194
1195 pub fn FILE_writer(f: *libc::FILE, cleanup: bool) -> @Writer {
1196     if cleanup {
1197         @Wrapper { base: f, cleanup: FILERes::new(f) } as @Writer
1198     } else {
1199         @f as @Writer
1200     }
1201 }
1202
1203 impl Writer for fd_t {
1204     fn write(&self, v: &[u8]) {
1205         unsafe {
1206             let mut count = 0u;
1207             do v.as_imm_buf |vbuf, len| {
1208                 while count < len {
1209                     let vb = ptr::offset(vbuf, count) as *c_void;
1210                     let nout = libc::write(*self, vb, len as size_t);
1211                     if nout < 0 as ssize_t {
1212                         error!("error writing buffer");
1213                         error!("%s", os::last_os_error());
1214                         fail!();
1215                     }
1216                     count += nout as uint;
1217                 }
1218             }
1219         }
1220     }
1221     fn seek(&self, _offset: int, _whence: SeekStyle) {
1222         error!("need 64-bit foreign calls for seek, sorry");
1223         fail!();
1224     }
1225     fn tell(&self) -> uint {
1226         error!("need 64-bit foreign calls for tell, sorry");
1227         fail!();
1228     }
1229     fn flush(&self) -> int { 0 }
1230     fn get_type(&self) -> WriterType {
1231         unsafe {
1232             if libc::isatty(*self) == 0 { File } else { Screen }
1233         }
1234     }
1235 }
1236
1237 pub struct FdRes {
1238     fd: fd_t,
1239 }
1240
1241 impl FdRes {
1242     pub fn new(fd: fd_t) -> FdRes {
1243         FdRes { fd: fd }
1244     }
1245 }
1246
1247 impl Drop for FdRes {
1248     fn drop(&self) {
1249         unsafe {
1250             libc::close(self.fd);
1251         }
1252     }
1253 }
1254
1255 pub fn fd_writer(fd: fd_t, cleanup: bool) -> @Writer {
1256     if cleanup {
1257         @Wrapper { base: fd, cleanup: FdRes::new(fd) } as @Writer
1258     } else {
1259         @fd as @Writer
1260     }
1261 }
1262
1263
1264 pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
1265                    -> Result<@Writer, ~str> {
1266     #[cfg(windows)]
1267     fn wb() -> c_int {
1268       (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int
1269     }
1270
1271     #[cfg(unix)]
1272     fn wb() -> c_int { O_WRONLY as c_int }
1273
1274     let mut fflags: c_int = wb();
1275     for flags.iter().advance |f| {
1276         match *f {
1277           Append => fflags |= O_APPEND as c_int,
1278           Create => fflags |= O_CREAT as c_int,
1279           Truncate => fflags |= O_TRUNC as c_int,
1280           NoFlag => ()
1281         }
1282     }
1283     let fd = unsafe {
1284         do path.to_str().as_c_str |pathbuf| {
1285             libc::open(pathbuf, fflags,
1286                        (S_IRUSR | S_IWUSR) as c_int)
1287         }
1288     };
1289     if fd < (0 as c_int) {
1290         result::Err(fmt!("error opening %s: %s", path.to_str(),
1291                          os::last_os_error()))
1292     } else {
1293         result::Ok(fd_writer(fd, true))
1294     }
1295 }
1296
1297 pub fn u64_to_le_bytes<T>(n: u64, size: uint,
1298                           f: &fn(v: &[u8]) -> T) -> T {
1299     assert!(size <= 8u);
1300     match size {
1301       1u => f(&[n as u8]),
1302       2u => f(&[n as u8,
1303               (n >> 8) as u8]),
1304       4u => f(&[n as u8,
1305               (n >> 8) as u8,
1306               (n >> 16) as u8,
1307               (n >> 24) as u8]),
1308       8u => f(&[n as u8,
1309               (n >> 8) as u8,
1310               (n >> 16) as u8,
1311               (n >> 24) as u8,
1312               (n >> 32) as u8,
1313               (n >> 40) as u8,
1314               (n >> 48) as u8,
1315               (n >> 56) as u8]),
1316       _ => {
1317
1318         let mut bytes: ~[u8] = ~[];
1319         let mut i = size;
1320         let mut n = n;
1321         while i > 0u {
1322             bytes.push((n & 255_u64) as u8);
1323             n >>= 8_u64;
1324             i -= 1u;
1325         }
1326         f(bytes)
1327       }
1328     }
1329 }
1330
1331 pub fn u64_to_be_bytes<T>(n: u64, size: uint,
1332                            f: &fn(v: &[u8]) -> T) -> T {
1333     assert!(size <= 8u);
1334     match size {
1335       1u => f(&[n as u8]),
1336       2u => f(&[(n >> 8) as u8,
1337               n as u8]),
1338       4u => f(&[(n >> 24) as u8,
1339               (n >> 16) as u8,
1340               (n >> 8) as u8,
1341               n as u8]),
1342       8u => f(&[(n >> 56) as u8,
1343               (n >> 48) as u8,
1344               (n >> 40) as u8,
1345               (n >> 32) as u8,
1346               (n >> 24) as u8,
1347               (n >> 16) as u8,
1348               (n >> 8) as u8,
1349               n as u8]),
1350       _ => {
1351         let mut bytes: ~[u8] = ~[];
1352         let mut i = size;
1353         while i > 0u {
1354             let shift = ((i - 1u) * 8u) as u64;
1355             bytes.push((n >> shift) as u8);
1356             i -= 1u;
1357         }
1358         f(bytes)
1359       }
1360     }
1361 }
1362
1363 pub fn u64_from_be_bytes(data: &[u8],
1364                          start: uint,
1365                          size: uint)
1366                       -> u64 {
1367     let mut sz = size;
1368     assert!((sz <= 8u));
1369     let mut val = 0_u64;
1370     let mut pos = start;
1371     while sz > 0u {
1372         sz -= 1u;
1373         val += (data[pos] as u64) << ((sz * 8u) as u64);
1374         pos += 1u;
1375     }
1376     return val;
1377 }
1378
1379 // FIXME: #3048 combine trait+impl (or just move these to
1380 // default methods on writer)
1381 /// Generic utility functions defined on writers.
1382 pub trait WriterUtil {
1383
1384     /// Write a single utf-8 encoded char.
1385     fn write_char(&self, ch: char);
1386
1387     /// Write every char in the given str, encoded as utf-8.
1388     fn write_str(&self, s: &str);
1389
1390     /// Write the given str, as utf-8, followed by '\n'.
1391     fn write_line(&self, s: &str);
1392
1393     /// Write the result of passing n through `int::to_str_bytes`.
1394     fn write_int(&self, n: int);
1395
1396     /// Write the result of passing n through `uint::to_str_bytes`.
1397     fn write_uint(&self, n: uint);
1398
1399     /// Write a little-endian uint (number of bytes depends on system).
1400     fn write_le_uint(&self, n: uint);
1401
1402     /// Write a little-endian int (number of bytes depends on system).
1403     fn write_le_int(&self, n: int);
1404
1405     /// Write a big-endian uint (number of bytes depends on system).
1406     fn write_be_uint(&self, n: uint);
1407
1408     /// Write a big-endian int (number of bytes depends on system).
1409     fn write_be_int(&self, n: int);
1410
1411     /// Write a big-endian u64 (8 bytes).
1412     fn write_be_u64(&self, n: u64);
1413
1414     /// Write a big-endian u32 (4 bytes).
1415     fn write_be_u32(&self, n: u32);
1416
1417     /// Write a big-endian u16 (2 bytes).
1418     fn write_be_u16(&self, n: u16);
1419
1420     /// Write a big-endian i64 (8 bytes).
1421     fn write_be_i64(&self, n: i64);
1422
1423     /// Write a big-endian i32 (4 bytes).
1424     fn write_be_i32(&self, n: i32);
1425
1426     /// Write a big-endian i16 (2 bytes).
1427     fn write_be_i16(&self, n: i16);
1428
1429     /// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
1430     fn write_be_f64(&self, f: f64);
1431
1432     /// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
1433     fn write_be_f32(&self, f: f32);
1434
1435     /// Write a little-endian u64 (8 bytes).
1436     fn write_le_u64(&self, n: u64);
1437
1438     /// Write a little-endian u32 (4 bytes).
1439     fn write_le_u32(&self, n: u32);
1440
1441     /// Write a little-endian u16 (2 bytes).
1442     fn write_le_u16(&self, n: u16);
1443
1444     /// Write a little-endian i64 (8 bytes).
1445     fn write_le_i64(&self, n: i64);
1446
1447     /// Write a little-endian i32 (4 bytes).
1448     fn write_le_i32(&self, n: i32);
1449
1450     /// Write a little-endian i16 (2 bytes).
1451     fn write_le_i16(&self, n: i16);
1452
1453     /// Write a little-endian IEEE754 double-precision floating-point
1454     /// (8 bytes).
1455     fn write_le_f64(&self, f: f64);
1456
1457     /// Write a litten-endian IEEE754 single-precision floating-point
1458     /// (4 bytes).
1459     fn write_le_f32(&self, f: f32);
1460
1461     /// Write a u8 (1 byte).
1462     fn write_u8(&self, n: u8);
1463
1464     /// Write a i8 (1 byte).
1465     fn write_i8(&self, n: i8);
1466 }
1467
1468 impl<T:Writer> WriterUtil for T {
1469     fn write_char(&self, ch: char) {
1470         if (ch as uint) < 128u {
1471             self.write(&[ch as u8]);
1472         } else {
1473             self.write_str(str::from_char(ch));
1474         }
1475     }
1476     fn write_str(&self, s: &str) { self.write(s.as_bytes()) }
1477     fn write_line(&self, s: &str) {
1478         self.write_str(s);
1479         self.write_str(&"\n");
1480     }
1481     fn write_int(&self, n: int) {
1482         int::to_str_bytes(n, 10u, |bytes| self.write(bytes))
1483     }
1484     fn write_uint(&self, n: uint) {
1485         uint::to_str_bytes(n, 10u, |bytes| self.write(bytes))
1486     }
1487     fn write_le_uint(&self, n: uint) {
1488         u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v))
1489     }
1490     fn write_le_int(&self, n: int) {
1491         u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v))
1492     }
1493     fn write_be_uint(&self, n: uint) {
1494         u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v))
1495     }
1496     fn write_be_int(&self, n: int) {
1497         u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v))
1498     }
1499     fn write_be_u64(&self, n: u64) {
1500         u64_to_be_bytes(n, 8u, |v| self.write(v))
1501     }
1502     fn write_be_u32(&self, n: u32) {
1503         u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
1504     }
1505     fn write_be_u16(&self, n: u16) {
1506         u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
1507     }
1508     fn write_be_i64(&self, n: i64) {
1509         u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
1510     }
1511     fn write_be_i32(&self, n: i32) {
1512         u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
1513     }
1514     fn write_be_i16(&self, n: i16) {
1515         u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
1516     }
1517     fn write_be_f64(&self, f:f64) {
1518         unsafe {
1519             self.write_be_u64(cast::transmute(f))
1520         }
1521     }
1522     fn write_be_f32(&self, f:f32) {
1523         unsafe {
1524             self.write_be_u32(cast::transmute(f))
1525         }
1526     }
1527     fn write_le_u64(&self, n: u64) {
1528         u64_to_le_bytes(n, 8u, |v| self.write(v))
1529     }
1530     fn write_le_u32(&self, n: u32) {
1531         u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
1532     }
1533     fn write_le_u16(&self, n: u16) {
1534         u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
1535     }
1536     fn write_le_i64(&self, n: i64) {
1537         u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
1538     }
1539     fn write_le_i32(&self, n: i32) {
1540         u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
1541     }
1542     fn write_le_i16(&self, n: i16) {
1543         u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
1544     }
1545     fn write_le_f64(&self, f:f64) {
1546         unsafe {
1547             self.write_le_u64(cast::transmute(f))
1548         }
1549     }
1550     fn write_le_f32(&self, f:f32) {
1551         unsafe {
1552             self.write_le_u32(cast::transmute(f))
1553         }
1554     }
1555
1556     fn write_u8(&self, n: u8) { self.write([n]) }
1557     fn write_i8(&self, n: i8) { self.write([n as u8]) }
1558
1559 }
1560
1561 pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {
1562     mk_file_writer(path, flags).chain(|w| result::Ok(w))
1563 }
1564
1565
1566 // FIXME: fileflags // #2004
1567 pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
1568     unsafe {
1569         let f = do path.to_str().as_c_str |pathbuf| {
1570             do "w".as_c_str |modebuf| {
1571                 libc::fopen(pathbuf, modebuf)
1572             }
1573         };
1574         return if f as uint == 0u {
1575             result::Err(~"error opening " + path.to_str())
1576         } else {
1577             result::Ok(FILE_writer(f, true))
1578         }
1579     }
1580 }
1581
1582 // FIXME (#2004) it would be great if this could be a const
1583 // FIXME (#2004) why are these different from the way stdin() is
1584 // implemented?
1585
1586
1587 /**
1588 * Gives a `Writer` which allows you to write to the standard output.
1589 *
1590 * # Example
1591 *
1592 * ~~~ {.rust}
1593 * let stdout = core::io::stdout();
1594 * stdout.write_str("hello\n");
1595 * ~~~
1596 */
1597 pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
1598
1599 /**
1600 * Gives a `Writer` which allows you to write to standard error.
1601 *
1602 * # Example
1603 *
1604 * ~~~ {.rust}
1605 * let stderr = core::io::stderr();
1606 * stderr.write_str("hello\n");
1607 * ~~~
1608 */
1609 pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
1610
1611 /**
1612 * Prints a string to standard output.
1613 *
1614 * This string will not have an implicit newline at the end. If you want
1615 * an implicit newline, please see `println`.
1616 *
1617 * # Example
1618 *
1619 * ~~~ {.rust}
1620 * // print is imported into the prelude, and so is always available.
1621 * print("hello");
1622 * ~~~
1623 */
1624 pub fn print(s: &str) {
1625     stdout().write_str(s);
1626 }
1627
1628 /**
1629 * Prints a string to standard output, followed by a newline.
1630 *
1631 * If you do not want an implicit newline, please see `print`.
1632 *
1633 * # Example
1634 *
1635 * ~~~ {.rust}
1636 * // println is imported into the prelude, and so is always available.
1637 * println("hello");
1638 * ~~~
1639 */
1640 pub fn println(s: &str) {
1641     stdout().write_line(s);
1642 }
1643
1644 pub struct BytesWriter {
1645     bytes: @mut ~[u8],
1646     pos: @mut uint,
1647 }
1648
1649 impl BytesWriter {
1650     pub fn new() -> BytesWriter {
1651         BytesWriter {
1652             bytes: @mut ~[],
1653             pos: @mut 0
1654         }
1655     }
1656 }
1657
1658 impl Writer for BytesWriter {
1659     fn write(&self, v: &[u8]) {
1660         let v_len = v.len();
1661
1662         let bytes = &mut *self.bytes;
1663         let count = num::max(bytes.len(), *self.pos + v_len);
1664         bytes.reserve(count);
1665
1666         unsafe {
1667             vec::raw::set_len(bytes, count);
1668
1669             let view = bytes.mut_slice(*self.pos, count);
1670             vec::bytes::copy_memory(view, v, v_len);
1671         }
1672
1673         *self.pos += v_len;
1674     }
1675
1676     fn seek(&self, offset: int, whence: SeekStyle) {
1677         let pos = *self.pos;
1678         let len = self.bytes.len();
1679         *self.pos = seek_in_buf(offset, pos, len, whence);
1680     }
1681
1682     fn tell(&self) -> uint {
1683         *self.pos
1684     }
1685
1686     fn flush(&self) -> int {
1687         0
1688     }
1689
1690     fn get_type(&self) -> WriterType {
1691         File
1692     }
1693 }
1694
1695 pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] {
1696     let wr = @BytesWriter::new();
1697     f(wr as @Writer);
1698     let @BytesWriter { bytes, _ } = wr;
1699     (*bytes).clone()
1700 }
1701
1702 pub fn with_str_writer(f: &fn(@Writer)) -> ~str {
1703     let mut v = with_bytes_writer(f);
1704
1705     // Make sure the vector has a trailing null and is proper utf8.
1706     v.push(0);
1707     assert!(str::is_utf8(v));
1708
1709     unsafe {
1710         ::cast::transmute(v)
1711     }
1712 }
1713
1714 // Utility functions
1715 pub fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
1716    uint {
1717     let mut bpos = pos as int;
1718     let blen = len as int;
1719     match whence {
1720       SeekSet => bpos = offset,
1721       SeekCur => bpos += offset,
1722       SeekEnd => bpos = blen + offset
1723     }
1724     if bpos < 0 { bpos = 0; } else if bpos > blen { bpos = blen; }
1725     return bpos as uint;
1726 }
1727
1728 pub fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
1729     result::chain(read_whole_file(file), |bytes| {
1730         if str::is_utf8(bytes) {
1731             result::Ok(str::from_bytes(bytes))
1732         } else {
1733             result::Err(file.to_str() + " is not UTF-8")
1734         }
1735     })
1736 }
1737
1738 // FIXME (#2004): implement this in a low-level way. Going through the
1739 // abstractions is pointless.
1740 pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
1741     result::chain(file_reader(file), |rdr| {
1742         result::Ok(rdr.read_whole_stream())
1743     })
1744 }
1745
1746 // fsync related
1747
1748 pub mod fsync {
1749     use io::{FILERes, FdRes, fd_t};
1750     use libc;
1751     use ops::Drop;
1752     use option::{None, Option, Some};
1753     use os;
1754
1755     pub enum Level {
1756         // whatever fsync does on that platform
1757         FSync,
1758
1759         // fdatasync on linux, similiar or more on other platforms
1760         FDataSync,
1761
1762         // full fsync
1763         //
1764         // You must additionally sync the parent directory as well!
1765         FullFSync,
1766     }
1767
1768
1769     // Artifacts that need to fsync on destruction
1770     pub struct Res<t> {
1771         arg: Arg<t>,
1772     }
1773
1774     impl <t> Res<t> {
1775         pub fn new(arg: Arg<t>) -> Res<t> {
1776             Res { arg: arg }
1777         }
1778     }
1779
1780     #[unsafe_destructor]
1781     impl<T> Drop for Res<T> {
1782         fn drop(&self) {
1783             match self.arg.opt_level {
1784                 None => (),
1785                 Some(level) => {
1786                   // fail hard if not succesful
1787                   assert!(((self.arg.fsync_fn)(&self.arg.val, level) != -1));
1788                 }
1789             }
1790         }
1791     }
1792
1793     pub struct Arg<t> {
1794         val: t,
1795         opt_level: Option<Level>,
1796         fsync_fn: @fn(f: &t, Level) -> int,
1797     }
1798
1799     // fsync file after executing blk
1800     // FIXME (#2004) find better way to create resources within lifetime of
1801     // outer res
1802     pub fn FILE_res_sync(file: &FILERes, opt_level: Option<Level>,
1803                          blk: &fn(v: Res<*libc::FILE>)) {
1804         blk(Res::new(Arg {
1805             val: file.f, opt_level: opt_level,
1806             fsync_fn: |file, l| {
1807                 unsafe {
1808                     os::fsync_fd(libc::fileno(*file), l) as int
1809                 }
1810             }
1811         }));
1812     }
1813
1814     // fsync fd after executing blk
1815     pub fn fd_res_sync(fd: &FdRes, opt_level: Option<Level>,
1816                        blk: &fn(v: Res<fd_t>)) {
1817         blk(Res::new(Arg {
1818             val: fd.fd, opt_level: opt_level,
1819             fsync_fn: |fd, l| os::fsync_fd(*fd, l) as int
1820         }));
1821     }
1822
1823     // Type of objects that may want to fsync
1824     pub trait FSyncable { fn fsync(&self, l: Level) -> int; }
1825
1826     // Call o.fsync after executing blk
1827     pub fn obj_sync(o: @FSyncable, opt_level: Option<Level>,
1828                     blk: &fn(v: Res<@FSyncable>)) {
1829         blk(Res::new(Arg {
1830             val: o, opt_level: opt_level,
1831             fsync_fn: |o, l| (*o).fsync(l)
1832         }));
1833     }
1834 }
1835
1836 #[cfg(test)]
1837 mod tests {
1838     use i32;
1839     use io::{BytesWriter, SeekCur, SeekEnd, SeekSet};
1840     use io;
1841     use path::Path;
1842     use result;
1843     use u64;
1844     use vec;
1845
1846     #[test]
1847     fn test_simple() {
1848         let tmpfile = &Path("tmp/lib-io-test-simple.tmp");
1849         debug!(tmpfile);
1850         let frood: ~str =
1851             ~"A hoopy frood who really knows where his towel is.";
1852         debug!(frood.clone());
1853         {
1854             let out: @io::Writer =
1855                 result::unwrap(
1856                     io::file_writer(tmpfile, [io::Create, io::Truncate]));
1857             out.write_str(frood);
1858         }
1859         let inp: @io::Reader = result::unwrap(io::file_reader(tmpfile));
1860         let frood2: ~str = inp.read_c_str();
1861         debug!(frood2.clone());
1862         assert_eq!(frood, frood2);
1863     }
1864
1865     #[test]
1866     fn test_readchars_empty() {
1867         do io::with_str_reader("") |inp| {
1868             let res : ~[char] = inp.read_chars(128);
1869             assert_eq!(res.len(), 0);
1870         }
1871     }
1872
1873     #[test]
1874     fn test_read_line_utf8() {
1875         do io::with_str_reader("生锈的汤匙切肉汤hello生锈的汤匙切肉汤") |inp| {
1876             let line = inp.read_line();
1877             assert_eq!(line, ~"生锈的汤匙切肉汤hello生锈的汤匙切肉汤");
1878         }
1879     }
1880
1881     #[test]
1882     fn test_read_lines() {
1883         do io::with_str_reader("a\nb\nc\n") |inp| {
1884             assert_eq!(inp.read_lines(), ~[~"a", ~"b", ~"c"]);
1885         }
1886
1887         do io::with_str_reader("a\nb\nc") |inp| {
1888             assert_eq!(inp.read_lines(), ~[~"a", ~"b", ~"c"]);
1889         }
1890
1891         do io::with_str_reader("") |inp| {
1892             assert!(inp.read_lines().is_empty());
1893         }
1894     }
1895
1896     #[test]
1897     fn test_readchars_wide() {
1898         let wide_test = ~"生锈的汤匙切肉汤hello生锈的汤匙切肉汤";
1899         let ivals : ~[int] = ~[
1900             29983, 38152, 30340, 27748,
1901             21273, 20999, 32905, 27748,
1902             104, 101, 108, 108, 111,
1903             29983, 38152, 30340, 27748,
1904             21273, 20999, 32905, 27748];
1905         fn check_read_ln(len : uint, s: &str, ivals: &[int]) {
1906             do io::with_str_reader(s) |inp| {
1907                 let res : ~[char] = inp.read_chars(len);
1908                 if len <= ivals.len() {
1909                     assert_eq!(res.len(), len);
1910                 }
1911                 for ivals.iter().zip(res.iter()).advance |(iv, c)| {
1912                     assert!(*iv == *c as int)
1913                 }
1914             }
1915         }
1916         let mut i = 0;
1917         while i < 8 {
1918             check_read_ln(i, wide_test, ivals);
1919             i += 1;
1920         }
1921         // check a long read for good measure
1922         check_read_ln(128, wide_test, ivals);
1923     }
1924
1925     #[test]
1926     fn test_readchar() {
1927         do io::with_str_reader("生") |inp| {
1928             let res : char = inp.read_char();
1929             assert_eq!(res as int, 29983);
1930         }
1931     }
1932
1933     #[test]
1934     fn test_readchar_empty() {
1935         do io::with_str_reader("") |inp| {
1936             let res : char = inp.read_char();
1937             assert_eq!(res as int, -1);
1938         }
1939     }
1940
1941     #[test]
1942     fn file_reader_not_exist() {
1943         match io::file_reader(&Path("not a file")) {
1944           result::Err(e) => {
1945             assert_eq!(e, ~"error opening not a file");
1946           }
1947           result::Ok(_) => fail!()
1948         }
1949     }
1950
1951     #[test]
1952     #[should_fail]
1953     #[ignore(cfg(windows))]
1954     fn test_read_buffer_too_small() {
1955         let path = &Path("tmp/lib-io-test-read-buffer-too-small.tmp");
1956         // ensure the file exists
1957         io::file_writer(path, [io::Create]).unwrap();
1958
1959         let file = io::file_reader(path).unwrap();
1960         let mut buf = vec::from_elem(5, 0u8);
1961         file.read(buf, 6); // this should fail because buf is too small
1962     }
1963
1964     #[test]
1965     fn test_read_buffer_big_enough() {
1966         let path = &Path("tmp/lib-io-test-read-buffer-big-enough.tmp");
1967         // ensure the file exists
1968         io::file_writer(path, [io::Create]).unwrap();
1969
1970         let file = io::file_reader(path).unwrap();
1971         let mut buf = vec::from_elem(5, 0u8);
1972         file.read(buf, 4); // this should succeed because buf is big enough
1973     }
1974
1975     #[test]
1976     fn test_write_empty() {
1977         let file = io::file_writer(&Path("tmp/lib-io-test-write-empty.tmp"),
1978                                    [io::Create]).unwrap();
1979         file.write([]);
1980     }
1981
1982     #[test]
1983     fn file_writer_bad_name() {
1984         match io::file_writer(&Path("?/?"), []) {
1985           result::Err(e) => {
1986             assert!(e.starts_with("error opening"));
1987           }
1988           result::Ok(_) => fail!()
1989         }
1990     }
1991
1992     #[test]
1993     fn buffered_file_writer_bad_name() {
1994         match io::buffered_file_writer(&Path("?/?")) {
1995           result::Err(e) => {
1996             assert!(e.starts_with("error opening"));
1997           }
1998           result::Ok(_) => fail!()
1999         }
2000     }
2001
2002     #[test]
2003     fn bytes_buffer_overwrite() {
2004         let wr = BytesWriter::new();
2005         wr.write([0u8, 1u8, 2u8, 3u8]);
2006         assert!(*wr.bytes == ~[0u8, 1u8, 2u8, 3u8]);
2007         wr.seek(-2, SeekCur);
2008         wr.write([4u8, 5u8, 6u8, 7u8]);
2009         assert!(*wr.bytes == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]);
2010         wr.seek(-2, SeekEnd);
2011         wr.write([8u8]);
2012         wr.seek(1, SeekSet);
2013         wr.write([9u8]);
2014         assert!(*wr.bytes == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]);
2015     }
2016
2017     #[test]
2018     fn test_read_write_le() {
2019         let path = Path("tmp/lib-io-test-read-write-le.tmp");
2020         let uints = [0, 1, 2, 42, 10_123, 100_123_456, u64::max_value];
2021
2022         // write the ints to the file
2023         {
2024             let file = io::file_writer(&path, [io::Create]).unwrap();
2025             for uints.iter().advance |i| {
2026                 file.write_le_u64(*i);
2027             }
2028         }
2029
2030         // then read them back and check that they are the same
2031         {
2032             let file = io::file_reader(&path).unwrap();
2033             for uints.iter().advance |i| {
2034                 assert_eq!(file.read_le_u64(), *i);
2035             }
2036         }
2037     }
2038
2039     #[test]
2040     fn test_read_write_be() {
2041         let path = Path("tmp/lib-io-test-read-write-be.tmp");
2042         let uints = [0, 1, 2, 42, 10_123, 100_123_456, u64::max_value];
2043
2044         // write the ints to the file
2045         {
2046             let file = io::file_writer(&path, [io::Create]).unwrap();
2047             for uints.iter().advance |i| {
2048                 file.write_be_u64(*i);
2049             }
2050         }
2051
2052         // then read them back and check that they are the same
2053         {
2054             let file = io::file_reader(&path).unwrap();
2055             for uints.iter().advance |i| {
2056                 assert_eq!(file.read_be_u64(), *i);
2057             }
2058         }
2059     }
2060
2061     #[test]
2062     fn test_read_be_int_n() {
2063         let path = Path("tmp/lib-io-test-read-be-int-n.tmp");
2064         let ints = [i32::min_value, -123456, -42, -5, 0, 1, i32::max_value];
2065
2066         // write the ints to the file
2067         {
2068             let file = io::file_writer(&path, [io::Create]).unwrap();
2069             for ints.iter().advance |i| {
2070                 file.write_be_i32(*i);
2071             }
2072         }
2073
2074         // then read them back and check that they are the same
2075         {
2076             let file = io::file_reader(&path).unwrap();
2077             for ints.iter().advance |i| {
2078                 // this tests that the sign extension is working
2079                 // (comparing the values as i32 would not test this)
2080                 assert_eq!(file.read_be_int_n(4), *i as i64);
2081             }
2082         }
2083     }
2084
2085     #[test]
2086     fn test_read_f32() {
2087         let path = Path("tmp/lib-io-test-read-f32.tmp");
2088         //big-endian floating-point 8.1250
2089         let buf = ~[0x41, 0x02, 0x00, 0x00];
2090
2091         {
2092             let file = io::file_writer(&path, [io::Create]).unwrap();
2093             file.write(buf);
2094         }
2095
2096         {
2097             let file = io::file_reader(&path).unwrap();
2098             let f = file.read_be_f32();
2099             assert_eq!(f, 8.1250);
2100         }
2101     }
2102
2103     #[test]
2104     fn test_read_write_f32() {
2105         let path = Path("tmp/lib-io-test-read-write-f32.tmp");
2106         let f:f32 = 8.1250;
2107
2108         {
2109             let file = io::file_writer(&path, [io::Create]).unwrap();
2110             file.write_be_f32(f);
2111             file.write_le_f32(f);
2112         }
2113
2114         {
2115             let file = io::file_reader(&path).unwrap();
2116             assert_eq!(file.read_be_f32(), 8.1250);
2117             assert_eq!(file.read_le_f32(), 8.1250);
2118         }
2119     }
2120 }