Skip to content

Commit 1404a86

Browse files
committed
std: add a io::with_str_reader fn to remove a str copy
1 parent 5812beb commit 1404a86

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

src/libstd/io.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -227,41 +227,58 @@ fn file_reader(path: str) -> result::t<reader, str> {
227227
// Byte buffer readers
228228

229229
// TODO: const u8, but this fails with rustboot.
230-
type byte_buf = {buf: [u8], mutable pos: uint};
230+
type byte_buf = {buf: [u8], mutable pos: uint, len: uint};
231231

232232
impl of reader for byte_buf {
233233
fn read_bytes(len: uint) -> [u8] {
234-
let rest = vec::len(self.buf) - self.pos;
234+
let rest = self.len - self.pos;
235235
let to_read = len;
236236
if rest < to_read { to_read = rest; }
237237
let range = vec::slice(self.buf, self.pos, self.pos + to_read);
238238
self.pos += to_read;
239239
ret range;
240240
}
241241
fn read_byte() -> int {
242-
if self.pos == vec::len(self.buf) { ret -1; }
242+
if self.pos == self.len { ret -1; }
243243
let b = self.buf[self.pos];
244244
self.pos += 1u;
245245
ret b as int;
246246
}
247247
fn unread_byte(_byte: int) { #error("TODO: unread_byte"); fail; }
248-
fn eof() -> bool { self.pos == vec::len(self.buf) }
248+
fn eof() -> bool { self.pos == self.len }
249249
fn seek(offset: int, whence: seek_style) {
250250
let pos = self.pos;
251-
let len = vec::len(self.buf);
252-
self.pos = seek_in_buf(offset, pos, len, whence);
251+
self.pos = seek_in_buf(offset, pos, self.len, whence);
253252
}
254253
fn tell() -> uint { self.pos }
255254
}
256255

257256
fn bytes_reader(bytes: [u8]) -> reader {
258-
{buf: bytes, mutable pos: 0u} as reader
257+
bytes_reader_between(bytes, 0u, vec::len(bytes))
258+
}
259+
260+
fn bytes_reader_between(bytes: [u8], start: uint, end: uint) -> reader {
261+
{buf: bytes, mutable pos: start, len: end} as reader
262+
}
263+
264+
fn with_bytes_reader<t>(bytes: [u8], f: fn(reader) -> t) -> t {
265+
f(bytes_reader(bytes))
266+
}
267+
268+
fn with_bytes_reader_between<t>(bytes: [u8], start: uint, end: uint,
269+
f: fn(reader) -> t) -> t {
270+
f(bytes_reader_between(bytes, start, end))
259271
}
260272

261273
fn string_reader(s: str) -> reader {
262274
bytes_reader(str::bytes(s))
263275
}
264276

277+
fn with_str_reader<T>(s: str, f: fn(reader) -> T) -> T {
278+
str::as_bytes(s) { |bytes|
279+
with_bytes_reader_between(bytes, 0u, str::len(s), f)
280+
}
281+
}
265282

266283
// Writing
267284
enum fileflag { append, create, truncate, no_flag, }

src/libstd/json.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ Function: from_str
490490
Deserializes a json value from a string.
491491
*/
492492
fn from_str(s: str) -> result::t<json, error> {
493-
from_reader(io::string_reader(s))
493+
io::with_str_reader(s, from_reader)
494494
}
495495

496496
/*

0 commit comments

Comments
 (0)