diff options
| author | Marijn Haverbeke <[email protected]> | 2011-05-06 22:13:13 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <[email protected]> | 2011-05-06 22:51:19 +0200 |
| commit | a3ec0b1f643d00b9418e4884bd7caa07bf052201 (patch) | |
| tree | 82000510ac9c9cf3f0c7cf4ae5f3c6b123b559cb /src/lib/io.rs | |
| parent | Register new snapshots. (diff) | |
| download | rust-a3ec0b1f643d00b9418e4884bd7caa07bf052201.tar.xz rust-a3ec0b1f643d00b9418e4884bd7caa07bf052201.zip | |
Rename std modules to be camelcased
(Have fun mergining your stuff with this.)
Diffstat (limited to 'src/lib/io.rs')
| -rw-r--r-- | src/lib/io.rs | 531 |
1 files changed, 0 insertions, 531 deletions
diff --git a/src/lib/io.rs b/src/lib/io.rs deleted file mode 100644 index 364810ba..00000000 --- a/src/lib/io.rs +++ /dev/null @@ -1,531 +0,0 @@ -import os.libc; - -native "rust" mod rustrt { - fn rust_get_stdin() -> os.libc.FILE; - fn rust_get_stdout() -> os.libc.FILE; -} - -// Reading - -// FIXME This is all buffered. We might need an unbuffered variant as well - -tag seek_style {seek_set; seek_end; seek_cur;} - -// The raw underlying reader class. All readers must implement this. -type buf_reader = - state obj { - fn read(uint len) -> vec[u8]; - fn read_byte() -> int; - fn unread_byte(int byte); - fn eof() -> bool; - - // FIXME: Seekable really should be orthogonal. We will need - // inheritance. - fn seek(int offset, seek_style whence); - fn tell() -> uint; - }; - -// Convenience methods for reading. -type reader = - state obj { - // FIXME: This should inherit from buf_reader. - fn get_buf_reader() -> buf_reader; - - fn read_byte() -> int; - fn unread_byte(int byte); - fn read_bytes(uint len) -> vec[u8]; - fn read_char() -> char; - fn eof() -> bool; - fn read_line() -> str; - fn read_c_str() -> str; - fn read_le_uint(uint size) -> uint; - fn read_le_int(uint size) -> int; - fn read_be_uint(uint size) -> uint; - fn read_whole_stream() -> vec[u8]; - - fn seek(int offset, seek_style whence); - fn tell() -> uint; // FIXME: eventually u64 - }; - -fn convert_whence(seek_style whence) -> int { - alt (whence) { - case (seek_set) {ret 0;} - case (seek_cur) {ret 1;} - case (seek_end) {ret 2;} - } -} - -state obj FILE_buf_reader(os.libc.FILE f, bool must_close) { - fn read(uint len) -> vec[u8] { - auto buf = _vec.alloc[u8](len); - auto read = os.libc.fread(_vec.buf[u8](buf), 1u, len, f); - _vec.len_set[u8](buf, read); - ret buf; - } - fn read_byte() -> int { - ret os.libc.fgetc(f); - } - fn unread_byte(int byte) { - os.libc.ungetc(byte, f); - } - fn eof() -> bool { - ret os.libc.feof(f) != 0; - } - fn seek(int offset, seek_style whence) { - assert (os.libc.fseek(f, offset, convert_whence(whence)) == 0); - } - fn tell() -> uint { - ret os.libc.ftell(f) as uint; - } - drop { - if (must_close) { os.libc.fclose(f); } - } -} - -// FIXME: Convert this into pseudomethods on buf_reader. -state obj new_reader(buf_reader rdr) { - fn get_buf_reader() -> buf_reader { - ret rdr; - } - fn read_byte() -> int { - ret rdr.read_byte(); - } - fn unread_byte(int byte) { - ret rdr.unread_byte(byte); - } - fn read_bytes(uint len) -> vec[u8] { - ret rdr.read(len); - } - fn read_char() -> char { - auto c0 = rdr.read_byte(); - if (c0 == -1) {ret -1 as char;} // FIXME will this stay valid? - auto b0 = c0 as u8; - auto w = _str.utf8_char_width(b0); - assert (w > 0u); - if (w == 1u) {ret b0 as char;} - auto val = 0u; - while (w > 1u) { - w -= 1u; - auto next = rdr.read_byte(); - assert (next > -1); - assert (next & 0xc0 == 0x80); - val <<= 6u; - val += (next & 0x3f) as uint; - } - // See _str.char_at - val += ((b0 << ((w + 1u) as u8)) as uint) << ((w - 1u) * 6u - w - 1u); - ret val as char; - } - fn eof() -> bool { - ret rdr.eof(); - } - fn read_line() -> str { - let vec[u8] buf = vec(); - // No break yet in rustc - auto go_on = true; - while (go_on) { - auto ch = rdr.read_byte(); - if (ch == -1 || ch == 10) {go_on = false;} - else {_vec.push[u8](buf, ch as u8);} - } - ret _str.unsafe_from_bytes(buf); - } - fn read_c_str() -> str { - let vec[u8] buf = vec(); - auto go_on = true; - while (go_on) { - auto ch = rdr.read_byte(); - if (ch < 1) {go_on = false;} - else {_vec.push[u8](buf, ch as u8);} - } - ret _str.unsafe_from_bytes(buf); - } - // FIXME deal with eof? - fn read_le_uint(uint size) -> uint { - auto val = 0u; - auto pos = 0u; - while (size > 0u) { - val += (rdr.read_byte() as uint) << pos; - pos += 8u; - size -= 1u; - } - ret val; - } - fn read_le_int(uint size) -> int { - auto val = 0u; - auto pos = 0u; - while (size > 0u) { - val += (rdr.read_byte() as uint) << pos; - pos += 8u; - size -= 1u; - } - ret val as int; - } - // FIXME deal with eof? - fn read_be_uint(uint size) -> uint { - auto val = 0u; - auto sz = size; // FIXME: trans.ml bug workaround - while (sz > 0u) { - sz -= 1u; - val += (rdr.read_byte() as uint) << (sz * 8u); - } - ret val; - } - fn read_whole_stream() -> vec[u8] { - let vec[u8] buf = vec(); - while (!rdr.eof()) { - buf += rdr.read(2048u); - } - ret buf; - } - fn seek(int offset, seek_style whence) { - ret rdr.seek(offset, whence); - } - fn tell() -> uint { - ret rdr.tell(); - } -} - -fn stdin() -> reader { - ret new_reader(FILE_buf_reader(rustrt.rust_get_stdin(), false)); -} - -fn file_reader(str path) -> reader { - auto f = os.libc.fopen(_str.buf(path), _str.buf("r")); - if (f as uint == 0u) { - log_err "error opening " + path; - fail; - } - ret new_reader(FILE_buf_reader(f, true)); -} - -// FIXME: Remove me once objects are exported. -fn new_reader_(buf_reader bufr) -> reader { - ret new_reader(bufr); -} - - -// Byte buffer readers - -// TODO: mutable? u8, but this fails with rustboot. -type byte_buf = @rec(vec[u8] buf, mutable uint pos); - -state obj byte_buf_reader(byte_buf bbuf) { - fn read(uint len) -> vec[u8] { - auto rest = _vec.len[u8](bbuf.buf) - bbuf.pos; - auto to_read = len; - if (rest < to_read) { - to_read = rest; - } - auto range = _vec.slice[u8](bbuf.buf, bbuf.pos, bbuf.pos + to_read); - bbuf.pos += to_read; - ret range; - } - fn read_byte() -> int { - if (bbuf.pos == _vec.len[u8](bbuf.buf)) {ret -1;} - auto b = bbuf.buf.(bbuf.pos); - bbuf.pos += 1u; - ret b as int; - } - - fn unread_byte(int byte) { - log_err "TODO: unread_byte"; - fail; - } - - fn eof() -> bool { - ret bbuf.pos == _vec.len[u8](bbuf.buf); - } - - fn seek(int offset, seek_style whence) { - auto pos = bbuf.pos; - auto len = _vec.len[u8](bbuf.buf); - bbuf.pos = seek_in_buf(offset, pos, len, whence); - } - - fn tell() -> uint { ret bbuf.pos; } -} - -fn new_byte_buf_reader(vec[u8] buf) -> byte_buf_reader { - ret byte_buf_reader(@rec(buf=buf, mutable pos=0u)); -} - - -// Writing - -tag fileflag { - append; - create; - truncate; - none; -} - -type buf_writer = state obj { - fn write(vec[u8] v); - - // FIXME: Seekable really should be orthogonal. We will need inheritance. - fn seek(int offset, seek_style whence); - fn tell() -> uint; // FIXME: eventually u64 -}; - -state obj FILE_writer(os.libc.FILE f, bool must_close) { - fn write(vec[u8] v) { - auto len = _vec.len[u8](v); - auto vbuf = _vec.buf[u8](v); - auto nout = os.libc.fwrite(vbuf, len, 1u, f); - if (nout < 1u) { - log_err "error dumping buffer"; - } - } - - fn seek(int offset, seek_style whence) { - assert (os.libc.fseek(f, offset, convert_whence(whence)) == 0); - } - - fn tell() -> uint { - ret os.libc.ftell(f) as uint; - } - - drop { - if (must_close) {os.libc.fclose(f);} - } -} - -state obj fd_buf_writer(int fd, bool must_close) { - fn write(vec[u8] v) { - auto len = _vec.len[u8](v); - auto count = 0u; - auto vbuf; - while (count < len) { - vbuf = _vec.buf_off[u8](v, count); - auto nout = os.libc.write(fd, vbuf, len); - if (nout < 0) { - log_err "error dumping buffer"; - log_err sys.rustrt.last_os_error(); - fail; - } - count += nout as uint; - } - } - - fn seek(int offset, seek_style whence) { - log_err "need 64-bit native calls for seek, sorry"; - fail; - } - - fn tell() -> uint { - log_err "need 64-bit native calls for tell, sorry"; - fail; - } - - drop { - if (must_close) {os.libc.close(fd);} - } -} - -fn file_buf_writer(str path, vec[fileflag] flags) -> buf_writer { - let int fflags = - os.libc_constants.O_WRONLY() | - os.libc_constants.O_BINARY(); - - for (fileflag f in flags) { - alt (f) { - case (append) { fflags |= os.libc_constants.O_APPEND(); } - case (create) { fflags |= os.libc_constants.O_CREAT(); } - case (truncate) { fflags |= os.libc_constants.O_TRUNC(); } - case (none) {} - } - } - - auto fd = os.libc.open(_str.buf(path), - fflags, - os.libc_constants.S_IRUSR() | - os.libc_constants.S_IWUSR()); - - if (fd < 0) { - log_err "error opening file for writing"; - log_err sys.rustrt.last_os_error(); - fail; - } - ret fd_buf_writer(fd, true); -} - -type writer = - state obj { - fn get_buf_writer() -> buf_writer; - // write_str will continue to do utf-8 output only. an alternative - // function will be provided for general encoded string output - fn write_str(str s); - fn write_char(char ch); - fn write_int(int n); - fn write_uint(uint n); - fn write_bytes(vec[u8] bytes); - fn write_le_uint(uint n, uint size); - fn write_le_int(int n, uint size); - fn write_be_uint(uint n, uint size); - }; - -fn uint_to_le_bytes(uint n, uint size) -> vec[u8] { - let vec[u8] bytes = vec(); - while (size > 0u) { - bytes += vec((n & 255u) as u8); - n >>= 8u; - size -= 1u; - } - ret bytes; -} - -fn uint_to_be_bytes(uint n, uint size) -> vec[u8] { - let vec[u8] bytes = vec(); - auto i = (size - 1u) as int; - while (i >= 0) { - bytes += vec(((n >> ((i * 8) as uint)) & 255u) as u8); - i -= 1; - } - ret bytes; -} - -state obj new_writer(buf_writer out) { - fn get_buf_writer() -> buf_writer { - ret out; - } - fn write_str(str s) { - out.write(_str.bytes(s)); - } - fn write_char(char ch) { - // FIXME needlessly consy - out.write(_str.bytes(_str.from_char(ch))); - } - fn write_int(int n) { - out.write(_str.bytes(_int.to_str(n, 10u))); - } - fn write_uint(uint n) { - out.write(_str.bytes(_uint.to_str(n, 10u))); - } - fn write_bytes(vec[u8] bytes) { - out.write(bytes); - } - fn write_le_uint(uint n, uint size) { - out.write(uint_to_le_bytes(n, size)); - } - fn write_le_int(int n, uint size) { - out.write(uint_to_le_bytes(n as uint, size)); - } - fn write_be_uint(uint n, uint size) { - out.write(uint_to_be_bytes(n, size)); - } -} - -// FIXME: Remove me once objects are exported. -fn new_writer_(buf_writer out) -> writer { - ret new_writer(out); -} - -fn file_writer(str path, vec[fileflag] flags) -> writer { - ret new_writer(file_buf_writer(path, flags)); -} - -// FIXME: fileflags -fn buffered_file_buf_writer(str path) -> buf_writer { - auto f = os.libc.fopen(_str.buf(path), _str.buf("w")); - if (f as uint == 0u) { - log_err "error opening " + path; - fail; - } - ret FILE_writer(f, true); -} - -// FIXME it would be great if this could be a const -fn stdout() -> writer { - ret new_writer(fd_buf_writer(1, false)); -} - -type str_writer = - state obj { - fn get_writer() -> writer; - fn get_str() -> str; - }; - -type mutable_byte_buf = @rec(mutable vec[mutable u8] buf, mutable uint pos); - -state obj byte_buf_writer(mutable_byte_buf buf) { - fn write(vec[u8] v) { - // Fast path. - if (buf.pos == _vec.len(buf.buf)) { - // FIXME: Fix our type system. There's no reason you shouldn't be - // able to add a mutable vector to an immutable one. - auto mv = _vec.rustrt.unsafe_vec_to_mut[u8](v); - buf.buf += mv; - buf.pos += _vec.len[u8](v); - ret; - } - - // FIXME: Optimize. These should be unique pointers. - auto vlen = _vec.len[u8](v); - auto vpos = 0u; - while (vpos < vlen) { - auto b = v.(vpos); - if (buf.pos == _vec.len(buf.buf)) { - buf.buf += vec(mutable b); - } else { - buf.buf.(buf.pos) = b; - } - buf.pos += 1u; - vpos += 1u; - } - } - - fn seek(int offset, seek_style whence) { - auto pos = buf.pos; - auto len = _vec.len(buf.buf); - buf.pos = seek_in_buf(offset, pos, len, whence); - } - - fn tell() -> uint { ret buf.pos; } -} - -fn string_writer() -> str_writer { - // FIXME: yikes, this is bad. Needs fixing of mutable syntax. - let vec[mutable u8] b = vec(mutable 0u8); - _vec.pop(b); - - let mutable_byte_buf buf = @rec(mutable buf = b, mutable pos = 0u); - state obj str_writer_wrap(writer wr, mutable_byte_buf buf) { - fn get_writer() -> writer {ret wr;} - fn get_str() -> str {ret _str.unsafe_from_mutable_bytes(buf.buf);} - } - ret str_writer_wrap(new_writer(byte_buf_writer(buf)), buf); -} - - -// Utility functions - -fn seek_in_buf(int offset, uint pos, uint len, seek_style whence) -> uint { - auto bpos = pos as int; - auto blen = len as int; - alt (whence) { - case (seek_set) { bpos = offset; } - case (seek_cur) { bpos += offset; } - case (seek_end) { bpos = blen + offset; } - } - - if (bpos < 0) { - bpos = 0; - } else if (bpos > blen) { - bpos = blen; - } - - ret bpos as uint; -} - - -// -// Local Variables: -// mode: rust -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; -// End: -// |