]> git.lizzy.rs Git - rust.git/blob - src/libstd/io.rs
Add externfn macro and correctly label fixed_stack_segments
[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         #[fixed_stack_segment]; #[inline(never)];
932
933         unsafe {
934             do bytes.as_mut_buf |buf_p, buf_len| {
935                 assert!(buf_len >= len);
936
937                 let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
938                                         len as size_t, *self) as uint;
939                 if count < len {
940                   match libc::ferror(*self) {
941                     0 => (),
942                     _ => {
943                       error!("error reading buffer");
944                       error!("%s", os::last_os_error());
945                       fail!();
946                     }
947                   }
948                 }
949
950                 count
951             }
952         }
953     }
954     fn read_byte(&self) -> int {
955         #[fixed_stack_segment]; #[inline(never)];
956
957         unsafe {
958             libc::fgetc(*self) as int
959         }
960     }
961     fn eof(&self) -> bool {
962         #[fixed_stack_segment]; #[inline(never)];
963
964         unsafe {
965             return libc::feof(*self) != 0 as c_int;
966         }
967     }
968     fn seek(&self, offset: int, whence: SeekStyle) {
969         #[fixed_stack_segment]; #[inline(never)];
970
971         unsafe {
972             assert!(libc::fseek(*self,
973                                      offset as c_long,
974                                      convert_whence(whence)) == 0 as c_int);
975         }
976     }
977     fn tell(&self) -> uint {
978         #[fixed_stack_segment]; #[inline(never)];
979
980         unsafe {
981             return libc::ftell(*self) as uint;
982         }
983     }
984 }
985
986 struct Wrapper<T, C> {
987     base: T,
988     cleanup: C,
989 }
990
991 // A forwarding impl of reader that also holds on to a resource for the
992 // duration of its lifetime.
993 // FIXME there really should be a better way to do this // #2004
994 impl<R:Reader,C> Reader for Wrapper<R, C> {
995     fn read(&self, bytes: &mut [u8], len: uint) -> uint {
996         self.base.read(bytes, len)
997     }
998     fn read_byte(&self) -> int { self.base.read_byte() }
999     fn eof(&self) -> bool { self.base.eof() }
1000     fn seek(&self, off: int, whence: SeekStyle) {
1001         self.base.seek(off, whence)
1002     }
1003     fn tell(&self) -> uint { self.base.tell() }
1004 }
1005
1006 pub struct FILERes {
1007     f: *libc::FILE,
1008 }
1009
1010 impl FILERes {
1011     pub fn new(f: *libc::FILE) -> FILERes {
1012         FILERes { f: f }
1013     }
1014 }
1015
1016 impl Drop for FILERes {
1017     fn drop(&self) {
1018         #[fixed_stack_segment]; #[inline(never)];
1019
1020         unsafe {
1021             libc::fclose(self.f);
1022         }
1023     }
1024 }
1025
1026 pub fn FILE_reader(f: *libc::FILE, cleanup: bool) -> @Reader {
1027     if cleanup {
1028         @Wrapper { base: f, cleanup: FILERes::new(f) } as @Reader
1029     } else {
1030         @f as @Reader
1031     }
1032 }
1033
1034 // FIXME (#2004): this should either be an trait-less impl, a set of
1035 // top-level functions that take a reader, or a set of default methods on
1036 // reader (which can then be called reader)
1037
1038 /**
1039 * Gives a `Reader` that allows you to read values from standard input.
1040 *
1041 * # Example
1042 *
1043 * ~~~ {.rust}
1044 * let stdin = std::io::stdin();
1045 * let line = stdin.read_line();
1046 * std::io::print(line);
1047 * ~~~
1048 */
1049 pub fn stdin() -> @Reader {
1050     #[fixed_stack_segment]; #[inline(never)];
1051
1052     unsafe {
1053         @rustrt::rust_get_stdin() as @Reader
1054     }
1055 }
1056
1057 pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
1058     #[fixed_stack_segment]; #[inline(never)];
1059
1060     let f = do path.with_c_str |pathbuf| {
1061         do "rb".with_c_str |modebuf| {
1062             unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) }
1063         }
1064     };
1065
1066     if f as uint == 0u {
1067         Err(~"error opening " + path.to_str())
1068     } else {
1069         Ok(FILE_reader(f, true))
1070     }
1071 }
1072
1073
1074 // Byte readers
1075 pub struct BytesReader {
1076     // FIXME(#5723) see other FIXME below
1077     // FIXME(#7268) this should also be parameterized over <'self>
1078     bytes: &'static [u8],
1079     pos: @mut uint
1080 }
1081
1082 impl Reader for BytesReader {
1083     fn read(&self, bytes: &mut [u8], len: uint) -> uint {
1084         let count = num::min(len, self.bytes.len() - *self.pos);
1085
1086         let view = self.bytes.slice(*self.pos, self.bytes.len());
1087         vec::bytes::copy_memory(bytes, view, count);
1088
1089         *self.pos += count;
1090
1091         count
1092     }
1093
1094     fn read_byte(&self) -> int {
1095         if *self.pos == self.bytes.len() {
1096             return -1;
1097         }
1098
1099         let b = self.bytes[*self.pos];
1100         *self.pos += 1u;
1101         b as int
1102     }
1103
1104     fn eof(&self) -> bool {
1105         *self.pos == self.bytes.len()
1106     }
1107
1108     fn seek(&self, offset: int, whence: SeekStyle) {
1109         let pos = *self.pos;
1110         *self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence);
1111     }
1112
1113     fn tell(&self) -> uint {
1114         *self.pos
1115     }
1116 }
1117
1118 pub fn with_bytes_reader<T>(bytes: &[u8], f: &fn(@Reader) -> T) -> T {
1119     // XXX XXX XXX this is glaringly unsound
1120     // FIXME(#5723) Use a &Reader for the callback's argument. Should be:
1121     // fn with_bytes_reader<'r, T>(bytes: &'r [u8], f: &fn(&'r Reader) -> T) -> T
1122     let bytes: &'static [u8] = unsafe { cast::transmute(bytes) };
1123     f(@BytesReader {
1124         bytes: bytes,
1125         pos: @mut 0
1126     } as @Reader)
1127 }
1128
1129 pub fn with_str_reader<T>(s: &str, f: &fn(@Reader) -> T) -> T {
1130     // FIXME(#5723): As above.
1131     with_bytes_reader(s.as_bytes(), f)
1132 }
1133
1134 // Writing
1135 pub enum FileFlag { Append, Create, Truncate, NoFlag, }
1136
1137 // What type of writer are we?
1138 #[deriving(Eq)]
1139 pub enum WriterType { Screen, File }
1140
1141 // FIXME (#2004): Seekable really should be orthogonal.
1142 // FIXME (#2004): eventually u64
1143 /// The raw underlying writer trait. All writers must implement this.
1144 pub trait Writer {
1145
1146     /// Write all of the given bytes.
1147     fn write(&self, v: &[u8]);
1148
1149     /// Move the current position within the stream. The second parameter
1150     /// determines the position that the first parameter is relative to.
1151     fn seek(&self, int, SeekStyle);
1152
1153     /// Return the current position within the stream.
1154     fn tell(&self) -> uint;
1155
1156     /// Flush the output buffer for this stream (if there is one).
1157     fn flush(&self) -> int;
1158
1159     /// Determine if this Writer is writing to a file or not.
1160     fn get_type(&self) -> WriterType;
1161 }
1162
1163 impl Writer for @Writer {
1164     fn write(&self, v: &[u8]) { self.write(v) }
1165     fn seek(&self, a: int, b: SeekStyle) { self.seek(a, b) }
1166     fn tell(&self) -> uint { self.tell() }
1167     fn flush(&self) -> int { self.flush() }
1168     fn get_type(&self) -> WriterType { self.get_type() }
1169 }
1170
1171 impl<W:Writer,C> Writer for Wrapper<W, C> {
1172     fn write(&self, bs: &[u8]) { self.base.write(bs); }
1173     fn seek(&self, off: int, style: SeekStyle) { self.base.seek(off, style); }
1174     fn tell(&self) -> uint { self.base.tell() }
1175     fn flush(&self) -> int { self.base.flush() }
1176     fn get_type(&self) -> WriterType { File }
1177 }
1178
1179 impl Writer for *libc::FILE {
1180     fn write(&self, v: &[u8]) {
1181         #[fixed_stack_segment]; #[inline(never)];
1182
1183         unsafe {
1184             do v.as_imm_buf |vbuf, len| {
1185                 let nout = libc::fwrite(vbuf as *c_void,
1186                                         1,
1187                                         len as size_t,
1188                                         *self);
1189                 if nout != len as size_t {
1190                     error!("error writing buffer");
1191                     error!("%s", os::last_os_error());
1192                     fail!();
1193                 }
1194             }
1195         }
1196     }
1197     fn seek(&self, offset: int, whence: SeekStyle) {
1198         #[fixed_stack_segment]; #[inline(never)];
1199
1200         unsafe {
1201             assert!(libc::fseek(*self,
1202                                      offset as c_long,
1203                                      convert_whence(whence)) == 0 as c_int);
1204         }
1205     }
1206     fn tell(&self) -> uint {
1207         #[fixed_stack_segment]; #[inline(never)];
1208
1209         unsafe {
1210             libc::ftell(*self) as uint
1211         }
1212     }
1213     fn flush(&self) -> int {
1214         #[fixed_stack_segment]; #[inline(never)];
1215
1216         unsafe {
1217             libc::fflush(*self) as int
1218         }
1219     }
1220     fn get_type(&self) -> WriterType {
1221         #[fixed_stack_segment]; #[inline(never)];
1222
1223         unsafe {
1224             let fd = libc::fileno(*self);
1225             if libc::isatty(fd) == 0 { File   }
1226             else                     { Screen }
1227         }
1228     }
1229 }
1230
1231 pub fn FILE_writer(f: *libc::FILE, cleanup: bool) -> @Writer {
1232     if cleanup {
1233         @Wrapper { base: f, cleanup: FILERes::new(f) } as @Writer
1234     } else {
1235         @f as @Writer
1236     }
1237 }
1238
1239 impl Writer for fd_t {
1240     fn write(&self, v: &[u8]) {
1241         #[fixed_stack_segment]; #[inline(never)];
1242
1243         unsafe {
1244             let mut count = 0u;
1245             do v.as_imm_buf |vbuf, len| {
1246                 while count < len {
1247                     let vb = ptr::offset(vbuf, count as int) as *c_void;
1248                     let nout = libc::write(*self, vb, len as size_t);
1249                     if nout < 0 as ssize_t {
1250                         error!("error writing buffer");
1251                         error!("%s", os::last_os_error());
1252                         fail!();
1253                     }
1254                     count += nout as uint;
1255                 }
1256             }
1257         }
1258     }
1259     fn seek(&self, _offset: int, _whence: SeekStyle) {
1260         error!("need 64-bit foreign calls for seek, sorry");
1261         fail!();
1262     }
1263     fn tell(&self) -> uint {
1264         error!("need 64-bit foreign calls for tell, sorry");
1265         fail!();
1266     }
1267     fn flush(&self) -> int { 0 }
1268     fn get_type(&self) -> WriterType {
1269         #[fixed_stack_segment]; #[inline(never)];
1270
1271         unsafe {
1272             if libc::isatty(*self) == 0 { File } else { Screen }
1273         }
1274     }
1275 }
1276
1277 pub struct FdRes {
1278     fd: fd_t,
1279 }
1280
1281 impl FdRes {
1282     pub fn new(fd: fd_t) -> FdRes {
1283         FdRes { fd: fd }
1284     }
1285 }
1286
1287 impl Drop for FdRes {
1288     fn drop(&self) {
1289         #[fixed_stack_segment]; #[inline(never)];
1290
1291         unsafe {
1292             libc::close(self.fd);
1293         }
1294     }
1295 }
1296
1297 pub fn fd_writer(fd: fd_t, cleanup: bool) -> @Writer {
1298     if cleanup {
1299         @Wrapper { base: fd, cleanup: FdRes::new(fd) } as @Writer
1300     } else {
1301         @fd as @Writer
1302     }
1303 }
1304
1305
1306 pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
1307                    -> Result<@Writer, ~str> {
1308     #[fixed_stack_segment]; #[inline(never)];
1309
1310     #[cfg(windows)]
1311     fn wb() -> c_int {
1312       (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int
1313     }
1314
1315     #[cfg(unix)]
1316     fn wb() -> c_int { O_WRONLY as c_int }
1317
1318     let mut fflags: c_int = wb();
1319     for f in flags.iter() {
1320         match *f {
1321           Append => fflags |= O_APPEND as c_int,
1322           Create => fflags |= O_CREAT as c_int,
1323           Truncate => fflags |= O_TRUNC as c_int,
1324           NoFlag => ()
1325         }
1326     }
1327     let fd = unsafe {
1328         do path.with_c_str |pathbuf| {
1329             libc::open(pathbuf, fflags, (S_IRUSR | S_IWUSR) as c_int)
1330         }
1331     };
1332     if fd < (0 as c_int) {
1333         Err(fmt!("error opening %s: %s", path.to_str(), os::last_os_error()))
1334     } else {
1335         Ok(fd_writer(fd, true))
1336     }
1337 }
1338
1339 pub fn u64_to_le_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 as u8,
1345               (n >> 8) as u8]),
1346       4u => f(&[n as u8,
1347               (n >> 8) as u8,
1348               (n >> 16) as u8,
1349               (n >> 24) as u8]),
1350       8u => f(&[n as u8,
1351               (n >> 8) as u8,
1352               (n >> 16) as u8,
1353               (n >> 24) as u8,
1354               (n >> 32) as u8,
1355               (n >> 40) as u8,
1356               (n >> 48) as u8,
1357               (n >> 56) as u8]),
1358       _ => {
1359
1360         let mut bytes: ~[u8] = ~[];
1361         let mut i = size;
1362         let mut n = n;
1363         while i > 0u {
1364             bytes.push((n & 255_u64) as u8);
1365             n >>= 8_u64;
1366             i -= 1u;
1367         }
1368         f(bytes)
1369       }
1370     }
1371 }
1372
1373 pub fn u64_to_be_bytes<T>(n: u64, size: uint,
1374                            f: &fn(v: &[u8]) -> T) -> T {
1375     assert!(size <= 8u);
1376     match size {
1377       1u => f(&[n as u8]),
1378       2u => f(&[(n >> 8) as u8,
1379               n as u8]),
1380       4u => f(&[(n >> 24) as u8,
1381               (n >> 16) as u8,
1382               (n >> 8) as u8,
1383               n as u8]),
1384       8u => f(&[(n >> 56) as u8,
1385               (n >> 48) as u8,
1386               (n >> 40) as u8,
1387               (n >> 32) as u8,
1388               (n >> 24) as u8,
1389               (n >> 16) as u8,
1390               (n >> 8) as u8,
1391               n as u8]),
1392       _ => {
1393         let mut bytes: ~[u8] = ~[];
1394         let mut i = size;
1395         while i > 0u {
1396             let shift = ((i - 1u) * 8u) as u64;
1397             bytes.push((n >> shift) as u8);
1398             i -= 1u;
1399         }
1400         f(bytes)
1401       }
1402     }
1403 }
1404
1405 pub fn u64_from_be_bytes(data: &[u8],
1406                          start: uint,
1407                          size: uint)
1408                       -> u64 {
1409     let mut sz = size;
1410     assert!((sz <= 8u));
1411     let mut val = 0_u64;
1412     let mut pos = start;
1413     while sz > 0u {
1414         sz -= 1u;
1415         val += (data[pos] as u64) << ((sz * 8u) as u64);
1416         pos += 1u;
1417     }
1418     return val;
1419 }
1420
1421 // FIXME: #3048 combine trait+impl (or just move these to
1422 // default methods on writer)
1423 /// Generic utility functions defined on writers.
1424 pub trait WriterUtil {
1425
1426     /// Write a single utf-8 encoded char.
1427     fn write_char(&self, ch: char);
1428
1429     /// Write every char in the given str, encoded as utf-8.
1430     fn write_str(&self, s: &str);
1431
1432     /// Write the given str, as utf-8, followed by '\n'.
1433     fn write_line(&self, s: &str);
1434
1435     /// Write the result of passing n through `int::to_str_bytes`.
1436     fn write_int(&self, n: int);
1437
1438     /// Write the result of passing n through `uint::to_str_bytes`.
1439     fn write_uint(&self, n: uint);
1440
1441     /// Write a little-endian uint (number of bytes depends on system).
1442     fn write_le_uint(&self, n: uint);
1443
1444     /// Write a little-endian int (number of bytes depends on system).
1445     fn write_le_int(&self, n: int);
1446
1447     /// Write a big-endian uint (number of bytes depends on system).
1448     fn write_be_uint(&self, n: uint);
1449
1450     /// Write a big-endian int (number of bytes depends on system).
1451     fn write_be_int(&self, n: int);
1452
1453     /// Write a big-endian u64 (8 bytes).
1454     fn write_be_u64(&self, n: u64);
1455
1456     /// Write a big-endian u32 (4 bytes).
1457     fn write_be_u32(&self, n: u32);
1458
1459     /// Write a big-endian u16 (2 bytes).
1460     fn write_be_u16(&self, n: u16);
1461
1462     /// Write a big-endian i64 (8 bytes).
1463     fn write_be_i64(&self, n: i64);
1464
1465     /// Write a big-endian i32 (4 bytes).
1466     fn write_be_i32(&self, n: i32);
1467
1468     /// Write a big-endian i16 (2 bytes).
1469     fn write_be_i16(&self, n: i16);
1470
1471     /// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
1472     fn write_be_f64(&self, f: f64);
1473
1474     /// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
1475     fn write_be_f32(&self, f: f32);
1476
1477     /// Write a little-endian u64 (8 bytes).
1478     fn write_le_u64(&self, n: u64);
1479
1480     /// Write a little-endian u32 (4 bytes).
1481     fn write_le_u32(&self, n: u32);
1482
1483     /// Write a little-endian u16 (2 bytes).
1484     fn write_le_u16(&self, n: u16);
1485
1486     /// Write a little-endian i64 (8 bytes).
1487     fn write_le_i64(&self, n: i64);
1488
1489     /// Write a little-endian i32 (4 bytes).
1490     fn write_le_i32(&self, n: i32);
1491
1492     /// Write a little-endian i16 (2 bytes).
1493     fn write_le_i16(&self, n: i16);
1494
1495     /// Write a little-endian IEEE754 double-precision floating-point
1496     /// (8 bytes).
1497     fn write_le_f64(&self, f: f64);
1498
1499     /// Write a little-endian IEEE754 single-precision floating-point
1500     /// (4 bytes).
1501     fn write_le_f32(&self, f: f32);
1502
1503     /// Write a u8 (1 byte).
1504     fn write_u8(&self, n: u8);
1505
1506     /// Write a i8 (1 byte).
1507     fn write_i8(&self, n: i8);
1508 }
1509
1510 impl<T:Writer> WriterUtil for T {
1511     fn write_char(&self, ch: char) {
1512         if (ch as uint) < 128u {
1513             self.write(&[ch as u8]);
1514         } else {
1515             self.write_str(str::from_char(ch));
1516         }
1517     }
1518     fn write_str(&self, s: &str) { self.write(s.as_bytes()) }
1519     fn write_line(&self, s: &str) {
1520         self.write_str(s);
1521         self.write_str(&"\n");
1522     }
1523     fn write_int(&self, n: int) {
1524         int::to_str_bytes(n, 10u, |bytes| self.write(bytes))
1525     }
1526     fn write_uint(&self, n: uint) {
1527         uint::to_str_bytes(n, 10u, |bytes| self.write(bytes))
1528     }
1529     fn write_le_uint(&self, n: uint) {
1530         u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v))
1531     }
1532     fn write_le_int(&self, n: int) {
1533         u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v))
1534     }
1535     fn write_be_uint(&self, n: uint) {
1536         u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v))
1537     }
1538     fn write_be_int(&self, n: int) {
1539         u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v))
1540     }
1541     fn write_be_u64(&self, n: u64) {
1542         u64_to_be_bytes(n, 8u, |v| self.write(v))
1543     }
1544     fn write_be_u32(&self, n: u32) {
1545         u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
1546     }
1547     fn write_be_u16(&self, n: u16) {
1548         u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
1549     }
1550     fn write_be_i64(&self, n: i64) {
1551         u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
1552     }
1553     fn write_be_i32(&self, n: i32) {
1554         u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
1555     }
1556     fn write_be_i16(&self, n: i16) {
1557         u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
1558     }
1559     fn write_be_f64(&self, f:f64) {
1560         unsafe {
1561             self.write_be_u64(cast::transmute(f))
1562         }
1563     }
1564     fn write_be_f32(&self, f:f32) {
1565         unsafe {
1566             self.write_be_u32(cast::transmute(f))
1567         }
1568     }
1569     fn write_le_u64(&self, n: u64) {
1570         u64_to_le_bytes(n, 8u, |v| self.write(v))
1571     }
1572     fn write_le_u32(&self, n: u32) {
1573         u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
1574     }
1575     fn write_le_u16(&self, n: u16) {
1576         u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
1577     }
1578     fn write_le_i64(&self, n: i64) {
1579         u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
1580     }
1581     fn write_le_i32(&self, n: i32) {
1582         u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
1583     }
1584     fn write_le_i16(&self, n: i16) {
1585         u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
1586     }
1587     fn write_le_f64(&self, f:f64) {
1588         unsafe {
1589             self.write_le_u64(cast::transmute(f))
1590         }
1591     }
1592     fn write_le_f32(&self, f:f32) {
1593         unsafe {
1594             self.write_le_u32(cast::transmute(f))
1595         }
1596     }
1597
1598     fn write_u8(&self, n: u8) { self.write([n]) }
1599     fn write_i8(&self, n: i8) { self.write([n as u8]) }
1600
1601 }
1602
1603 pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {
1604     mk_file_writer(path, flags).chain(|w| Ok(w))
1605 }
1606
1607
1608 // FIXME: fileflags // #2004
1609 pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
1610     #[fixed_stack_segment]; #[inline(never)];
1611
1612     unsafe {
1613         let f = do path.with_c_str |pathbuf| {
1614             do "w".with_c_str |modebuf| {
1615                 libc::fopen(pathbuf, modebuf)
1616             }
1617         };
1618         return if f as uint == 0u {
1619             Err(~"error opening " + path.to_str())
1620         } else {
1621             Ok(FILE_writer(f, true))
1622         }
1623     }
1624 }
1625
1626 // FIXME (#2004) it would be great if this could be a const
1627 // FIXME (#2004) why are these different from the way stdin() is
1628 // implemented?
1629
1630
1631 /**
1632 * Gives a `Writer` which allows you to write to the standard output.
1633 *
1634 * # Example
1635 *
1636 * ~~~ {.rust}
1637 * let stdout = std::io::stdout();
1638 * stdout.write_str("hello\n");
1639 * ~~~
1640 */
1641 pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
1642
1643 /**
1644 * Gives a `Writer` which allows you to write to standard error.
1645 *
1646 * # Example
1647 *
1648 * ~~~ {.rust}
1649 * let stderr = std::io::stderr();
1650 * stderr.write_str("hello\n");
1651 * ~~~
1652 */
1653 pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
1654
1655 /**
1656 * Prints a string to standard output.
1657 *
1658 * This string will not have an implicit newline at the end. If you want
1659 * an implicit newline, please see `println`.
1660 *
1661 * # Example
1662 *
1663 * ~~~ {.rust}
1664 * // print is imported into the prelude, and so is always available.
1665 * print("hello");
1666 * ~~~
1667 */
1668 pub fn print(s: &str) {
1669     stdout().write_str(s);
1670 }
1671
1672 /**
1673 * Prints a string to standard output, followed by a newline.
1674 *
1675 * If you do not want an implicit newline, please see `print`.
1676 *
1677 * # Example
1678 *
1679 * ~~~ {.rust}
1680 * // println is imported into the prelude, and so is always available.
1681 * println("hello");
1682 * ~~~
1683 */
1684 pub fn println(s: &str) {
1685     stdout().write_line(s);
1686 }
1687
1688 pub struct BytesWriter {
1689     bytes: @mut ~[u8],
1690     pos: @mut uint,
1691 }
1692
1693 impl BytesWriter {
1694     pub fn new() -> BytesWriter {
1695         BytesWriter {
1696             bytes: @mut ~[],
1697             pos: @mut 0
1698         }
1699     }
1700 }
1701
1702 impl Writer for BytesWriter {
1703     fn write(&self, v: &[u8]) {
1704         let v_len = v.len();
1705
1706         let bytes = &mut *self.bytes;
1707         let count = num::max(bytes.len(), *self.pos + v_len);
1708         bytes.reserve(count);
1709
1710         unsafe {
1711             vec::raw::set_len(bytes, count);
1712
1713             let view = bytes.mut_slice(*self.pos, count);
1714             vec::bytes::copy_memory(view, v, v_len);
1715         }
1716
1717         *self.pos += v_len;
1718     }
1719
1720     fn seek(&self, offset: int, whence: SeekStyle) {
1721         let pos = *self.pos;
1722         let len = self.bytes.len();
1723         *self.pos = seek_in_buf(offset, pos, len, whence);
1724     }
1725
1726     fn tell(&self) -> uint {
1727         *self.pos
1728     }
1729
1730     fn flush(&self) -> int {
1731         0
1732     }
1733
1734     fn get_type(&self) -> WriterType {
1735         File
1736     }
1737 }
1738
1739 pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] {
1740     let wr = @BytesWriter::new();
1741     f(wr as @Writer);
1742     let @BytesWriter { bytes, _ } = wr;
1743     (*bytes).clone()
1744 }
1745
1746 pub fn with_str_writer(f: &fn(@Writer)) -> ~str {
1747     str::from_bytes(with_bytes_writer(f))
1748 }
1749
1750 // Utility functions
1751 pub fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
1752    uint {
1753     let mut bpos = pos as int;
1754     let blen = len as int;
1755     match whence {
1756       SeekSet => bpos = offset,
1757       SeekCur => bpos += offset,
1758       SeekEnd => bpos = blen + offset
1759     }
1760     if bpos < 0 { bpos = 0; } else if bpos > blen { bpos = blen; }
1761     return bpos as uint;
1762 }
1763
1764 pub fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
1765     do read_whole_file(file).chain |bytes| {
1766         if str::is_utf8(bytes) {
1767             Ok(str::from_bytes(bytes))
1768         } else {
1769             Err(file.to_str() + " is not UTF-8")
1770         }
1771     }
1772 }
1773
1774 // FIXME (#2004): implement this in a low-level way. Going through the
1775 // abstractions is pointless.
1776 pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
1777     do file_reader(file).chain |rdr| {
1778         Ok(rdr.read_whole_stream())
1779     }
1780 }
1781
1782 // fsync related
1783
1784 pub mod fsync {
1785     use io::{FILERes, FdRes, fd_t};
1786     use libc;
1787     use ops::Drop;
1788     use option::{None, Option, Some};
1789     use os;
1790
1791     pub enum Level {
1792         // whatever fsync does on that platform
1793         FSync,
1794
1795         // fdatasync on linux, similiar or more on other platforms
1796         FDataSync,
1797
1798         // full fsync
1799         //
1800         // You must additionally sync the parent directory as well!
1801         FullFSync,
1802     }
1803
1804
1805     // Artifacts that need to fsync on destruction
1806     pub struct Res<t> {
1807         arg: Arg<t>,
1808     }
1809
1810     impl <t> Res<t> {
1811         pub fn new(arg: Arg<t>) -> Res<t> {
1812             Res { arg: arg }
1813         }
1814     }
1815
1816     #[unsafe_destructor]
1817     impl<T> Drop for Res<T> {
1818         fn drop(&self) {
1819             match self.arg.opt_level {
1820                 None => (),
1821                 Some(level) => {
1822                   // fail hard if not succesful
1823                   assert!(((self.arg.fsync_fn)(&self.arg.val, level) != -1));
1824                 }
1825             }
1826         }
1827     }
1828
1829     pub struct Arg<t> {
1830         val: t,
1831         opt_level: Option<Level>,
1832         fsync_fn: @fn(f: &t, Level) -> int,
1833     }
1834
1835     // fsync file after executing blk
1836     // FIXME (#2004) find better way to create resources within lifetime of
1837     // outer res
1838     pub fn FILE_res_sync(file: &FILERes, opt_level: Option<Level>,
1839                          blk: &fn(v: Res<*libc::FILE>)) {
1840         blk(Res::new(Arg {
1841             val: file.f, opt_level: opt_level,
1842             fsync_fn: |file, l| fsync_fd(fileno(*file), l)
1843         }));
1844
1845         fn fileno(stream: *libc::FILE) -> libc::c_int {
1846             #[fixed_stack_segment]; #[inline(never)];
1847             unsafe { libc::fileno(stream) }
1848         }
1849     }
1850
1851     // fsync fd after executing blk
1852     pub fn fd_res_sync(fd: &FdRes, opt_level: Option<Level>,
1853                        blk: &fn(v: Res<fd_t>)) {
1854         blk(Res::new(Arg {
1855             val: fd.fd, opt_level: opt_level,
1856             fsync_fn: |fd, l| fsync_fd(*fd, l)
1857         }));
1858     }
1859
1860     fn fsync_fd(fd: libc::c_int, level: Level) -> int {
1861         #[fixed_stack_segment]; #[inline(never)];
1862
1863         os::fsync_fd(fd, level) as int
1864     }
1865
1866     // Type of objects that may want to fsync
1867     pub trait FSyncable { fn fsync(&self, l: Level) -> int; }
1868
1869     // Call o.fsync after executing blk
1870     pub fn obj_sync(o: @FSyncable, opt_level: Option<Level>,
1871                     blk: &fn(v: Res<@FSyncable>)) {
1872         blk(Res::new(Arg {
1873             val: o, opt_level: opt_level,
1874             fsync_fn: |o, l| (*o).fsync(l)
1875         }));
1876     }
1877 }
1878
1879 #[cfg(test)]
1880 mod tests {
1881     use prelude::*;
1882     use i32;
1883     use io::{BytesWriter, SeekCur, SeekEnd, SeekSet};
1884     use io;
1885     use path::Path;
1886     use result::{Ok, Err};
1887     use u64;
1888     use vec;
1889
1890     #[test]
1891     fn test_simple() {
1892         let tmpfile = &Path("tmp/lib-io-test-simple.tmp");
1893         debug!(tmpfile);
1894         let frood: ~str =
1895             ~"A hoopy frood who really knows where his towel is.";
1896         debug!(frood.clone());
1897         {
1898             let out = io::file_writer(tmpfile, [io::Create, io::Truncate]).unwrap();
1899             out.write_str(frood);
1900         }
1901         let inp = io::file_reader(tmpfile).unwrap();
1902         let frood2: ~str = inp.read_c_str();
1903         debug!(frood2.clone());
1904         assert_eq!(frood, frood2);
1905     }
1906
1907     #[test]
1908     fn test_each_byte_each_char_file() {
1909         // Issue #5056 -- shouldn't include trailing EOF.
1910         let path = Path("tmp/lib-io-test-each-byte-each-char-file.tmp");
1911
1912         {
1913             // create empty, enough to reproduce a problem
1914             io::file_writer(&path, [io::Create]).unwrap();
1915         }
1916
1917         {
1918             let file = io::file_reader(&path).unwrap();
1919             do file.each_byte() |_| {
1920                 fail!("must be empty")
1921             };
1922         }
1923
1924         {
1925             let file = io::file_reader(&path).unwrap();
1926             do file.each_char() |_| {
1927                 fail!("must be empty")
1928             };
1929         }
1930     }
1931
1932     #[test]
1933     fn test_readchars_empty() {
1934         do io::with_str_reader("") |inp| {
1935             let res : ~[char] = inp.read_chars(128);
1936             assert_eq!(res.len(), 0);
1937         }
1938     }
1939
1940     #[test]
1941     fn test_read_line_utf8() {
1942         do io::with_str_reader("生锈的汤匙切肉汤hello生锈的汤匙切肉汤") |inp| {
1943             let line = inp.read_line();
1944             assert_eq!(line, ~"生锈的汤匙切肉汤hello生锈的汤匙切肉汤");
1945         }
1946     }
1947
1948     #[test]
1949     fn test_read_lines() {
1950         do io::with_str_reader("a\nb\nc\n") |inp| {
1951             assert_eq!(inp.read_lines(), ~[~"a", ~"b", ~"c"]);
1952         }
1953
1954         do io::with_str_reader("a\nb\nc") |inp| {
1955             assert_eq!(inp.read_lines(), ~[~"a", ~"b", ~"c"]);
1956         }
1957
1958         do io::with_str_reader("") |inp| {
1959             assert!(inp.read_lines().is_empty());
1960         }
1961     }
1962
1963     #[test]
1964     fn test_readchars_wide() {
1965         let wide_test = ~"生锈的汤匙切肉汤hello生锈的汤匙切肉汤";
1966         let ivals : ~[int] = ~[
1967             29983, 38152, 30340, 27748,
1968             21273, 20999, 32905, 27748,
1969             104, 101, 108, 108, 111,
1970             29983, 38152, 30340, 27748,
1971             21273, 20999, 32905, 27748];
1972         fn check_read_ln(len : uint, s: &str, ivals: &[int]) {
1973             do io::with_str_reader(s) |inp| {
1974                 let res : ~[char] = inp.read_chars(len);
1975                 if len <= ivals.len() {
1976                     assert_eq!(res.len(), len);
1977                 }
1978                 for (iv, c) in ivals.iter().zip(res.iter()) {
1979                     assert!(*iv == *c as int)
1980                 }
1981             }
1982         }
1983         let mut i = 0;
1984         while i < 8 {
1985             check_read_ln(i, wide_test, ivals);
1986             i += 1;
1987         }
1988         // check a long read for good measure
1989         check_read_ln(128, wide_test, ivals);
1990     }
1991
1992     #[test]
1993     fn test_readchar() {
1994         do io::with_str_reader("生") |inp| {
1995             let res : char = inp.read_char();
1996             assert_eq!(res as int, 29983);
1997         }
1998     }
1999
2000     #[test]
2001     fn test_readchar_empty() {
2002         do io::with_str_reader("") |inp| {
2003             let res : char = inp.read_char();
2004             assert_eq!(res as int, -1);
2005         }
2006     }
2007
2008     #[test]
2009     fn file_reader_not_exist() {
2010         match io::file_reader(&Path("not a file")) {
2011           Err(e) => {
2012             assert_eq!(e, ~"error opening not a file");
2013           }
2014           Ok(_) => fail!()
2015         }
2016     }
2017
2018     #[test]
2019     #[should_fail]
2020     #[ignore(cfg(windows))]
2021     fn test_read_buffer_too_small() {
2022         let path = &Path("tmp/lib-io-test-read-buffer-too-small.tmp");
2023         // ensure the file exists
2024         io::file_writer(path, [io::Create]).unwrap();
2025
2026         let file = io::file_reader(path).unwrap();
2027         let mut buf = vec::from_elem(5, 0u8);
2028         file.read(buf, 6); // this should fail because buf is too small
2029     }
2030
2031     #[test]
2032     fn test_read_buffer_big_enough() {
2033         let path = &Path("tmp/lib-io-test-read-buffer-big-enough.tmp");
2034         // ensure the file exists
2035         io::file_writer(path, [io::Create]).unwrap();
2036
2037         let file = io::file_reader(path).unwrap();
2038         let mut buf = vec::from_elem(5, 0u8);
2039         file.read(buf, 4); // this should succeed because buf is big enough
2040     }
2041
2042     #[test]
2043     fn test_write_empty() {
2044         let file = io::file_writer(&Path("tmp/lib-io-test-write-empty.tmp"),
2045                                    [io::Create]).unwrap();
2046         file.write([]);
2047     }
2048
2049     #[test]
2050     fn file_writer_bad_name() {
2051         match io::file_writer(&Path("?/?"), []) {
2052           Err(e) => {
2053             assert!(e.starts_with("error opening"));
2054           }
2055           Ok(_) => fail!()
2056         }
2057     }
2058
2059     #[test]
2060     fn buffered_file_writer_bad_name() {
2061         match io::buffered_file_writer(&Path("?/?")) {
2062           Err(e) => {
2063             assert!(e.starts_with("error opening"));
2064           }
2065           Ok(_) => fail!()
2066         }
2067     }
2068
2069     #[test]
2070     fn bytes_buffer_overwrite() {
2071         let wr = BytesWriter::new();
2072         wr.write([0u8, 1u8, 2u8, 3u8]);
2073         assert!(*wr.bytes == ~[0u8, 1u8, 2u8, 3u8]);
2074         wr.seek(-2, SeekCur);
2075         wr.write([4u8, 5u8, 6u8, 7u8]);
2076         assert!(*wr.bytes == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]);
2077         wr.seek(-2, SeekEnd);
2078         wr.write([8u8]);
2079         wr.seek(1, SeekSet);
2080         wr.write([9u8]);
2081         assert!(*wr.bytes == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]);
2082     }
2083
2084     #[test]
2085     fn test_read_write_le() {
2086         let path = Path("tmp/lib-io-test-read-write-le.tmp");
2087         let uints = [0, 1, 2, 42, 10_123, 100_123_456, u64::max_value];
2088
2089         // write the ints to the file
2090         {
2091             let file = io::file_writer(&path, [io::Create]).unwrap();
2092             for i in uints.iter() {
2093                 file.write_le_u64(*i);
2094             }
2095         }
2096
2097         // then read them back and check that they are the same
2098         {
2099             let file = io::file_reader(&path).unwrap();
2100             for i in uints.iter() {
2101                 assert_eq!(file.read_le_u64(), *i);
2102             }
2103         }
2104     }
2105
2106     #[test]
2107     fn test_read_write_be() {
2108         let path = Path("tmp/lib-io-test-read-write-be.tmp");
2109         let uints = [0, 1, 2, 42, 10_123, 100_123_456, u64::max_value];
2110
2111         // write the ints to the file
2112         {
2113             let file = io::file_writer(&path, [io::Create]).unwrap();
2114             for i in uints.iter() {
2115                 file.write_be_u64(*i);
2116             }
2117         }
2118
2119         // then read them back and check that they are the same
2120         {
2121             let file = io::file_reader(&path).unwrap();
2122             for i in uints.iter() {
2123                 assert_eq!(file.read_be_u64(), *i);
2124             }
2125         }
2126     }
2127
2128     #[test]
2129     fn test_read_be_int_n() {
2130         let path = Path("tmp/lib-io-test-read-be-int-n.tmp");
2131         let ints = [i32::min_value, -123456, -42, -5, 0, 1, i32::max_value];
2132
2133         // write the ints to the file
2134         {
2135             let file = io::file_writer(&path, [io::Create]).unwrap();
2136             for i in ints.iter() {
2137                 file.write_be_i32(*i);
2138             }
2139         }
2140
2141         // then read them back and check that they are the same
2142         {
2143             let file = io::file_reader(&path).unwrap();
2144             for i in ints.iter() {
2145                 // this tests that the sign extension is working
2146                 // (comparing the values as i32 would not test this)
2147                 assert_eq!(file.read_be_int_n(4), *i as i64);
2148             }
2149         }
2150     }
2151
2152     #[test]
2153     fn test_read_f32() {
2154         let path = Path("tmp/lib-io-test-read-f32.tmp");
2155         //big-endian floating-point 8.1250
2156         let buf = ~[0x41, 0x02, 0x00, 0x00];
2157
2158         {
2159             let file = io::file_writer(&path, [io::Create]).unwrap();
2160             file.write(buf);
2161         }
2162
2163         {
2164             let file = io::file_reader(&path).unwrap();
2165             let f = file.read_be_f32();
2166             assert_eq!(f, 8.1250);
2167         }
2168     }
2169
2170     #[test]
2171     fn test_read_write_f32() {
2172         let path = Path("tmp/lib-io-test-read-write-f32.tmp");
2173         let f:f32 = 8.1250;
2174
2175         {
2176             let file = io::file_writer(&path, [io::Create]).unwrap();
2177             file.write_be_f32(f);
2178             file.write_le_f32(f);
2179         }
2180
2181         {
2182             let file = io::file_reader(&path).unwrap();
2183             assert_eq!(file.read_be_f32(), 8.1250);
2184             assert_eq!(file.read_le_f32(), 8.1250);
2185         }
2186     }
2187 }