about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2012-02-29 10:48:57 -0800
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2012-03-02 19:15:34 -0800
commit1404a864a4f70a5865f2daac7e285c5dbc448e89 (patch)
tree0199f3bc4bc875a8ebf5ae5e283dc4daa2633f95 /src/libstd
parent5812bebf87c536e4106c68802ee1571bbb49fa18 (diff)
downloadrust-1404a864a4f70a5865f2daac7e285c5dbc448e89.tar.gz
rust-1404a864a4f70a5865f2daac7e285c5dbc448e89.zip
std: add a io::with_str_reader fn to remove a str copy
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/io.rs31
-rw-r--r--src/libstd/json.rs2
2 files changed, 25 insertions, 8 deletions
diff --git a/src/libstd/io.rs b/src/libstd/io.rs
index 133a2e83b57..290d791f711 100644
--- a/src/libstd/io.rs
+++ b/src/libstd/io.rs
@@ -227,11 +227,11 @@ fn file_reader(path: str) -> result::t<reader, str> {
 // Byte buffer readers
 
 // TODO: const u8, but this fails with rustboot.
-type byte_buf = {buf: [u8], mutable pos: uint};
+type byte_buf = {buf: [u8], mutable pos: uint, len: uint};
 
 impl of reader for byte_buf {
     fn read_bytes(len: uint) -> [u8] {
-        let rest = vec::len(self.buf) - self.pos;
+        let rest = self.len - self.pos;
         let to_read = len;
         if rest < to_read { to_read = rest; }
         let range = vec::slice(self.buf, self.pos, self.pos + to_read);
@@ -239,29 +239,46 @@ impl of reader for byte_buf {
         ret range;
     }
     fn read_byte() -> int {
-        if self.pos == vec::len(self.buf) { ret -1; }
+        if self.pos == self.len { ret -1; }
         let b = self.buf[self.pos];
         self.pos += 1u;
         ret b as int;
     }
     fn unread_byte(_byte: int) { #error("TODO: unread_byte"); fail; }
-    fn eof() -> bool { self.pos == vec::len(self.buf) }
+    fn eof() -> bool { self.pos == self.len }
     fn seek(offset: int, whence: seek_style) {
         let pos = self.pos;
-        let len = vec::len(self.buf);
-        self.pos = seek_in_buf(offset, pos, len, whence);
+        self.pos = seek_in_buf(offset, pos, self.len, whence);
     }
     fn tell() -> uint { self.pos }
 }
 
 fn bytes_reader(bytes: [u8]) -> reader {
-    {buf: bytes, mutable pos: 0u} as reader
+    bytes_reader_between(bytes, 0u, vec::len(bytes))
+}
+
+fn bytes_reader_between(bytes: [u8], start: uint, end: uint) -> reader {
+    {buf: bytes, mutable pos: start, len: end} as reader
+}
+
+fn with_bytes_reader<t>(bytes: [u8], f: fn(reader) -> t) -> t {
+    f(bytes_reader(bytes))
+}
+
+fn with_bytes_reader_between<t>(bytes: [u8], start: uint, end: uint,
+                                f: fn(reader) -> t) -> t {
+    f(bytes_reader_between(bytes, start, end))
 }
 
 fn string_reader(s: str) -> reader {
     bytes_reader(str::bytes(s))
 }
 
+fn with_str_reader<T>(s: str, f: fn(reader) -> T) -> T {
+    str::as_bytes(s) { |bytes|
+        with_bytes_reader_between(bytes, 0u, str::len(s), f)
+    }
+}
 
 // Writing
 enum fileflag { append, create, truncate, no_flag, }
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index d069c36e866..8bb6fb2fb9d 100644
--- a/src/libstd/json.rs
+++ b/src/libstd/json.rs
@@ -490,7 +490,7 @@ Function: from_str
 Deserializes a json value from a string.
 */
 fn from_str(s: str) -> result::t<json, error> {
-    from_reader(io::string_reader(s))
+    io::with_str_reader(s, from_reader)
 }
 
 /*