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