Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

copyless io::BytesWriter and rewriting str::raw::from_buf_len_nocopy #3518

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/fuzzer/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,8 @@ fn under(n: uint, it: fn(uint)) {
while i < n { it(i); i += 1u; }
}

fn devnull() -> io::Writer { io::mem_buffer_writer(io::mem_buffer()) }

fn as_str(f: fn@(io::Writer)) -> ~str {
let buf = io::mem_buffer();
f(io::mem_buffer_writer(buf));
io::mem_buffer_str(buf)
io::with_str_writer(f)
}

fn check_variants_of_ast(crate: ast::crate, codemap: codemap::codemap,
Expand Down
60 changes: 30 additions & 30 deletions src/libcore/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -670,9 +670,12 @@ fn stderr() -> Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
fn print(s: &str) { stdout().write_str(s); }
fn println(s: &str) { stdout().write_line(s); }

type MemBuffer = @{buf: DVec<u8>, mut pos: uint};
struct BytesWriter {
buf: DVec<u8>,
mut pos: uint,
}

impl MemBuffer: Writer {
impl @BytesWriter: Writer {
fn write(v: &[const u8]) {
do self.buf.swap |buf| {
let mut buf <- buf;
Expand Down Expand Up @@ -701,27 +704,24 @@ impl MemBuffer: Writer {
fn get_type() -> WriterType { File }
}

fn mem_buffer() -> MemBuffer {
@{buf: DVec(), mut pos: 0u}
fn BytesWriter() -> @BytesWriter {
@BytesWriter { buf: DVec(), mut pos: 0u }
}
fn mem_buffer_writer(b: MemBuffer) -> Writer { b as Writer }
fn mem_buffer_buf(b: MemBuffer) -> ~[u8] { b.buf.get() }
fn mem_buffer_str(b: MemBuffer) -> ~str {
str::from_bytes(b.buf.get())

fn with_bytes_writer(f: fn(Writer)) -> ~[u8] {
let wr = BytesWriter();
f(wr as Writer);
wr.buf.check_out(|buf| buf)
}

fn with_str_writer(f: fn(Writer)) -> ~str {
let buf = mem_buffer();
let wr = mem_buffer_writer(buf);
f(wr);
io::mem_buffer_str(buf)
}
let mut v = with_bytes_writer(f);

// Make sure the vector has a trailing null and is proper utf8.
vec::push(v, 0);
assert str::is_utf8(v);

fn with_buf_writer(f: fn(Writer)) -> ~[u8] {
let buf = mem_buffer();
let wr = mem_buffer_writer(buf);
f(wr);
io::mem_buffer_buf(buf)
unsafe { move ::unsafe::transmute(v) }
}

// Utility functions
Expand Down Expand Up @@ -946,18 +946,18 @@ mod tests {
}

#[test]
fn mem_buffer_overwrite() {
let mbuf = mem_buffer();
mbuf.write(~[0u8, 1u8, 2u8, 3u8]);
assert mem_buffer_buf(mbuf) == ~[0u8, 1u8, 2u8, 3u8];
mbuf.seek(-2, SeekCur);
mbuf.write(~[4u8, 5u8, 6u8, 7u8]);
assert mem_buffer_buf(mbuf) == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8];
mbuf.seek(-2, SeekEnd);
mbuf.write(~[8u8]);
mbuf.seek(1, SeekSet);
mbuf.write(~[9u8]);
assert mem_buffer_buf(mbuf) == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8];
fn bytes_buffer_overwrite() {
let wr = BytesWriter();
wr.write(~[0u8, 1u8, 2u8, 3u8]);
assert wr.buf.borrow(|buf| buf == ~[0u8, 1u8, 2u8, 3u8]);
wr.seek(-2, SeekCur);
wr.write(~[4u8, 5u8, 6u8, 7u8]);
assert wr.buf.borrow(|buf| buf == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]);
wr.seek(-2, SeekEnd);
wr.write(~[8u8]);
wr.seek(1, SeekSet);
wr.write(~[9u8]);
assert wr.buf.borrow(|buf| buf == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]);
}
}

Expand Down
17 changes: 8 additions & 9 deletions src/libcore/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1967,10 +1967,10 @@ mod raw {
export
from_buf,
from_buf_len,
from_buf_len_nocopy,
from_c_str,
from_c_str_len,
from_bytes,
form_slice,
slice_bytes,
view_bytes,
push_byte,
Expand Down Expand Up @@ -2003,14 +2003,6 @@ mod raw {
return ::unsafe::transmute(move v);
}

/// Create a Rust string from a *u8 buffer of the given length
/// without copying
unsafe fn from_buf_len_nocopy(buf: &a / *u8, len: uint) -> &a / str {
let v = (*buf, len + 1);
assert is_utf8(::unsafe::reinterpret_cast(&v));
return ::unsafe::transmute(move v);
}

/// Create a Rust string from a null-terminated C string
unsafe fn from_c_str(c_str: *libc::c_char) -> ~str {
from_buf(::unsafe::reinterpret_cast(&c_str))
Expand All @@ -2031,6 +2023,13 @@ mod raw {
/// Converts a byte to a string.
unsafe fn from_byte(u: u8) -> ~str { raw::from_bytes([u]) }

/// Form a slice from a *u8 buffer of the given length without copying.
unsafe fn buf_as_slice<T>(buf: *u8, len: uint, f: fn(&& &str) -> T) -> T {
let v = (*buf, len + 1);
assert is_utf8(::unsafe::reinterpret_cast(&v));
f(::unsafe::transmute(move v))
}

/**
* Takes a bytewise (not UTF-8) slice from a string.
*
Expand Down
7 changes: 3 additions & 4 deletions src/libcore/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,9 @@ pure fn refcount<T>(+t: @T) -> uint {

pure fn log_str<T>(t: T) -> ~str {
unsafe {
let buffer = io::mem_buffer();
let writer = io::mem_buffer_writer(buffer);
repr::write_repr(writer, &t);
return io::mem_buffer_str(buffer); // XXX: Extra malloc and copy.
do io::with_str_writer |wr| {
repr::write_repr(wr, &t)
}
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/libcore/to_bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,10 +373,10 @@ trait ToBytes {

impl<A: IterBytes> A: ToBytes {
fn to_bytes(lsb0: bool) -> ~[u8] {
let buf = io::mem_buffer();
for self.iter_bytes(lsb0) |bytes| {
buf.write(bytes)
do io::with_bytes_writer |wr| {
for self.iter_bytes(lsb0) |bytes| {
wr.write(bytes)
}
}
io::mem_buffer_buf(buf)
}
}
9 changes: 5 additions & 4 deletions src/libstd/ebml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -631,10 +631,11 @@ fn test_option_int() {

fn test_v(v: Option<int>) {
debug!("v == %?", v);
let mbuf = io::mem_buffer();
let ebml_w = ebml::Writer(io::mem_buffer_writer(mbuf));
serialize_0(ebml_w, v);
let ebml_doc = ebml::Doc(@io::mem_buffer_buf(mbuf));
let bytes = do io::with_bytes_writer |wr| {
let ebml_w = ebml::Writer(wr);
serialize_0(ebml_w, v);
};
let ebml_doc = ebml::Doc(@bytes);
let deser = ebml_deserializer(ebml_doc);
let v1 = deserialize_0(deser);
debug!("v1 == %?", v1);
Expand Down
51 changes: 24 additions & 27 deletions src/libstd/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,36 +233,33 @@ fn print_failures(st: ConsoleTestState) {

#[test]
fn should_sort_failures_before_printing_them() {
let buffer = io::mem_buffer();
let writer = io::mem_buffer_writer(buffer);

let test_a = {
name: ~"a",
testfn: fn~() { },
ignore: false,
should_fail: false
};

let test_b = {
name: ~"b",
testfn: fn~() { },
ignore: false,
should_fail: false
};
let s = do io::with_str_writer |wr| {
let test_a = {
name: ~"a",
testfn: fn~() { },
ignore: false,
should_fail: false
};

let st =
@{out: writer,
log_out: option::None,
use_color: false,
mut total: 0u,
mut passed: 0u,
mut failed: 0u,
mut ignored: 0u,
mut failures: ~[test_b, test_a]};
let test_b = {
name: ~"b",
testfn: fn~() { },
ignore: false,
should_fail: false
};

print_failures(st);
let st =
@{out: wr,
log_out: option::None,
use_color: false,
mut total: 0u,
mut passed: 0u,
mut failed: 0u,
mut ignored: 0u,
mut failures: ~[test_b, test_a]};

let s = io::mem_buffer_str(buffer);
print_failures(st);
};

let apos = option::get(str::find_str(s, ~"a"));
let bpos = option::get(str::find_str(s, ~"b"));
Expand Down
42 changes: 21 additions & 21 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,13 @@ fn path_to_str(&&p: @ast::path, intr: ident_interner) -> ~str {

fn fun_to_str(decl: ast::fn_decl, name: ast::ident,
params: ~[ast::ty_param], intr: ident_interner) -> ~str {
let buffer = io::mem_buffer();
let s = rust_printer(io::mem_buffer_writer(buffer), intr);
print_fn(s, decl, None, name, params, None);
end(s); // Close the head box
end(s); // Close the outer box
eof(s.s);
io::mem_buffer_str(buffer)
do io::with_str_writer |wr| {
let s = rust_printer(wr, intr);
print_fn(s, decl, None, name, params, None);
end(s); // Close the head box
end(s); // Close the outer box
eof(s.s);
}
}

#[test]
Expand All @@ -148,15 +148,15 @@ fn test_fun_to_str() {
}

fn block_to_str(blk: ast::blk, intr: ident_interner) -> ~str {
let buffer = io::mem_buffer();
let s = rust_printer(io::mem_buffer_writer(buffer), intr);
// containing cbox, will be closed by print-block at }
cbox(s, indent_unit);
// head-ibox, will be closed by print-block after {
ibox(s, 0u);
print_block(s, blk);
eof(s.s);
io::mem_buffer_str(buffer)
do io::with_str_writer |wr| {
let s = rust_printer(wr, intr);
// containing cbox, will be closed by print-block at }
cbox(s, indent_unit);
// head-ibox, will be closed by print-block after {
ibox(s, 0u);
print_block(s, blk);
eof(s.s);
}
}

fn meta_item_to_str(mi: @ast::meta_item, intr: ident_interner) -> ~str {
Expand Down Expand Up @@ -2027,11 +2027,11 @@ fn print_string(s: ps, st: ~str) {
}

fn to_str<T>(t: T, f: fn@(ps, T), intr: ident_interner) -> ~str {
let buffer = io::mem_buffer();
let s = rust_printer(io::mem_buffer_writer(buffer), intr);
f(s, t);
eof(s.s);
io::mem_buffer_str(buffer)
do io::with_str_writer |wr| {
let s = rust_printer(wr, intr);
f(s, t);
eof(s.s);
}
}

fn next_comment(s: ps) -> Option<comments::cmnt> {
Expand Down
Loading