aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/_str.rs13
-rw-r--r--src/lib/io.rs99
-rw-r--r--src/lib/linux_os.rs1
-rw-r--r--src/lib/macos_os.rs1
-rw-r--r--src/lib/win32_os.rs1
5 files changed, 101 insertions, 14 deletions
diff --git a/src/lib/_str.rs b/src/lib/_str.rs
index e73fd115..87eef514 100644
--- a/src/lib/_str.rs
+++ b/src/lib/_str.rs
@@ -7,7 +7,7 @@ native "rust" mod rustrt {
fn str_buf(str s) -> sbuf;
fn str_byte_len(str s) -> uint;
fn str_alloc(uint n_bytes) -> str;
- fn str_from_vec(vec[u8] b) -> str;
+ fn str_from_vec(vec[mutable? u8] b) -> str;
fn str_from_cstr(sbuf cstr) -> str;
fn str_from_buf(sbuf buf, uint len) -> str;
fn refcount[T](str s) -> uint;
@@ -109,7 +109,16 @@ fn from_bytes(vec[u8] v) : is_utf8(v) -> str {
}
// FIXME temp thing
-fn unsafe_from_bytes(vec[u8] v) -> str {
+fn unsafe_from_bytes(vec[mutable? u8] v) -> str {
+ ret rustrt.str_from_vec(v);
+}
+
+// FIXME even temp-er thing; rustc can use "unsafe_from_bytes" above
+fn unsafe_from_mutable_bytes(vec[mutable u8] mv) -> str {
+ let vec[u8] v = vec();
+ for (mutable u8 b in mv) {
+ v += vec(b);
+ }
ret rustrt.str_from_vec(v);
}
diff --git a/src/lib/io.rs b/src/lib/io.rs
index 165fe030..23a503ab 100644
--- a/src/lib/io.rs
+++ b/src/lib/io.rs
@@ -27,6 +27,14 @@ type reader =
impure fn tell() -> uint; // TODO: 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_reader(os.libc.FILE f, bool must_close) {
impure fn read_byte() -> u8 {
ret os.libc.fgetc(f) as u8;
@@ -90,13 +98,7 @@ state obj FILE_reader(os.libc.FILE f, bool must_close) {
ret val as int; // TODO does that work?
}
impure fn seek(int offset, seek_style whence) {
- auto wh;
- alt (whence) {
- case (seek_set) {wh = 0;}
- case (seek_cur) {wh = 1;}
- case (seek_end) {wh = 2;}
- }
- check(os.libc.fseek(f, offset, wh) == 0);
+ check(os.libc.fseek(f, offset, convert_whence(whence)) == 0);
}
impure fn tell() -> uint {
ret os.libc.ftell(f) as uint;
@@ -132,8 +134,34 @@ tag fileflag {
type buf_writer = state obj {
fn write(vec[u8] v);
+
+ fn seek(int offset, seek_style whence);
+ fn tell() -> uint; // TODO: 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 "error dumping buffer";
+ }
+ }
+
+ fn seek(int offset, seek_style whence) {
+ check(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);
@@ -151,6 +179,16 @@ state obj fd_buf_writer(int fd, bool must_close) {
}
}
+ fn seek(int offset, seek_style whence) {
+ log "need 64-bit native calls for seek, sorry";
+ fail;
+ }
+
+ fn tell() -> uint {
+ log "need 64-bit native calls for tell, sorry";
+ fail;
+ }
+
drop {
if (must_close) {os.libc.close(fd);}
}
@@ -239,19 +277,56 @@ type str_writer =
fn get_str() -> str;
};
-type byte_buf = @rec(mutable vec[u8] buf);
+type byte_buf = @rec(mutable vec[mutable u8] buf, mutable uint pos);
state obj byte_buf_writer(byte_buf buf) {
- fn write(vec[u8] v) {buf.buf += v;}
+ fn write(vec[u8] v) {
+ // TODO: optimize
+ auto vlen = _vec.len[u8](v);
+ auto vpos = 0u;
+ while (vpos < vlen) {
+ auto b = v.(vpos);
+ if (buf.pos == _vec.len[mutable u8](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 as int;
+ auto len = _vec.len[mutable u8](buf.buf) as int;
+ alt (whence) {
+ case (seek_set) { pos = offset; }
+ case (seek_cur) { pos += offset; }
+ case (seek_end) { pos = len + offset; }
+ }
+
+ if (pos < 0) {
+ pos = 0;
+ } else if (pos > len) {
+ pos = len;
+ }
+
+ buf.pos = pos as uint;
+ }
+
+ fn tell() -> uint { ret buf.pos; }
}
// TODO awkward! it's not possible to implement a writer with an extra method
fn string_writer() -> str_writer {
- let vec[u8] b = vec();
- let byte_buf buf = @rec(mutable buf = b);
+ // FIXME: yikes, this is bad. Needs fixing of mutable syntax.
+ let vec[mutable u8] b = vec(mutable 0u8);
+ _vec.pop[mutable u8](b);
+
+ let byte_buf buf = @rec(mutable buf = b, mutable pos = 0u);
state obj str_writer_wrap(writer wr, byte_buf buf) {
fn get_writer() -> writer {ret wr;}
- fn get_str() -> str {ret _str.unsafe_from_bytes(buf.buf);}
+ fn get_str() -> str {ret _str.unsafe_from_mutable_bytes(buf.buf);}
}
ret str_writer_wrap(new_writer(byte_buf_writer(buf)), buf);
}
diff --git a/src/lib/linux_os.rs b/src/lib/linux_os.rs
index bce85956..51f2943d 100644
--- a/src/lib/linux_os.rs
+++ b/src/lib/linux_os.rs
@@ -18,6 +18,7 @@ native mod libc = "libc.so.6" {
fn fgetc(FILE f) -> int;
fn ungetc(int c, FILE f);
fn fread(vbuf buf, uint size, uint n, FILE f) -> uint;
+ fn fwrite(vbuf buf, uint size, uint n, FILE f) -> uint;
fn fseek(FILE f, int offset, int whence) -> int;
fn ftell(FILE f) -> int;
diff --git a/src/lib/macos_os.rs b/src/lib/macos_os.rs
index f9734de3..9633c14c 100644
--- a/src/lib/macos_os.rs
+++ b/src/lib/macos_os.rs
@@ -15,6 +15,7 @@ native mod libc = "libc.dylib" {
fn fgetc(FILE f) -> int;
fn ungetc(int c, FILE f);
fn fread(vbuf buf, uint size, uint n, FILE f) -> uint;
+ fn fwrite(vbuf buf, uint size, uint n, FILE f) -> uint;
fn fseek(FILE f, int offset, int whence) -> int;
fn ftell(FILE f) -> int;
diff --git a/src/lib/win32_os.rs b/src/lib/win32_os.rs
index 3ca76e77..7f113b27 100644
--- a/src/lib/win32_os.rs
+++ b/src/lib/win32_os.rs
@@ -14,6 +14,7 @@ native mod libc = "msvcrt.dll" {
fn fgetc(FILE f) -> int;
fn ungetc(int c, FILE f);
fn fread(vbuf buf, uint size, uint n, FILE f) -> uint;
+ fn fwrite(vbuf buf, uint size, uint n, FILE f) -> uint;
fn fseek(FILE f, int offset, int whence) -> int;
fn ftell(FILE f) -> int;