diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs index c4dd4bcf4bc3f..216900d046eb0 100644 --- a/src/fuzzer/fuzzer.rs +++ b/src/fuzzer/fuzzer.rs @@ -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, diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 5fbad9fde95a6..ed87816a01bd1 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -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, mut pos: uint}; +struct BytesWriter { + buf: DVec, + mut pos: uint, +} -impl MemBuffer: Writer { +impl @BytesWriter: Writer { fn write(v: &[const u8]) { do self.buf.swap |buf| { let mut buf <- buf; @@ -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 @@ -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]); } } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 4c77dfe50b1ee..ac052bb4eb1da 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -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, @@ -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)) @@ -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(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. * diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index 1adadc5eba6bb..97fdda57eb182 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -99,10 +99,9 @@ pure fn refcount(+t: @T) -> uint { pure fn log_str(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) + } } } diff --git a/src/libcore/to_bytes.rs b/src/libcore/to_bytes.rs index 3363f5a0a6a5b..680003246239a 100644 --- a/src/libcore/to_bytes.rs +++ b/src/libcore/to_bytes.rs @@ -373,10 +373,10 @@ trait ToBytes { impl 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) } } diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index d6b8c2f4908e2..741d331cf00f3 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -631,10 +631,11 @@ fn test_option_int() { fn test_v(v: Option) { 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); diff --git a/src/libstd/test.rs b/src/libstd/test.rs index a2e7be51de81d..76b6310c85321 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -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")); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index a4e7d12bd21bc..be54ccc04507b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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] @@ -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 { @@ -2027,11 +2027,11 @@ fn print_string(s: ps, st: ~str) { } fn to_str(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 { diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 8994cac35d2fc..6b8a28235de43 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -68,7 +68,6 @@ type stats = { enum encode_ctxt = { diag: span_handler, tcx: ty::ctxt, - buf: io::MemBuffer, stats: stats, reachable: HashMap, reexports: ~[(~str, def_id)], @@ -1089,7 +1088,7 @@ const metadata_encoding_version : &[u8] = &[0x72, //'r' as u8, 0, 0, 0, 1 ]; fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] { - let buf = io::mem_buffer(); + let wr = io::BytesWriter(); let stats = {mut inline_bytes: 0, mut attr_bytes: 0, @@ -1102,7 +1101,6 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] { let ecx: @encode_ctxt = @encode_ctxt({ diag: parms.diag, tcx: parms.tcx, - buf: buf, stats: move stats, reachable: parms.reachable, reexports: parms.reexports, @@ -1115,37 +1113,36 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] { type_abbrevs: ty::new_ty_hash() }); - let buf_w = io::mem_buffer_writer(buf); - let ebml_w = ebml::Writer(buf_w); + let ebml_w = ebml::Writer(wr as io::Writer); encode_hash(ebml_w, ecx.link_meta.extras_hash); - let mut i = buf.pos; + let mut i = wr.pos; let crate_attrs = synthesize_crate_attrs(ecx, crate); encode_attributes(ebml_w, crate_attrs); - ecx.stats.attr_bytes = buf.pos - i; + ecx.stats.attr_bytes = wr.pos - i; - i = buf.pos; + i = wr.pos; encode_crate_deps(ecx, ebml_w, ecx.cstore); - ecx.stats.dep_bytes = buf.pos - i; + ecx.stats.dep_bytes = wr.pos - i; // Encode and index the items. ebml_w.start_tag(tag_items); - i = buf.pos; + i = wr.pos; let items_index = encode_info_for_items(ecx, ebml_w, crate); - ecx.stats.item_bytes = buf.pos - i; + ecx.stats.item_bytes = wr.pos - i; - i = buf.pos; + i = wr.pos; let items_buckets = create_index(items_index, hash_node_id); encode_index(ebml_w, items_buckets, write_int); - ecx.stats.index_bytes = buf.pos - i; + ecx.stats.index_bytes = wr.pos - i; ebml_w.end_tag(); - ecx.stats.total_bytes = buf.pos; + ecx.stats.total_bytes = wr.pos; if (parms.tcx.sess.meta_stats()) { - do buf.buf.borrow |v| { + do wr.buf.borrow |v| { do v.each |e| { if e == 0 { ecx.stats.zero_bytes += 1; @@ -1166,7 +1163,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] { // Pad this, since something (LLVM, presumably) is cutting off the // remaining % 4 bytes. - buf_w.write(&[0u8, 0u8, 0u8, 0u8]); + wr.write(&[0u8, 0u8, 0u8, 0u8]); // FIXME #3396: weird bug here, for reasons unclear this emits random // looking bytes (mostly 0x1) if we use the version byte-array constant @@ -1178,7 +1175,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] { (do str::as_bytes(~"rust\x00\x00\x00\x01") |bytes| { vec::slice(bytes, 0, 8) - }) + flate::deflate_bytes(io::mem_buffer_buf(buf)) + }) + flate::deflate_bytes(wr.buf.check_out(|buf| buf)) } // Get the encoded string for a type @@ -1188,9 +1185,9 @@ fn encoded_ty(tcx: ty::ctxt, t: ty::t) -> ~str { tcx: tcx, reachable: |_id| false, abbrevs: tyencode::ac_no_abbrevs}; - let buf = io::mem_buffer(); - tyencode::enc_ty(io::mem_buffer_writer(buf), cx, t); - return io::mem_buffer_str(buf); + do io::with_str_writer |wr| { + tyencode::enc_ty(wr, cx, t); + } } diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs index 2c8df582a55a2..6dc9810e296c6 100644 --- a/src/rustc/metadata/tyencode.rs +++ b/src/rustc/metadata/tyencode.rs @@ -45,12 +45,13 @@ fn enc_ty(w: io::Writer, cx: @ctxt, t: ty::t) { match cx.abbrevs { ac_no_abbrevs => { let result_str = match cx.tcx.short_names_cache.find(t) { - Some(s) => *s, - None => { - let buf = io::mem_buffer(); - enc_sty(io::mem_buffer_writer(buf), cx, ty::get(t).sty); - cx.tcx.short_names_cache.insert(t, @io::mem_buffer_str(buf)); - io::mem_buffer_str(buf) + Some(s) => *s, + None => { + let s = do io::with_str_writer |wr| { + enc_sty(wr, cx, ty::get(t).sty); + }; + cx.tcx.short_names_cache.insert(t, @s); + s } }; w.write_str(result_str); diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index e7b9cdb5d3576..4678b1cb90a73 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -1012,10 +1012,11 @@ fn mk_ctxt() -> fake_ext_ctxt { #[cfg(test)] fn roundtrip(in_item: @ast::item) { - let mbuf = io::mem_buffer(); - let ebml_w = ebml::Writer(io::mem_buffer_writer(mbuf)); - encode_item_ast(ebml_w, in_item); - let ebml_doc = ebml::Doc(@io::mem_buffer_buf(mbuf)); + let bytes = do io::with_bytes_writer |wr| { + let ebml_w = ebml::Writer(wr); + encode_item_ast(ebml_w, in_item); + }; + let ebml_doc = ebml::Doc(@bytes); let out_item = decode_item_ast(ebml_doc); let exp_str = diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs index afd9054c51f3c..c6d9c15c1a2ff 100644 --- a/src/test/run-pass-fulldeps/qquote.rs +++ b/src/test/run-pass-fulldeps/qquote.rs @@ -85,14 +85,14 @@ fn main() { fn check_pp(cx: fake_ext_ctxt, expr: T, f: fn(pprust::ps, T), expect: ~str) { - let buf = mem_buffer(); - let pp = pprust::rust_printer(buf as io::Writer,cx.parse_sess().interner); - f(pp, expr); - pp::eof(pp.s); - let str = mem_buffer_str(buf); - stdout().write_line(str); + let s = do io::with_str_writer |wr| { + let pp = pprust::rust_printer(wr, cx.parse_sess().interner); + f(pp, expr); + pp::eof(pp.s); + } + stdout().write_line(s); if expect != ~"" { - error!("expect: '%s', got: '%s'", expect, str); + error!("expect: '%s', got: '%s'", expect, s); assert str == expect; } } diff --git a/src/test/run-pass/auto_serialize.rs b/src/test/run-pass/auto_serialize.rs index fcb1adb95cbff..034d906741f7e 100644 --- a/src/test/run-pass/auto_serialize.rs +++ b/src/test/run-pass/auto_serialize.rs @@ -21,10 +21,11 @@ fn test_ser_and_deser(a1: A, assert s == expected; // check the EBML serializer: - let buf = io::mem_buffer(); - let w = ebml::Writer(buf as io::Writer); - ebml_ser_fn(w, a1); - let d = ebml::Doc(@io::mem_buffer_buf(buf)); + let bytes = do io::with_bytes_writer |wr| { + let w = ebml::Writer(wr); + ebml_ser_fn(w, a1); + }; + let d = ebml::Doc(@bytes); let a2 = ebml_deser_fn(ebml::ebml_deserializer(d)); io::print(~"\na1 = "); io_ser_fn(io::stdout(), a1);