(index<- )        ./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 cast::transmute;
   51  use clone::Clone;
   52  use c_str::ToCStr;
   53  use container::Container;
   54  use int;
   55  use iter::Iterator;
   56  use libc::consts::os::posix88::*;
   57  use libc::{c_int, c_void, size_t};
   58  use libc;
   59  use num;
   60  use ops::Drop;
   61  use option::{Some, None};
   62  use os;
   63  use path::{Path,GenericPath};
   64  use ptr;
   65  use result::{Result, Ok, Err};
   66  use str::{StrSlice, OwnedStr};
   67  use str;
   68  use to_str::ToStr;
   69  use uint;
   70  use vec::{MutableVector, ImmutableVector, OwnedVector, OwnedCopyableVector, CopyableVector};
   71  use vec;
   72  
   73  #[allow(non_camel_case_types)] // not sure what to do about this
   74  pub type fd_t = c_int;
   75  
   76  pub mod rustrt {
   77      use libc;
   78  
   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], lenuint) -> 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, positionint, styleSeekStyle) {
  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, lenuint) -> ~[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, cu8, includebool) -> ~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_utf8(bytes)
  645      }
  646  
  647      fn read_line(&self) -> ~str {
  648          self.read_until('\n' as u8, false)
  649      }
  650  
  651      fn read_chars(&self, nuint) -> ~[char] {
  652          // returns the (consumed offset, n_req), appends characters to &chars
  653          fn chars_from_utf8<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                      unsafe {
  665                          chars.push(transmute(b0 as u32));
  666                      }
  667                      continue;
  668                  }
  669                  // can't satisfy this char with the existing data
  670                  if end > bytes_len {
  671                      return (i - 1, end - bytes_len);
  672                  }
  673                  let mut val = 0;
  674                  while i < end {
  675                      let next = bytes[i] as int;
  676                      i += 1;
  677                      assert!((next > -1));
  678                      assert_eq!(next & 192, 128);
  679                      val <<= 6;
  680                      val += (next & 63) as uint;
  681                  }
  682                  // See str::StrSlice::char_at
  683                  val += ((b0 << ((w + 1) as u8)) as uint)
  684                      << (w - 1) * 6 - w - 1u;
  685                  unsafe {
  686                      chars.push(transmute(val as u32));
  687                  }
  688              }
  689              return (i, 0);
  690          }
  691          let mut bytes = ~[];
  692          let mut chars = ~[];
  693          // might need more bytes, but reading n will never over-read
  694          let mut nbread = n;
  695          while nbread > 0 {
  696              let data = self.read_bytes(nbread);
  697              if data.is_empty() {
  698                  // eof - FIXME (#2004): should we do something if
  699                  // we're split in a unicode char?
  700                  break;
  701              }
  702              bytes.push_all(data);
  703              let (offset, nbreq) = chars_from_utf8::<T>(&bytes, &mut chars);
  704              let ncreq = n - chars.len();
  705              // again we either know we need a certain number of bytes
  706              // to complete a character, or we make sure we don't
  707              // over-read by reading 1-byte per char needed
  708              nbread = if ncreq > nbreq { ncreq } else { nbreq };
  709              if nbread > 0 {
  710                  bytes = bytes.slice(offset, bytes.len()).to_owned();
  711              }
  712          }
  713          chars
  714      }
  715  
  716      fn read_char(&self) -> char {
  717          let c = self.read_chars(1);
  718          if c.len() == 0 {
  719              return unsafe { transmute(-1u32) }; // FIXME: #8971: unsound
  720          }
  721          assert_eq!(c.len(), 1);
  722          return c[0];
  723      }
  724  
  725      fn read_c_str(&self) -> ~str {
  726          self.read_until(0u8, false)
  727      }
  728  
  729      fn read_whole_stream(&self) -> ~[u8] {
  730          let mut bytes~[u8] = ~[];
  731          while !self.eof() { bytes.push_all(self.read_bytes(2048u)); }
  732          bytes
  733      }
  734  
  735      fn each_byte(&self, it&fn(int) -> bool) -> bool {
  736          loop {
  737              match self.read_byte() {
  738                  -1 => break,
  739                  ch => if !it(ch) { return false; }
  740              }
  741          }
  742          return true;
  743      }
  744  
  745      fn each_char(&self, it&fn(char) -> bool) -> bool {
  746          // FIXME: #8971: unsound
  747          let eofchar = unsafe { transmute(-1u32) };
  748          loop {
  749              match self.read_char() {
  750                  c if c == eof => break,
  751                  ch => if !it(ch) { return false; }
  752              }
  753          }
  754          return true;
  755      }
  756  
  757      fn each_line(&self, it&fn(s: &str) -> bool) -> bool {
  758          while !self.eof() {
  759              // include the \n, so that we can distinguish an entirely empty
  760              // line read after "...\n", and the trailing empty line in
  761              // "...\n\n".
  762              let mut line = self.read_until('\n' as u8, true);
  763  
  764              // blank line at the end of the reader is ignored
  765              if self.eof() && line.is_empty() { break; }
  766  
  767              // trim the \n, so that each_line is consistent with read_line
  768              let n = line.len();
  769              if line[n-1] == '\n' as u8 {
  770                  unsafe { str::raw::set_len(&mut line, n-1); }
  771              }
  772  
  773              if !it(line) { return false; }
  774          }
  775          return true;
  776      }
  777  
  778      fn read_lines(&self) -> ~[~str] {
  779          do vec::build(None) |push| {
  780              do self.each_line |line| {
  781                  push(line.to_owned());
  782                  true
  783              };
  784          }
  785      }
  786  
  787      // FIXME int reading methods need to deal with eof - issue #2004
  788  
  789      fn read_le_uint_n(&self, nbytesuint) -> u64 {
  790          assert!(nbytes > 0 && nbytes <= 8);
  791  
  792          let mut val = 0u64;
  793          let mut pos = 0;
  794          let mut i = nbytes;
  795          while i > 0 {
  796              val += (self.read_u8() as u64) << pos;
  797              pos += 8;
  798              i -= 1;
  799          }
  800          val
  801      }
  802  
  803      fn read_le_int_n(&self, nbytesuint) -> i64 {
  804          extend_sign(self.read_le_uint_n(nbytes), nbytes)
  805      }
  806  
  807      fn read_be_uint_n(&self, nbytesuint) -> u64 {
  808          assert!(nbytes > 0 && nbytes <= 8);
  809  
  810          let mut val = 0u64;
  811          let mut i = nbytes;
  812          while i > 0 {
  813              i -= 1;
  814              val += (self.read_u8() as u64) << i * 8;
  815          }
  816          val
  817      }
  818  
  819      fn read_be_int_n(&self, nbytesuint) -> i64 {
  820          extend_sign(self.read_be_uint_n(nbytes), nbytes)
  821      }
  822  
  823      fn read_le_uint(&self) -> uint {
  824          self.read_le_uint_n(uint::bytes) as uint
  825      }
  826  
  827      fn read_le_int(&self) -> int {
  828          self.read_le_int_n(int::bytes) as int
  829      }
  830  
  831      fn read_be_uint(&self) -> uint {
  832          self.read_be_uint_n(uint::bytes) as uint
  833      }
  834  
  835      fn read_be_int(&self) -> int {
  836          self.read_be_int_n(int::bytes) as int
  837      }
  838  
  839      fn read_be_u64(&self) -> u64 {
  840          self.read_be_uint_n(8) as u64
  841      }
  842  
  843      fn read_be_u32(&self) -> u32 {
  844          self.read_be_uint_n(4) as u32
  845      }
  846  
  847      fn read_be_u16(&self) -> u16 {
  848          self.read_be_uint_n(2) as u16
  849      }
  850  
  851      fn read_be_i64(&self) -> i64 {
  852          self.read_be_int_n(8) as i64
  853      }
  854  
  855      fn read_be_i32(&self) -> i32 {
  856          self.read_be_int_n(4) as i32
  857      }
  858  
  859      fn read_be_i16(&self) -> i16 {
  860          self.read_be_int_n(2) as i16
  861      }
  862  
  863      fn read_be_f64(&self) -> f64 {
  864          unsafe {
  865              cast::transmute::<u64, f64>(self.read_be_u64())
  866          }
  867      }
  868  
  869      fn read_be_f32(&self) -> f32 {
  870          unsafe {
  871              cast::transmute::<u32, f32>(self.read_be_u32())
  872          }
  873      }
  874  
  875      fn read_le_u64(&self) -> u64 {
  876          self.read_le_uint_n(8) as u64
  877      }
  878  
  879      fn read_le_u32(&self) -> u32 {
  880          self.read_le_uint_n(4) as u32
  881      }
  882  
  883      fn read_le_u16(&self) -> u16 {
  884          self.read_le_uint_n(2) as u16
  885      }
  886  
  887      fn read_le_i64(&self) -> i64 {
  888          self.read_le_int_n(8) as i64
  889      }
  890  
  891      fn read_le_i32(&self) -> i32 {
  892          self.read_le_int_n(4) as i32
  893      }
  894  
  895      fn read_le_i16(&self) -> i16 {
  896          self.read_le_int_n(2) as i16
  897      }
  898  
  899      fn read_le_f64(&self) -> f64 {
  900          unsafe {
  901              cast::transmute::<u64, f64>(self.read_le_u64())
  902          }
  903      }
  904  
  905      fn read_le_f32(&self) -> f32 {
  906          unsafe {
  907              cast::transmute::<u32, f32>(self.read_le_u32())
  908          }
  909      }
  910  
  911      fn read_u8(&self) -> u8 {
  912          self.read_byte() as u8
  913      }
  914  
  915      fn read_i8(&self) -> i8 {
  916          self.read_byte() as i8
  917      }
  918  }
  919  
  920  fn extend_sign(valu64, nbytesuint) -> i64 {
  921      let shift = (8 - nbytes) * 8;
  922      (val << shift) as i64 >> shift
  923  }
  924  
  925  // Reader implementations
  926  
  927  fn convert_whence(whenceSeekStyle) -> i32 {
  928      return match whence {
  929        SeekSet => 0i32,
  930        SeekCur => 1i32,
  931        SeekEnd => 2i32
  932      };
  933  }
  934  
  935  impl Reader for *libc::FILE {
  936      fn read(&self, bytes&mut [u8], lenuint) -> uint {
  937          #[fixed_stack_segment]; #[inline(never)];
  938  
  939          unsafe {
  940              do bytes.as_mut_buf |buf_p, buf_len| {
  941                  assert!(buf_len >= len);
  942  
  943                  let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
  944                                          len as size_t, *self) as uint;
  945                  if count < len {
  946                    match libc::ferror(*self) {
  947                      0 => (),
  948                      _ => {
  949                        error2!("error reading buffer: {}", os::last_os_error());
  950                        fail2!();
  951                      }
  952                    }
  953                  }
  954  
  955                  count
  956              }
  957          }
  958      }
  959      fn read_byte(&self) -> int {
  960          #[fixed_stack_segment]; #[inline(never)];
  961  
  962          unsafe {
  963              libc::fgetc(*self) as int
  964          }
  965      }
  966      fn eof(&self) -> bool {
  967          #[fixed_stack_segment]; #[inline(never)];
  968  
  969          unsafe {
  970              return libc::feof(*self) != 0 as c_int;
  971          }
  972      }
  973      fn seek(&self, offsetint, whenceSeekStyle) {
  974          #[fixed_stack_segment]; #[inline(never)];
  975  
  976          unsafe {
  977              assert!(libc::fseek(*self,
  978                                       offset as libc::c_long,
  979                                       convert_whence(whence)) == 0 as c_int);
  980          }
  981      }
  982      fn tell(&self) -> uint {
  983          #[fixed_stack_segment]; #[inline(never)];
  984  
  985          unsafe {
  986              return libc::ftell(*self) as uint;
  987          }
  988      }
  989  }
  990  
  991  struct Wrapper<T, C> {
  992      base: T,
  993      cleanup: C,
  994  }
  995  
  996  // A forwarding impl of reader that also holds on to a resource for the
  997  // duration of its lifetime.
  998  // FIXME there really should be a better way to do this // #2004
  999  impl<R:Reader,C> Reader for Wrapper<R, C> {
 1000      fn read(&self, bytes&mut [u8], lenuint) -> uint {
 1001          self.base.read(bytes, len)
 1002      }
 1003      fn read_byte(&self) -> int { self.base.read_byte() }
 1004      fn eof(&self) -> bool { self.base.eof() }
 1005      fn seek(&self, offint, whenceSeekStyle) {
 1006          self.base.seek(off, whence)
 1007      }
 1008      fn tell(&self) -> uint { self.base.tell() }
 1009  }
 1010  
 1011  pub struct FILERes {
 1012      f: *libc::FILE,
 1013  }
 1014  
 1015  impl FILERes {
 1016      pub fn new(f*libc::FILE) -> FILERes {
 1017          FILERes { f: f }
 1018      }
 1019  }
 1020  
 1021  impl Drop for FILERes {
 1022      fn drop(&mut self) {
 1023          #[fixed_stack_segment]; #[inline(never)];
 1024  
 1025          unsafe {
 1026              libc::fclose(self.f);
 1027          }
 1028      }
 1029  }
 1030  
 1031  pub fn FILE_reader(f*libc::FILE, cleanupbool) -> @Reader {
 1032      if cleanup {
 1033          @Wrapper { base: f, cleanup: FILERes::new(f) } as @Reader
 1034      } else {
 1035          @f as @Reader
 1036      }
 1037  }
 1038  
 1039  // FIXME (#2004): this should either be an trait-less impl, a set of
 1040  // top-level functions that take a reader, or a set of default methods on
 1041  // reader (which can then be called reader)
 1042  
 1043  /**
 1044  * Gives a `Reader` that allows you to read values from standard input.
 1045  *
 1046  * # Example
 1047  *
 1048  * ```rust
 1049  * let stdin = std::io::stdin();
 1050  * let line = stdin.read_line();
 1051  * std::io::print(line);
 1052  * ```
 1053  */
 1054  pub fn stdin() -> @Reader {
 1055      #[fixed_stack_segment]; #[inline(never)];
 1056  
 1057      unsafe {
 1058          @rustrt::rust_get_stdin() as @Reader
 1059      }
 1060  }
 1061  
 1062  pub fn file_reader(path&Path) -> Result<@Reader, ~str> {
 1063      #[fixed_stack_segment]; #[inline(never)];
 1064  
 1065      let f = do path.with_c_str |pathbuf| {
 1066          do "rb".with_c_str |modebuf| {
 1067              unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) }
 1068          }
 1069      };
 1070  
 1071      if f as uint == 0u {
 1072          do path.display().with_str |p| {
 1073              Err(~"error opening " + p)
 1074          }
 1075      } else {
 1076          Ok(FILE_reader(f, true))
 1077      }
 1078  }
 1079  
 1080  
 1081  // Byte readers
 1082  pub struct BytesReader {
 1083      // FIXME(#5723) see other FIXME below
 1084      // FIXME(#7268) this should also be parameterized over <'self>
 1085      bytes: &'static [u8],
 1086      pos: @mut uint
 1087  }
 1088  
 1089  impl Reader for BytesReader {
 1090      fn read(&self, bytes&mut [u8], lenuint) -> uint {
 1091          let count = num::min(len, self.bytes.len() - *self.pos);
 1092  
 1093          let view = self.bytes.slice(*self.pos, self.bytes.len());
 1094          vec::bytes::copy_memory(bytes, view, count);
 1095  
 1096          *self.pos += count;
 1097  
 1098          count
 1099      }
 1100  
 1101      fn read_byte(&self) -> int {
 1102          if *self.pos == self.bytes.len() {
 1103              return -1;
 1104          }
 1105  
 1106          let b = self.bytes[*self.pos];
 1107          *self.pos += 1u;
 1108          b as int
 1109      }
 1110  
 1111      fn eof(&self) -> bool {
 1112          *self.pos == self.bytes.len()
 1113      }
 1114  
 1115      fn seek(&self, offsetint, whenceSeekStyle) {
 1116          let pos = *self.pos;
 1117          *self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence);
 1118      }
 1119  
 1120      fn tell(&self) -> uint {
 1121          *self.pos
 1122      }
 1123  }
 1124  
 1125  pub fn with_bytes_reader<T>(bytes&[u8], f&fn(@Reader) -> T) -> T {
 1126      // XXX XXX XXX this is glaringly unsound
 1127      // FIXME(#5723) Use a &Reader for the callback's argument. Should be:
 1128      // fn with_bytes_reader<'r, T>(bytes: &'r [u8], f: &fn(&'r Reader) -> T) -> T
 1129      let bytes&'static [u8] = unsafe { cast::transmute(bytes) };
 1130      f(@BytesReader {
 1131          bytes: bytes,
 1132          pos: @mut 0
 1133      } as @Reader)
 1134  }
 1135  
 1136  pub fn with_str_reader<T>(s&str, f&fn(@Reader) -> T) -> T {
 1137      // FIXME(#5723): As above.
 1138      with_bytes_reader(s.as_bytes(), f)
 1139  }
 1140  
 1141  // Writing
 1142  pub enum FileFlag { Append, Create, Truncate, NoFlag, }
 1143  
 1144  // What type of writer are we?
 1145  #[deriving(Eq)]
 1146  pub enum WriterType { Screen, File }
 1147  
 1148  // FIXME (#2004): Seekable really should be orthogonal.
 1149  // FIXME (#2004): eventually u64
 1150  /// The raw underlying writer trait. All writers must implement this.
 1151  pub trait Writer {
 1152  
 1153      /// Write all of the given bytes.
 1154      fn write(&self, v: &[u8]);
 1155  
 1156      /// Move the current position within the stream. The second parameter
 1157      /// determines the position that the first parameter is relative to.
 1158      fn seek(&self, int, SeekStyle);
 1159  
 1160      /// Return the current position within the stream.
 1161      fn tell(&self) -> uint;
 1162  
 1163      /// Flush the output buffer for this stream (if there is one).
 1164      fn flush(&self) -> int;
 1165  
 1166      /// Determine if this Writer is writing to a file or not.
 1167      fn get_type(&self) -> WriterType;
 1168  }
 1169  
 1170  impl Writer for @Writer {
 1171      fn write(&self, v&[u8]) { self.write(v) }
 1172      fn seek(&self, aint, bSeekStyle) { self.seek(a, b) }
 1173      fn tell(&self) -> uint { self.tell() }
 1174      fn flush(&self) -> int { self.flush() }
 1175      fn get_type(&self) -> WriterType { self.get_type() }
 1176  }
 1177  
 1178  impl<W:Writer,C> Writer for Wrapper<W, C> {
 1179      fn write(&self, bs&[u8]) { self.base.write(bs); }
 1180      fn seek(&self, offint, styleSeekStyle) { self.base.seek(off, style); }
 1181      fn tell(&self) -> uint { self.base.tell() }
 1182      fn flush(&self) -> int { self.base.flush() }
 1183      fn get_type(&self) -> WriterType { File }
 1184  }
 1185  
 1186  impl Writer for *libc::FILE {
 1187      fn write(&self, v&[u8]) {
 1188          #[fixed_stack_segment]; #[inline(never)];
 1189  
 1190          unsafe {
 1191              do v.as_imm_buf |vbuf, len| {
 1192                  let nout = libc::fwrite(vbuf as *c_void,
 1193                                          1,
 1194                                          len as size_t,
 1195                                          *self);
 1196                  if nout != len as size_t {
 1197                      error2!("error writing buffer: {}", os::last_os_error());
 1198                      fail2!();
 1199                  }
 1200              }
 1201          }
 1202      }
 1203      fn seek(&self, offsetint, whenceSeekStyle) {
 1204          #[fixed_stack_segment]; #[inline(never)];
 1205  
 1206          unsafe {
 1207              assert!(libc::fseek(*self,
 1208                                       offset as libc::c_long,
 1209                                       convert_whence(whence)) == 0 as c_int);
 1210          }
 1211      }
 1212      fn tell(&self) -> uint {
 1213          #[fixed_stack_segment]; #[inline(never)];
 1214  
 1215          unsafe {
 1216              libc::ftell(*self) as uint
 1217          }
 1218      }
 1219      fn flush(&self) -> int {
 1220          #[fixed_stack_segment]; #[inline(never)];
 1221  
 1222          unsafe {
 1223              libc::fflush(*self) as int
 1224          }
 1225      }
 1226      fn get_type(&self) -> WriterType {
 1227          #[fixed_stack_segment]; #[inline(never)];
 1228  
 1229          unsafe {
 1230              let fd = libc::fileno(*self);
 1231              if libc::isatty(fd) == 0 { File   }
 1232              else                     { Screen }
 1233          }
 1234      }
 1235  }
 1236  
 1237  impl Writer for fd_t {
 1238      fn write(&self, v&[u8]) {
 1239          #[fixed_stack_segment]; #[inline(never)];
 1240  
 1241          #[cfg(windows)]
 1242          type IoSize = libc::c_uint;
 1243          #[cfg(windows)]
 1244          type IoRet = c_int;
 1245  
 1246          #[cfg(unix)]
 1247          type IoSize = size_t;
 1248          #[cfg(unix)]
 1249          type IoRet = libc::ssize_t;
 1250  
 1251          unsafe {
 1252              let mut count = 0u;
 1253              do v.as_imm_buf |vbuf, len| {
 1254                  while count < len {
 1255                      let vb = ptr::offset(vbuf, count as int) as *c_void;
 1256                      let nout = libc::write(*self, vb, len as IoSize);
 1257                      if nout < 0 as IoRet {
 1258                          error2!("error writing buffer: {}", os::last_os_error());
 1259                          fail2!();
 1260                      }
 1261                      count += nout as uint;
 1262                  }
 1263              }
 1264          }
 1265      }
 1266      fn seek(&self, _offsetint, _whenceSeekStyle) {
 1267          error2!("need 64-bit foreign calls for seek, sorry");
 1268          fail2!();
 1269      }
 1270      fn tell(&self) -> uint {
 1271          error2!("need 64-bit foreign calls for tell, sorry");
 1272          fail2!();
 1273      }
 1274      fn flush(&self) -> int { 0 }
 1275      fn get_type(&self) -> WriterType {
 1276          #[fixed_stack_segment]; #[inline(never)];
 1277  
 1278          unsafe {
 1279              if libc::isatty(*self) == 0 { File } else { Screen }
 1280          }
 1281      }
 1282  }
 1283  
 1284  pub struct FdRes {
 1285      fd: fd_t,
 1286  }
 1287  
 1288  impl FdRes {
 1289      pub fn new(fdfd_t) -> FdRes {
 1290          FdRes { fd: fd }
 1291      }
 1292  }
 1293  
 1294  impl Drop for FdRes {
 1295      fn drop(&mut self) {
 1296          #[fixed_stack_segment]; #[inline(never)];
 1297  
 1298          unsafe {
 1299              libc::close(self.fd);
 1300          }
 1301      }
 1302  }
 1303  
 1304  pub fn fd_writer(fdfd_t, cleanupbool) -> @Writer {
 1305      if cleanup {
 1306          @Wrapper { base: fd, cleanup: FdRes::new(fd) } as @Writer
 1307      } else {
 1308          @fd as @Writer
 1309      }
 1310  }
 1311  
 1312  
 1313  pub fn mk_file_writer(path&Path, flags&[FileFlag])
 1314                     -> Result<@Writer, ~str> {
 1315      #[fixed_stack_segment]; #[inline(never)];
 1316  
 1317      #[cfg(windows)]
 1318      fn wb() -> c_int {
 1319        (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int
 1320      }
 1321  
 1322      #[cfg(unix)]
 1323      fn wb() -> c_int { O_WRONLY as c_int }
 1324  
 1325      let mut fflagsc_int = wb();
 1326      for f in flags.iter() {
 1327          match *f {
 1328            Append => fflags |= O_APPEND as c_int,
 1329            Create => fflags |= O_CREAT as c_int,
 1330            Truncate => fflags |= O_TRUNC as c_int,
 1331            NoFlag => ()
 1332          }
 1333      }
 1334      let fd = unsafe {
 1335          do path.with_c_str |pathbuf| {
 1336              libc::open(pathbuf, fflags, (S_IRUSR | S_IWUSR) as c_int)
 1337          }
 1338      };
 1339      if fd < (0 as c_int) {
 1340          Err(format!("error opening {}{}", path.display(), os::last_os_error()))
 1341      } else {
 1342          Ok(fd_writer(fd, true))
 1343      }
 1344  }
 1345  
 1346  pub fn u64_to_le_bytes<T>(nu64, sizeuint,
 1347                            f&fn(v: &[u8]) -> T) -> T {
 1348      assert!(size <= 8u);
 1349      match size {
 1350        1u => f(&[n as u8]),
 1351        2u => f(&[n as u8,
 1352                (n >> 8) as u8]),
 1353        4u => f(&[n as u8,
 1354                (n >> 8) as u8,
 1355                (n >> 16) as u8,
 1356                (n >> 24) as u8]),
 1357        8u => f(&[n as u8,
 1358                (n >> 8) as u8,
 1359                (n >> 16) as u8,
 1360                (n >> 24) as u8,
 1361                (n >> 32) as u8,
 1362                (n >> 40) as u8,
 1363                (n >> 48) as u8,
 1364                (n >> 56) as u8]),
 1365        _ => {
 1366  
 1367          let mut bytes~[u8] = ~[];
 1368          let mut i = size;
 1369          let mut n = n;
 1370          while i > 0u {
 1371              bytes.push((n & 255_u64) as u8);
 1372              n >>= 8_u64;
 1373              i -= 1u;
 1374          }
 1375          f(bytes)
 1376        }
 1377      }
 1378  }
 1379  
 1380  pub fn u64_to_be_bytes<T>(nu64, sizeuint,
 1381                             f&fn(v: &[u8]) -> T) -> T {
 1382      assert!(size <= 8u);
 1383      match size {
 1384        1u => f(&[n as u8]),
 1385        2u => f(&[(n >> 8) as u8,
 1386                n as u8]),
 1387        4u => f(&[(n >> 24) as u8,
 1388                (n >> 16) as u8,
 1389                (n >> 8) as u8,
 1390                n as u8]),
 1391        8u => f(&[(n >> 56) as u8,
 1392                (n >> 48) as u8,
 1393                (n >> 40) as u8,
 1394                (n >> 32) as u8,
 1395                (n >> 24) as u8,
 1396                (n >> 16) as u8,
 1397                (n >> 8) as u8,
 1398                n as u8]),
 1399        _ => {
 1400          let mut bytes~[u8] = ~[];
 1401          let mut i = size;
 1402          while i > 0u {
 1403              let shift = ((i - 1u) * 8u) as u64;
 1404              bytes.push((n >> shift) as u8);
 1405              i -= 1u;
 1406          }
 1407          f(bytes)
 1408        }
 1409      }
 1410  }
 1411  
 1412  pub fn u64_from_be_bytes(data&[u8],
 1413                           startuint,
 1414                           sizeuint)
 1415                        -> u64 {
 1416      let mut sz = size;
 1417      assert!((sz <= 8u));
 1418      let mut val = 0_u64;
 1419      let mut pos = start;
 1420      while sz > 0u {
 1421          sz -= 1u;
 1422          val += (data[pos] as u64) << ((sz * 8u) as u64);
 1423          pos += 1u;
 1424      }
 1425      return val;
 1426  }
 1427  
 1428  // FIXME: #3048 combine trait+impl (or just move these to
 1429  // default methods on writer)
 1430  /// Generic utility functions defined on writers.
 1431  pub trait WriterUtil {
 1432  
 1433      /// Write a single utf-8 encoded char.
 1434      fn write_char(&self, ch: char);
 1435  
 1436      /// Write every char in the given str, encoded as utf-8.
 1437      fn write_str(&self, s: &str);
 1438  
 1439      /// Write the given str, as utf-8, followed by '\n'.
 1440      fn write_line(&self, s: &str);
 1441  
 1442      /// Write the result of passing n through `int::to_str_bytes`.
 1443      fn write_int(&self, n: int);
 1444  
 1445      /// Write the result of passing n through `uint::to_str_bytes`.
 1446      fn write_uint(&self, n: uint);
 1447  
 1448      /// Write a little-endian uint (number of bytes depends on system).
 1449      fn write_le_uint(&self, n: uint);
 1450  
 1451      /// Write a little-endian int (number of bytes depends on system).
 1452      fn write_le_int(&self, n: int);
 1453  
 1454      /// Write a big-endian uint (number of bytes depends on system).
 1455      fn write_be_uint(&self, n: uint);
 1456  
 1457      /// Write a big-endian int (number of bytes depends on system).
 1458      fn write_be_int(&self, n: int);
 1459  
 1460      /// Write a big-endian u64 (8 bytes).
 1461      fn write_be_u64(&self, n: u64);
 1462  
 1463      /// Write a big-endian u32 (4 bytes).
 1464      fn write_be_u32(&self, n: u32);
 1465  
 1466      /// Write a big-endian u16 (2 bytes).
 1467      fn write_be_u16(&self, n: u16);
 1468  
 1469      /// Write a big-endian i64 (8 bytes).
 1470      fn write_be_i64(&self, n: i64);
 1471  
 1472      /// Write a big-endian i32 (4 bytes).
 1473      fn write_be_i32(&self, n: i32);
 1474  
 1475      /// Write a big-endian i16 (2 bytes).
 1476      fn write_be_i16(&self, n: i16);
 1477  
 1478      /// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
 1479      fn write_be_f64(&self, f: f64);
 1480  
 1481      /// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
 1482      fn write_be_f32(&self, f: f32);
 1483  
 1484      /// Write a little-endian u64 (8 bytes).
 1485      fn write_le_u64(&self, n: u64);
 1486  
 1487      /// Write a little-endian u32 (4 bytes).
 1488      fn write_le_u32(&self, n: u32);
 1489  
 1490      /// Write a little-endian u16 (2 bytes).
 1491      fn write_le_u16(&self, n: u16);
 1492  
 1493      /// Write a little-endian i64 (8 bytes).
 1494      fn write_le_i64(&self, n: i64);
 1495  
 1496      /// Write a little-endian i32 (4 bytes).
 1497      fn write_le_i32(&self, n: i32);
 1498  
 1499      /// Write a little-endian i16 (2 bytes).
 1500      fn write_le_i16(&self, n: i16);
 1501  
 1502      /// Write a little-endian IEEE754 double-precision floating-point
 1503      /// (8 bytes).
 1504      fn write_le_f64(&self, f: f64);
 1505  
 1506      /// Write a little-endian IEEE754 single-precision floating-point
 1507      /// (4 bytes).
 1508      fn write_le_f32(&self, f: f32);
 1509  
 1510      /// Write a u8 (1 byte).
 1511      fn write_u8(&self, n: u8);
 1512  
 1513      /// Write a i8 (1 byte).
 1514      fn write_i8(&self, n: i8);
 1515  }
 1516  
 1517  impl<T:Writer> WriterUtil for T {
 1518      fn write_char(&self, chchar) {
 1519          if (ch as uint) < 128u {
 1520              self.write(&[ch as u8]);
 1521          } else {
 1522              self.write_str(str::from_char(ch));
 1523          }
 1524      }
 1525      fn write_str(&self, s&str) { self.write(s.as_bytes()) }
 1526      fn write_line(&self, s&str) {
 1527          self.write_str(s);
 1528          self.write_str(&"\n");
 1529      }
 1530      fn write_int(&self, nint) {
 1531          int::to_str_bytes(n, 10u, |bytes| self.write(bytes))
 1532      }
 1533      fn write_uint(&self, nuint) {
 1534          uint::to_str_bytes(n, 10u, |bytes| self.write(bytes))
 1535      }
 1536      fn write_le_uint(&self, nuint) {
 1537          u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v))
 1538      }
 1539      fn write_le_int(&self, nint) {
 1540          u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v))
 1541      }
 1542      fn write_be_uint(&self, nuint) {
 1543          u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v))
 1544      }
 1545      fn write_be_int(&self, nint) {
 1546          u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v))
 1547      }
 1548      fn write_be_u64(&self, nu64) {
 1549          u64_to_be_bytes(n, 8u, |v| self.write(v))
 1550      }
 1551      fn write_be_u32(&self, nu32) {
 1552          u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
 1553      }
 1554      fn write_be_u16(&self, nu16) {
 1555          u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
 1556      }
 1557      fn write_be_i64(&self, ni64) {
 1558          u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
 1559      }
 1560      fn write_be_i32(&self, ni32) {
 1561          u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
 1562      }
 1563      fn write_be_i16(&self, ni16) {
 1564          u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
 1565      }
 1566      fn write_be_f64(&self, f:f64) {
 1567          unsafe {
 1568              self.write_be_u64(cast::transmute(f))
 1569          }
 1570      }
 1571      fn write_be_f32(&self, f:f32) {
 1572          unsafe {
 1573              self.write_be_u32(cast::transmute(f))
 1574          }
 1575      }
 1576      fn write_le_u64(&self, nu64) {
 1577          u64_to_le_bytes(n, 8u, |v| self.write(v))
 1578      }
 1579      fn write_le_u32(&self, nu32) {
 1580          u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
 1581      }
 1582      fn write_le_u16(&self, nu16) {
 1583          u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
 1584      }
 1585      fn write_le_i64(&self, ni64) {
 1586          u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
 1587      }
 1588      fn write_le_i32(&self, ni32) {
 1589          u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
 1590      }
 1591      fn write_le_i16(&self, ni16) {
 1592          u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
 1593      }
 1594      fn write_le_f64(&self, f:f64) {
 1595          unsafe {
 1596              self.write_le_u64(cast::transmute(f))
 1597          }
 1598      }
 1599      fn write_le_f32(&self, f:f32) {
 1600          unsafe {
 1601              self.write_le_u32(cast::transmute(f))
 1602          }
 1603      }
 1604  
 1605      fn write_u8(&self, nu8) { self.write([n]) }
 1606      fn write_i8(&self, ni8) { self.write([n as u8]) }
 1607  
 1608  }
 1609  
 1610  pub fn file_writer(path&Path, flags&[FileFlag]) -> Result<@Writer, ~str> {
 1611      mk_file_writer(path, flags).and_then(|w| Ok(w))
 1612  }
 1613  
 1614  // FIXME (#2004) it would be great if this could be a const
 1615  // FIXME (#2004) why are these different from the way stdin() is
 1616  // implemented?
 1617  
 1618  
 1619  /**
 1620  * Gives a `Writer` which allows you to write to the standard output.
 1621  *
 1622  * # Example
 1623  *
 1624  * ```rust
 1625  * let stdout = std::io::stdout();
 1626  * stdout.write_str("hello\n");
 1627  * ```
 1628  */
 1629  pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
 1630  
 1631  /**
 1632  * Gives a `Writer` which allows you to write to standard error.
 1633  *
 1634  * # Example
 1635  *
 1636  * ```rust
 1637  * let stderr = std::io::stderr();
 1638  * stderr.write_str("hello\n");
 1639  * ```
 1640  */
 1641  pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
 1642  
 1643  /**
 1644  * Prints a string to standard output.
 1645  *
 1646  * This string will not have an implicit newline at the end. If you want
 1647  * an implicit newline, please see `println`.
 1648  *
 1649  * # Example
 1650  *
 1651  * ```rust
 1652  * // print is imported into the prelude, and so is always available.
 1653  * print("hello");
 1654  * ```
 1655  */
 1656  pub fn print(s&str) {
 1657      stdout().write_str(s);
 1658  }
 1659  
 1660  /**
 1661  * Prints a string to standard output, followed by a newline.
 1662  *
 1663  * If you do not want an implicit newline, please see `print`.
 1664  *
 1665  * # Example
 1666  *
 1667  * ```rust
 1668  * // println is imported into the prelude, and so is always available.
 1669  * println("hello");
 1670  * ```
 1671  */
 1672  pub fn println(s&str) {
 1673      stdout().write_line(s);
 1674  }
 1675  
 1676  pub struct BytesWriter {
 1677      bytes: @mut ~[u8],
 1678      pos: @mut uint,
 1679  }
 1680  
 1681  impl BytesWriter {
 1682      pub fn new() -> BytesWriter {
 1683          BytesWriter {
 1684              bytes: @mut ~[],
 1685              pos: @mut 0
 1686          }
 1687      }
 1688  }
 1689  
 1690  impl Writer for BytesWriter {
 1691      fn write(&self, v&[u8]) {
 1692          let v_len = v.len();
 1693  
 1694          let bytes = &mut *self.bytes;
 1695          let count = num::max(bytes.len(), *self.pos + v_len);
 1696          bytes.reserve(count);
 1697  
 1698          unsafe {
 1699              vec::raw::set_len(bytes, count);
 1700  
 1701              let view = bytes.mut_slice(*self.pos, count);
 1702              vec::bytes::copy_memory(view, v, v_len);
 1703          }
 1704  
 1705          *self.pos += v_len;
 1706      }
 1707  
 1708      fn seek(&self, offsetint, whenceSeekStyle) {
 1709          let pos = *self.pos;
 1710          let len = self.bytes.len();
 1711          *self.pos = seek_in_buf(offset, pos, len, whence);
 1712      }
 1713  
 1714      fn tell(&self) -> uint {
 1715          *self.pos
 1716      }
 1717  
 1718      fn flush(&self) -> int {
 1719          0
 1720      }
 1721  
 1722      fn get_type(&self) -> WriterType {
 1723          File
 1724      }
 1725  }
 1726  
 1727  pub fn with_bytes_writer(f&fn(@Writer)) -> ~[u8] {
 1728      let wr = @BytesWriter::new();
 1729      f(wr as @Writer);
 1730      let @BytesWriter { bytes, _ } = wr;
 1731      (*bytes).clone()
 1732  }
 1733  
 1734  pub fn with_str_writer(f&fn(@Writer)) -> ~str {
 1735      str::from_utf8(with_bytes_writer(f))
 1736  }
 1737  
 1738  // Utility functions
 1739  pub fn seek_in_buf(offsetint, posuint, lenuint, whenceSeekStyle) ->
 1740     uint {
 1741      let mut bpos = pos as int;
 1742      let blen = len as int;
 1743      match whence {
 1744        SeekSet => bpos = offset,
 1745        SeekCur => bpos += offset,
 1746        SeekEnd => bpos = blen + offset
 1747      }
 1748      if bpos < 0 { bpos = 0; } else if bpos > blen { bpos = blen; }
 1749      return bpos as uint;
 1750  }
 1751  
 1752  pub fn read_whole_file_str(file&Path) -> Result<~str, ~str> {
 1753      do read_whole_file(file).and_then |bytes| {
 1754          if str::is_utf8(bytes) {
 1755              Ok(str::from_utf8(bytes))
 1756          } else {
 1757              Err(file.display().to_str() + " is not UTF-8")
 1758          }
 1759      }
 1760  }
 1761  
 1762  // FIXME (#2004): implement this in a low-level way. Going through the
 1763  // abstractions is pointless.
 1764  pub fn read_whole_file(file&Path) -> Result<~[u8], ~str> {
 1765      do file_reader(file).and_then |rdr| {
 1766          Ok(rdr.read_whole_stream())
 1767      }
 1768  }
 1769  
 1770  // fsync related
 1771  
 1772  pub mod fsync {
 1773      use io::{FILERes, FdRes, fd_t};
 1774      use libc;
 1775      use ops::Drop;
 1776      use option::{None, Option, Some};
 1777      use os;
 1778  
 1779      pub enum Level {
 1780          // whatever fsync does on that platform
 1781          FSync,
 1782  
 1783          // fdatasync on linux, similiar or more on other platforms
 1784          FDataSync,
 1785  
 1786          // full fsync
 1787          //
 1788          // You must additionally sync the parent directory as well!
 1789          FullFSync,
 1790      }
 1791  
 1792  
 1793      // Artifacts that need to fsync on destruction
 1794      pub struct Res<t> {
 1795          arg: Arg<t>,
 1796      }
 1797  
 1798      impl <t> Res<t> {
 1799          pub fn new(argArg<t>) -> Res<t> {
 1800              Res { arg: arg }
 1801          }
 1802      }
 1803  
 1804      #[unsafe_destructor]
 1805      impl<T> Drop for Res<T> {
 1806          fn drop(&mut self) {
 1807              match self.arg.opt_level {
 1808                  None => (),
 1809                  Some(level) => {
 1810                    // fail hard if not succesful
 1811                    assert!(((self.arg.fsync_fn)(&self.arg.val, level) != -1));
 1812                  }
 1813              }
 1814          }
 1815      }
 1816  
 1817      pub struct Arg<t> {
 1818          val: t,
 1819          opt_level: Option<Level>,
 1820          fsync_fn: extern "Rust" fn(f: &t, Level) -> int,
 1821      }
 1822  
 1823      // fsync file after executing blk
 1824      // FIXME (#2004) find better way to create resources within lifetime of
 1825      // outer res
 1826      pub fn FILE_res_sync(file&FILERes,
 1827                           opt_levelOption<Level>,
 1828                           blk&fn(v: Res<*libc::FILE>)) {
 1829          blk(Res::new(Arg {
 1830              val: file.f,
 1831              opt_level: opt_level,
 1832              fsync_fn: fsync_FILE,
 1833          }));
 1834  
 1835          fn fileno(stream*libc::FILE) -> libc::c_int {
 1836              #[fixed_stack_segment]; #[inline(never)];
 1837              unsafe { libc::fileno(stream) }
 1838          }
 1839  
 1840          fn fsync_FILE(stream&*libc::FILE, levelLevel) -> int {
 1841              fsync_fd(fileno(*stream), level)
 1842          }
 1843      }
 1844  
 1845      // fsync fd after executing blk
 1846      pub fn fd_res_sync(fd&FdRes, opt_levelOption<Level>,
 1847                         blk&fn(v: Res<fd_t>)) {
 1848          blk(Res::new(Arg {
 1849              val: fd.fd,
 1850              opt_level: opt_level,
 1851              fsync_fn: fsync_fd_helper,
 1852          }));
 1853      }
 1854  
 1855      fn fsync_fd(fdlibc::c_int, levelLevel) -> int {
 1856          #[fixed_stack_segment]; #[inline(never)];
 1857  
 1858          os::fsync_fd(fd, level) as int
 1859      }
 1860  
 1861      fn fsync_fd_helper(fd_ptr&libc::c_int, levelLevel) -> int {
 1862          fsync_fd(*fd_ptr, level)
 1863      }
 1864  
 1865      // Type of objects that may want to fsync
 1866      pub trait FSyncable { fn fsync(&self, l: Level) -> int; }
 1867  
 1868      // Call o.fsync after executing blk
 1869      pub fn obj_sync(o@FSyncable, opt_levelOption<Level>,
 1870                      blk&fn(v: Res<@FSyncable>)) {
 1871          blk(Res::new(Arg {
 1872              val: o,
 1873              opt_level: opt_level,
 1874              fsync_fn: obj_fsync_fn,
 1875          }));
 1876      }
 1877  
 1878      fn obj_fsync_fn(o&@FSyncable, levelLevel) -> int {
 1879          (*o).fsync(level)
 1880      }
 1881  }
 1882  
 1883  #[cfg(test)]
 1884  mod tests {
 1885      use prelude::*;
 1886      use i32;
 1887      use io::{BytesWriter, SeekCur, SeekEnd, SeekSet};
 1888      use io;
 1889      use path::Path;
 1890      use result::{Ok, Err};
 1891      use u64;
 1892      use vec;
 1893      use cast::transmute;
 1894  
 1895      #[test]
 1896      fn test_simple() {
 1897          let tmpfile = &Path::new("tmp/lib-io-test-simple.tmp");
 1898          debug2!("{}", tmpfile.display());
 1899          let frood: ~str =
 1900              ~"A hoopy frood who really knows where his towel is.";
 1901          debug2!("{}", frood.clone());
 1902          {
 1903              let out = io::file_writer(tmpfile, [io::Create, io::Truncate]).unwrap();
 1904              out.write_str(frood);
 1905          }
 1906          let inp = io::file_reader(tmpfile).unwrap();
 1907          let frood2: ~str = inp.read_c_str();
 1908          debug2!("{}", frood2.clone());
 1909          assert_eq!(frood, frood2);
 1910      }
 1911  
 1912      #[test]
 1913      fn test_each_byte_each_char_file() {
 1914          // Issue #5056 -- shouldn't include trailing EOF.
 1915          let path = Path::new("tmp/lib-io-test-each-byte-each-char-file.tmp");
 1916  
 1917          {
 1918              // create empty, enough to reproduce a problem
 1919              io::file_writer(&path, [io::Create]).unwrap();
 1920          }
 1921  
 1922          {
 1923              let file = io::file_reader(&path).unwrap();
 1924              do file.each_byte() |_| {
 1925                  fail2!("must be empty")
 1926              };
 1927          }
 1928  
 1929          {
 1930              let file = io::file_reader(&path).unwrap();
 1931              do file.each_char() |_| {
 1932                  fail2!("must be empty")
 1933              };
 1934          }
 1935      }
 1936  
 1937      #[test]
 1938      fn test_readchars_empty() {
 1939          do io::with_str_reader("") |inp| {
 1940              let res : ~[char] = inp.read_chars(128);
 1941              assert_eq!(res.len(), 0);
 1942          }
 1943      }
 1944  
 1945      #[test]
 1946      fn test_read_line_utf8() {
 1947          do io::with_str_reader("生锈的汤匙切肉汤hello生锈的汤匙切肉汤") |inp| {
 1948              let line = inp.read_line();
 1949              assert_eq!(line, ~"生锈的汤匙切肉汤hello生锈的汤匙切肉汤");
 1950          }
 1951      }
 1952  
 1953      #[test]
 1954      fn test_read_lines() {
 1955          do io::with_str_reader("a\nb\nc\n") |inp| {
 1956              assert_eq!(inp.read_lines(), ~[~"a", ~"b", ~"c"]);
 1957          }
 1958  
 1959          do io::with_str_reader("a\nb\nc") |inp| {
 1960              assert_eq!(inp.read_lines(), ~[~"a", ~"b", ~"c"]);
 1961          }
 1962  
 1963          do io::with_str_reader("") |inp| {
 1964              assert!(inp.read_lines().is_empty());
 1965          }
 1966      }
 1967  
 1968      #[test]
 1969      fn test_readchars_wide() {
 1970          let wide_test = ~"生锈的汤匙切肉汤hello生锈的汤匙切肉汤";
 1971          let ivals : ~[int] = ~[
 1972              29983, 38152, 30340, 27748,
 1973              21273, 20999, 32905, 27748,
 1974              104, 101, 108, 108, 111,
 1975              29983, 38152, 30340, 27748,
 1976              21273, 20999, 32905, 27748];
 1977          fn check_read_ln(len : uint, s: &str, ivals: &[int]) {
 1978              do io::with_str_reader(s) |inp| {
 1979                  let res : ~[char] = inp.read_chars(len);
 1980                  if len <= ivals.len() {
 1981                      assert_eq!(res.len(), len);
 1982                  }
 1983                  for (iv, c) in ivals.iter().zip(res.iter()) {
 1984                      assert!(*iv == *c as int)
 1985                  }
 1986              }
 1987          }
 1988          let mut i = 0;
 1989          while i < 8 {
 1990              check_read_ln(i, wide_test, ivals);
 1991              i += 1;
 1992          }
 1993          // check a long read for good measure
 1994          check_read_ln(128, wide_test, ivals);
 1995      }
 1996  
 1997      #[test]
 1998      fn test_readchar() {
 1999          do io::with_str_reader("生") |inp| {
 2000              let res = inp.read_char();
 2001              assert_eq!(res as int, 29983);
 2002          }
 2003      }
 2004  
 2005      #[test]
 2006      fn test_readchar_empty() {
 2007          do io::with_str_reader("") |inp| {
 2008              let res = inp.read_char();
 2009              assert_eq!(res, unsafe { transmute(-1u32) }); // FIXME: #8971: unsound
 2010          }
 2011      }
 2012  
 2013      #[test]
 2014      fn file_reader_not_exist() {
 2015          match io::file_reader(&Path::new("not a file")) {
 2016            Err(e) => {
 2017              assert_eq!(e, ~"error opening not a file");
 2018            }
 2019            Ok(_) => fail2!()
 2020          }
 2021      }
 2022  
 2023      #[test]
 2024      #[should_fail]
 2025      fn test_read_buffer_too_small() {
 2026          let path = &Path::new("tmp/lib-io-test-read-buffer-too-small.tmp");
 2027          // ensure the file exists
 2028          io::file_writer(path, [io::Create]).unwrap();
 2029  
 2030          let file = io::file_reader(path).unwrap();
 2031          let mut buf = vec::from_elem(5, 0u8);
 2032          file.read(buf, 6); // this should fail because buf is too small
 2033      }
 2034  
 2035      #[test]
 2036      fn test_read_buffer_big_enough() {
 2037          let path = &Path::new("tmp/lib-io-test-read-buffer-big-enough.tmp");
 2038          // ensure the file exists
 2039          io::file_writer(path, [io::Create]).unwrap();
 2040  
 2041          let file = io::file_reader(path).unwrap();
 2042          let mut buf = vec::from_elem(5, 0u8);
 2043          file.read(buf, 4); // this should succeed because buf is big enough
 2044      }
 2045  
 2046      #[test]
 2047      fn test_write_empty() {
 2048          let file = io::file_writer(&Path::new("tmp/lib-io-test-write-empty.tmp"),
 2049                                     [io::Create]).unwrap();
 2050          file.write([]);
 2051      }
 2052  
 2053      #[test]
 2054      fn file_writer_bad_name() {
 2055          match io::file_writer(&Path::new("?/?"), []) {
 2056            Err(e) => {
 2057              assert!(e.starts_with("error opening"));
 2058            }
 2059            Ok(_) => fail2!()
 2060          }
 2061      }
 2062  
 2063      #[test]
 2064      fn bytes_buffer_overwrite() {
 2065          let wr = BytesWriter::new();
 2066          wr.write([0u8, 1u8, 2u8, 3u8]);
 2067          assert!(*wr.bytes == ~[0u8, 1u8, 2u8, 3u8]);
 2068          wr.seek(-2, SeekCur);
 2069          wr.write([4u8, 5u8, 6u8, 7u8]);
 2070          assert!(*wr.bytes == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]);
 2071          wr.seek(-2, SeekEnd);
 2072          wr.write([8u8]);
 2073          wr.seek(1, SeekSet);
 2074          wr.write([9u8]);
 2075          assert!(*wr.bytes == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]);
 2076      }
 2077  
 2078      #[test]
 2079      fn test_read_write_le() {
 2080          let path = Path::new("tmp/lib-io-test-read-write-le.tmp");
 2081          let uints = [0, 1, 2, 42, 10_123, 100_123_456, u64::max_value];
 2082  
 2083          // write the ints to the file
 2084          {
 2085              let file = io::file_writer(&path, [io::Create]).unwrap();
 2086              for i in uints.iter() {
 2087                  file.write_le_u64(*i);
 2088              }
 2089          }
 2090  
 2091          // then read them back and check that they are the same
 2092          {
 2093              let file = io::file_reader(&path).unwrap();
 2094              for i in uints.iter() {
 2095                  assert_eq!(file.read_le_u64(), *i);
 2096              }
 2097          }
 2098      }
 2099  
 2100      #[test]
 2101      fn test_read_write_be() {
 2102          let path = Path::new("tmp/lib-io-test-read-write-be.tmp");
 2103          let uints = [0, 1, 2, 42, 10_123, 100_123_456, u64::max_value];
 2104  
 2105          // write the ints to the file
 2106          {
 2107              let file = io::file_writer(&path, [io::Create]).unwrap();
 2108              for i in uints.iter() {
 2109                  file.write_be_u64(*i);
 2110              }
 2111          }
 2112  
 2113          // then read them back and check that they are the same
 2114          {
 2115              let file = io::file_reader(&path).unwrap();
 2116              for i in uints.iter() {
 2117                  assert_eq!(file.read_be_u64(), *i);
 2118              }
 2119          }
 2120      }
 2121  
 2122      #[test]
 2123      fn test_read_be_int_n() {
 2124          let path = Path::new("tmp/lib-io-test-read-be-int-n.tmp");
 2125          let ints = [i32::min_value, -123456, -42, -5, 0, 1, i32::max_value];
 2126  
 2127          // write the ints to the file
 2128          {
 2129              let file = io::file_writer(&path, [io::Create]).unwrap();
 2130              for i in ints.iter() {
 2131                  file.write_be_i32(*i);
 2132              }
 2133          }
 2134  
 2135          // then read them back and check that they are the same
 2136          {
 2137              let file = io::file_reader(&path).unwrap();
 2138              for i in ints.iter() {
 2139                  // this tests that the sign extension is working
 2140                  // (comparing the values as i32 would not test this)
 2141                  assert_eq!(file.read_be_int_n(4), *i as i64);
 2142              }
 2143          }
 2144      }
 2145  
 2146      #[test]
 2147      fn test_read_f32() {
 2148          let path = Path::new("tmp/lib-io-test-read-f32.tmp");
 2149          //big-endian floating-point 8.1250
 2150          let buf = ~[0x41, 0x02, 0x00, 0x00];
 2151  
 2152          {
 2153              let file = io::file_writer(&path, [io::Create]).unwrap();
 2154              file.write(buf);
 2155          }
 2156  
 2157          {
 2158              let file = io::file_reader(&path).unwrap();
 2159              let f = file.read_be_f32();
 2160              assert_eq!(f, 8.1250);
 2161          }
 2162      }
 2163  
 2164      #[test]
 2165      fn test_read_write_f32() {
 2166          let path = Path::new("tmp/lib-io-test-read-write-f32.tmp");
 2167          let f:f32 = 8.1250;
 2168  
 2169          {
 2170              let file = io::file_writer(&path, [io::Create]).unwrap();
 2171              file.write_be_f32(f);
 2172              file.write_le_f32(f);
 2173          }
 2174  
 2175          {
 2176              let file = io::file_reader(&path).unwrap();
 2177              assert_eq!(file.read_be_f32(), 8.1250);
 2178              assert_eq!(file.read_le_f32(), 8.1250);
 2179          }
 2180      }
 2181  }

libstd/io.rs:1345:1-1345:1 -fn- definition:

pub fn u64_to_le_bytes<T>(n: u64, size: uint,
references:-
1592:         u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
1583:         u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
1586:         u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
1589:         u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
1577:         u64_to_le_bytes(n, 8u, |v| self.write(v))
1537:         u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v))
1580:         u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
1540:         u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v))
libstd/rt/io/extensions.rs:
608:         u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
592:         u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
536:         u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v))
596:         u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
604:         u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
600:         u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
588:         u64_to_le_bytes(n, 8u, |v| self.write(v))
540:         u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v))


libstd/io.rs:1145:16-1145:16 -enum- definition:
#[deriving(Eq)]
pub enum WriterType { Screen, File }
references:-
1145: #[deriving(Eq)]
1722:     fn get_type(&self) -> WriterType {
1145: #[deriving(Eq)]
1167:     fn get_type(&self) -> WriterType;
1175:     fn get_type(&self) -> WriterType { self.get_type() }
1183:     fn get_type(&self) -> WriterType { File }
1226:     fn get_type(&self) -> WriterType {
1145: #[deriving(Eq)]
1275:     fn get_type(&self) -> WriterType {


libstd/io.rs:1835:8-1835:8 -fn- definition:
        fn fileno(stream: *libc::FILE) -> libc::c_int {
            #[fixed_stack_segment]; #[inline(never)];
references:-
1841:             fsync_fd(fileno(*stream), level)


libstd/io.rs:990:1-990:1 -struct- definition:

struct Wrapper<T, C> {
references:-
1306:         @Wrapper { base: fd, cleanup: FdRes::new(fd) } as @Writer
1178: impl<W:Writer,C> Writer for Wrapper<W, C> {
1033:         @Wrapper { base: f, cleanup: FILERes::new(f) } as @Reader
999: impl<R:Reader,C> Reader for Wrapper<R, C> {


libstd/io.rs:926:1-926:1 -fn- definition:

fn convert_whence(whence: SeekStyle) -> i32 {
references:-
1209:                                      convert_whence(whence)) == 0 as c_int);
979:                                      convert_whence(whence)) == 0 as c_int);


libstd/io.rs:1249:8-1249:8 -ty- definition:
        type IoRet = libc::ssize_t;

references:-
1257:                     if nout < 0 as IoRet {


libstd/io.rs:1430:50-1430:50 -trait- definition:
/// Generic utility functions defined on writers.
pub trait WriterUtil {
references:-
1517: impl<T:Writer> WriterUtil for T {


libstd/io.rs:1628:3-1628:3 -fn- definition:
*/
pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
references:-
1673:     stdout().write_line(s);
1657:     stdout().write_str(s);


libstd/io.rs:1030:1-1030:1 -fn- definition:

pub fn FILE_reader(f: *libc::FILE, cleanup: bool) -> @Reader {
references:-
1076:         Ok(FILE_reader(f, true))


libstd/io.rs:1010:1-1010:1 -struct- definition:

pub struct FILERes {
references:-
1016:     pub fn new(f: *libc::FILE) -> FILERes {
1826:     pub fn FILE_res_sync(file: &FILERes,
1017:         FILERes { f: f }
1021: impl Drop for FILERes {
1015: impl FILERes {


libstd/io.rs:1861:4-1861:4 -fn- definition:
    fn fsync_fd_helper(fd_ptr: &libc::c_int, level: Level) -> int {
        fsync_fd(*fd_ptr, level)
references:-
1851:             fsync_fn: fsync_fd_helper,


libstd/io.rs:1738:21-1738:21 -fn- definition:
// Utility functions
pub fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
references:-
1117:         *self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence);
1711:         *self.pos = seek_in_buf(offset, pos, len, whence);


libstd/io.rs:1794:4-1794:4 -struct- definition:
    pub struct Res<t> {
        arg: Arg<t>,
references:-
1805:     impl<T> Drop for Res<T> {
1870:                     blk: &fn(v: Res<@FSyncable>)) {
1799:         pub fn new(arg: Arg<t>) -> Res<t> {
1800:             Res { arg: arg }
1828:                          blk: &fn(v: Res<*libc::FILE>)) {
1798:     impl <t> Res<t> {
1847:                        blk: &fn(v: Res<fd_t>)) {


libstd/io.rs:653:8-653:8 -fn- definition:
        fn chars_from_utf8<T:Reader>(bytes: &~[u8], chars: &mut ~[char])
            -> (uint, uint) {
references:-
703:             let (offset, nbreq) = chars_from_utf8::<T>(&bytes, &mut chars);


libstd/io.rs:1150:70-1150:70 -trait- definition:
/// The raw underlying writer trait. All writers must implement this.
pub trait Writer {
references:-
1517: impl<T:Writer> WriterUtil for T {
1690: impl Writer for BytesWriter {
1629: pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
1727: pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] {
1610: pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {
1729:     f(wr as @Writer);
1170: impl Writer for @Writer {
1308:         @fd as @Writer
1306:         @Wrapper { base: fd, cleanup: FdRes::new(fd) } as @Writer
1734: pub fn with_str_writer(f: &fn(@Writer)) -> ~str {
1178: impl<W:Writer,C> Writer for Wrapper<W, C> {
1170: impl Writer for @Writer {
1314:                    -> Result<@Writer, ~str> {
1237: impl Writer for fd_t {
1304: pub fn fd_writer(fd: fd_t, cleanup: bool) -> @Writer {
1178: impl<W:Writer,C> Writer for Wrapper<W, C> {
1186: impl Writer for *libc::FILE {
1641: pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }


libstd/io.rs:1283:1-1283:1 -struct- definition:

pub struct FdRes {
references:-
1294: impl Drop for FdRes {
1288: impl FdRes {
1289:     pub fn new(fd: fd_t) -> FdRes {
1290:         FdRes { fd: fd }
1846:     pub fn fd_res_sync(fd: &FdRes, opt_level: Option<Level>,


libstd/io.rs:1817:4-1817:4 -struct- definition:
    pub struct Arg<t> {
        val: t,
references:-
1848:         blk(Res::new(Arg {
1795:         arg: Arg<t>,
1871:         blk(Res::new(Arg {
1829:         blk(Res::new(Arg {
1799:         pub fn new(arg: Arg<t>) -> Res<t> {


libstd/io.rs:1061:1-1061:1 -fn- definition:

pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
references:-
1765:     do file_reader(file).and_then |rdr| {


libstd/io.rs:1303:1-1303:1 -fn- definition:

pub fn fd_writer(fd: fd_t, cleanup: bool) -> @Writer {
references:-
1641: pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
1342:         Ok(fd_writer(fd, true))
1629: pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }


libstd/io.rs:1779:4-1779:4 -enum- definition:
    pub enum Level {
        // whatever fsync does on that platform
references:-
1869:     pub fn obj_sync(o: @FSyncable, opt_level: Option<Level>,
1861:     fn fsync_fd_helper(fd_ptr: &libc::c_int, level: Level) -> int {
1819:         opt_level: Option<Level>,
1840:         fn fsync_FILE(stream: &*libc::FILE, level: Level) -> int {
1855:     fn fsync_fd(fd: libc::c_int, level: Level) -> int {
1866:     pub trait FSyncable { fn fsync(&self, l: Level) -> int; }
1846:     pub fn fd_res_sync(fd: &FdRes, opt_level: Option<Level>,
1820:         fsync_fn: extern "Rust" fn(f: &t, Level) -> int,
1827:                          opt_level: Option<Level>,
1878:     fn obj_fsync_fn(o: &@FSyncable, level: Level) -> int {
libstd/os.rs:
340: pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {


libstd/io.rs:1323:4-1323:4 -fn- definition:
    fn wb() -> c_int { O_WRONLY as c_int }

references:-
1325:     let mut fflags: c_int = wb();


libstd/io.rs:1081:16-1081:16 -struct- definition:
// Byte readers
pub struct BytesReader {
references:-
1089: impl Reader for BytesReader {
1130:     f(@BytesReader {


libstd/io.rs:218:3-218:3 -trait- definition:
*/
pub trait ReaderUtil {
references:-
620: impl<T:Reader> ReaderUtil for T {


libstd/io.rs:1840:8-1840:8 -fn- definition:
        fn fsync_FILE(stream: &*libc::FILE, level: Level) -> int {
            fsync_fd(fileno(*stream), level)
references:-
1832:             fsync_fn: fsync_FILE,


libstd/io.rs:1247:8-1247:8 -ty- definition:
        type IoSize = size_t;
        #[cfg(unix)]
references:-
1256:                     let nout = libc::write(*self, vb, len as IoSize);


libstd/io.rs:1726:1-1726:1 -fn- definition:

pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] {
references:-
1735:     str::from_utf8(with_bytes_writer(f))
libstd/to_bytes.rs:
363:         do io::with_bytes_writer |wr| {


libstd/io.rs:73:65-73:65 -ty- definition:
#[allow(non_camel_case_types)] // not sure what to do about this
pub type fd_t = c_int;
references:-
1289:     pub fn new(fd: fd_t) -> FdRes {
1304: pub fn fd_writer(fd: fd_t, cleanup: bool) -> @Writer {
1237: impl Writer for fd_t {
1847:                        blk: &fn(v: Res<fd_t>)) {
1285:     fd: fd_t,


libstd/io.rs:115:3-115:3 -trait- definition:
*/
pub trait Reader {
references:-
999: impl<R:Reader,C> Reader for Wrapper<R, C> {
1058:         @rustrt::rust_get_stdin() as @Reader
1062: pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
1133:     } as @Reader)
1125: pub fn with_bytes_reader<T>(bytes: &[u8], f: &fn(@Reader) -> T) -> T {
1136: pub fn with_str_reader<T>(s: &str, f: &fn(@Reader) -> T) -> T {
999: impl<R:Reader,C> Reader for Wrapper<R, C> {
935: impl Reader for *libc::FILE {
190: impl Reader for @Reader {
190: impl Reader for @Reader {
1033:         @Wrapper { base: f, cleanup: FILERes::new(f) } as @Reader
1089: impl Reader for BytesReader {
1035:         @f as @Reader
653:         fn chars_from_utf8<T:Reader>(bytes: &~[u8], chars: &mut ~[char])
620: impl<T:Reader> ReaderUtil for T {
1031: pub fn FILE_reader(f: *libc::FILE, cleanup: bool) -> @Reader {
1054: pub fn stdin() -> @Reader {


libstd/io.rs:1379:1-1379:1 -fn- definition:

pub fn u64_to_be_bytes<T>(n: u64, size: uint,
references:-
1555:         u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
1543:         u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v))
1558:         u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
1564:         u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
1549:         u64_to_be_bytes(n, 8u, |v| self.write(v))
1546:         u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v))
1561:         u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
1552:         u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
libstd/rt/io/extensions.rs:
548:         u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v))
556:         u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
544:         u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v))
564:         u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
572:         u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
560:         u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
568:         u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
552:         u64_to_be_bytes(n, 8u, |v| self.write(v))


libstd/io.rs:1763:30-1763:30 -fn- definition:
// abstractions is pointless.
pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
references:-
1753:     do read_whole_file(file).and_then |bytes| {


libstd/io.rs:1312:1-1312:1 -fn- definition:

pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
references:-
1611:     mk_file_writer(path, flags).and_then(|w| Ok(w))


libstd/io.rs:1866:4-1866:4 -trait- definition:
    pub trait FSyncable { fn fsync(&self, l: Level) -> int; }

references:-
1870:                     blk: &fn(v: Res<@FSyncable>)) {
1869:     pub fn obj_sync(o: @FSyncable, opt_level: Option<Level>,
1878:     fn obj_fsync_fn(o: &@FSyncable, level: Level) -> int {


libstd/io.rs:1855:4-1855:4 -fn- definition:
    fn fsync_fd(fd: libc::c_int, level: Level) -> int {
        #[fixed_stack_segment]; #[inline(never)];
references:-
1841:             fsync_fd(fileno(*stream), level)
1862:         fsync_fd(*fd_ptr, level)


libstd/io.rs:1878:4-1878:4 -fn- definition:
    fn obj_fsync_fn(o: &@FSyncable, level: Level) -> int {
        (*o).fsync(level)
references:-
1874:             fsync_fn: obj_fsync_fn,


libstd/io.rs:1141:11-1141:11 -enum- definition:
// Writing
pub enum FileFlag { Append, Create, Truncate, NoFlag, }
references:-
1313: pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
1610: pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {


libstd/io.rs:1675:1-1675:1 -struct- definition:

pub struct BytesWriter {
references:-
1730:     let @BytesWriter { bytes, _ } = wr;
1682:     pub fn new() -> BytesWriter {
1690: impl Writer for BytesWriter {
1681: impl BytesWriter {
1683:         BytesWriter {


libstd/io.rs:1124:1-1124:1 -fn- definition:

pub fn with_bytes_reader<T>(bytes: &[u8], f: &fn(@Reader) -> T) -> T {
references:-
1138:     with_bytes_reader(s.as_bytes(), f)


libstd/io.rs:105:3-105:3 -enum- definition:
*/
pub enum SeekStyle { SeekSet, SeekEnd, SeekCur, }
references:-
1115:     fn seek(&self, offset: int, whence: SeekStyle) {
1158:     fn seek(&self, int, SeekStyle);
973:     fn seek(&self, offset: int, whence: SeekStyle) {
1739: pub fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
1172:     fn seek(&self, a: int, b: SeekStyle) { self.seek(a, b) }
1180:     fn seek(&self, off: int, style: SeekStyle) { self.base.seek(off, style); }
1203:     fn seek(&self, offset: int, whence: SeekStyle) {
1266:     fn seek(&self, _offset: int, _whence: SeekStyle) {
1005:     fn seek(&self, off: int, whence: SeekStyle) {
176:     fn seek(&self, position: int, style: SeekStyle);
927: fn convert_whence(whence: SeekStyle) -> i32 {
1708:     fn seek(&self, offset: int, whence: SeekStyle) {
200:     fn seek(&self, position: int, style: SeekStyle) {


libstd/io.rs:919:1-919:1 -fn- definition:

fn extend_sign(val: u64, nbytes: uint) -> i64 {
references:-
820:         extend_sign(self.read_be_uint_n(nbytes), nbytes)
804:         extend_sign(self.read_le_uint_n(nbytes), nbytes)