Update some str functions to slices, merge as_buf and unpack_slice.

This commit is contained in:
Graydon Hoare 2012-07-24 12:35:34 -07:00
parent ae094a7adc
commit a63e0e47f0
15 changed files with 135 additions and 154 deletions

View File

@ -221,14 +221,13 @@ fn peek_(p: *rust_port) -> bool {
fn select2<A: send, B: send>(p_a: port<A>, p_b: port<B>)
-> either<A, B> {
let ports = ~[(**p_a).po, (**p_b).po];
let n_ports = 2 as libc::size_t;
let yield = 0u, yieldp = ptr::addr_of(yield);
let mut resport: *rust_port;
resport = rusti::init::<*rust_port>();
do vec::as_buf(ports) |ports| {
rustrt::rust_port_select(ptr::addr_of(resport), ports, n_ports,
yieldp);
do vec::as_buf(ports) |ports, n_ports| {
rustrt::rust_port_select(ptr::addr_of(resport), ports,
n_ports as size_t, yieldp);
}
if yield != 0u {

View File

@ -94,7 +94,7 @@ fn from_str(s: ~str) -> option<T> { parse_buf(str::bytes(s), 10u) }
/// Convert to a string in a given base
fn to_str(n: T, radix: uint) -> ~str {
do to_str_bytes(n, radix) |slice| {
do vec::unpack_slice(slice) |p, len| {
do vec::as_buf(slice) |p, len| {
unsafe { str::unsafe::from_buf_len(p, len) }
}
}

View File

@ -205,7 +205,7 @@ fn convert_whence(whence: seek_style) -> i32 {
impl of reader for *libc::FILE {
fn read(buf: &[mut u8], len: uint) -> uint {
do vec::unpack_slice(buf) |buf_p, buf_len| {
do vec::as_buf(buf) |buf_p, buf_len| {
assert buf_len <= len;
let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
@ -348,7 +348,7 @@ fn flush() -> int { self.base.flush() }
impl of writer for *libc::FILE {
fn write(v: &[const u8]) {
do vec::unpack_const_slice(v) |vbuf, len| {
do vec::as_const_buf(v) |vbuf, len| {
let nout = libc::fwrite(vbuf as *c_void, len as size_t,
1u as size_t, self);
if nout < 1 as size_t {
@ -377,7 +377,7 @@ fn FILE_writer(f: *libc::FILE, cleanup: bool) -> writer {
impl of writer for fd_t {
fn write(v: &[const u8]) {
let mut count = 0u;
do vec::unpack_const_slice(v) |vbuf, len| {
do vec::as_const_buf(v) |vbuf, len| {
while count < len {
let vb = ptr::const_offset(vbuf, count) as *c_void;
let nout = libc::write(self, vb, len as size_t);

View File

@ -175,10 +175,10 @@ fn test_unwrap_ptr() {
#[test]
fn test_unwrap_str() {
let x = ~"test";
let addr_x = str::as_buf(x, |buf| ptr::addr_of(buf));
let addr_x = str::as_buf(x, |buf, _len| ptr::addr_of(buf));
let opt = some(x);
let y = unwrap(opt);
let addr_y = str::as_buf(y, |buf| ptr::addr_of(buf));
let addr_y = str::as_buf(y, |buf, _len| ptr::addr_of(buf));
assert addr_x == addr_y;
}

View File

@ -71,8 +71,8 @@ fn as_c_charp<T>(s: ~str, f: fn(*c_char) -> T) -> T {
fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool)
-> option<~str> {
let buf = vec::to_mut(vec::from_elem(tmpbuf_sz, 0u8 as c_char));
do vec::as_mut_buf(buf) |b| {
if f(b, tmpbuf_sz as size_t) unsafe {
do vec::as_mut_buf(buf) |b, sz| {
if f(b, sz as size_t) unsafe {
some(str::unsafe::from_buf(b as *u8))
} else {
none
@ -667,7 +667,7 @@ fn do_copy_file(from: path, to: path) -> bool {
let mut done = false;
let mut ok = true;
while !done {
do vec::as_mut_buf(buf) |b| {
do vec::as_mut_buf(buf) |b, _sz| {
let nread = libc::fread(b as *mut c_void, 1u as size_t,
bufsize as size_t,
istream);
@ -970,7 +970,7 @@ fn copy_file_ok() {
assert (ostream as uint != 0u);
let s = ~"hello";
let mut buf = vec::to_mut(str::bytes(s) + ~[0 as u8]);
do vec::as_mut_buf(buf) |b| {
do vec::as_mut_buf(buf) |b, _len| {
assert (libc::fwrite(b as *c_void, 1u as size_t,
(str::len(s) + 1u) as size_t, ostream)
== buf.len() as size_t)};

View File

@ -192,8 +192,9 @@ fn test_buf_len() {
do str::as_c_str(s1) |p1| {
do str::as_c_str(s2) |p2| {
let v = ~[p0, p1, p2, null()];
do vec::as_buf(v) |vp| {
do vec::as_buf(v) |vp, len| {
assert unsafe { buf_len(vp) } == 3u;
assert len == 4u;
}
}
}

View File

@ -88,7 +88,7 @@ fn with_argv<T>(prog: ~str, args: ~[~str],
vec::push_all(argptrs, str::as_c_str(*t, |b| ~[b]));
}
vec::push(argptrs, ptr::null());
vec::as_buf(argptrs, cb)
vec::as_buf(argptrs, |buf, _len| cb(buf))
}
#[cfg(unix)]
@ -108,7 +108,7 @@ fn with_envp<T>(env: option<~[(~str,~str)]>,
vec::push_all(ptrs, str::as_c_str(*t, |b| ~[b]));
}
vec::push(ptrs, ptr::null());
vec::as_buf(ptrs, |p|
vec::as_buf(ptrs, |p, _len|
unsafe { cb(::unsafe::reinterpret_cast(p)) }
)
}

View File

@ -23,7 +23,6 @@
as_bytes,
as_buf,
as_c_str,
unpack_slice,
// Adding things to and removing things from a string
push_str_no_overallocate,
@ -127,11 +126,16 @@
*
* Fails if invalid UTF-8
*/
pure fn from_bytes(+vv: ~[u8]) -> ~str {
pure fn from_bytes(vv: &[const u8]) -> ~str {
assert is_utf8(vv);
ret unsafe { unsafe::from_bytes(vv) };
}
/// Copy a slice into a new unique str
pure fn from_slice(s: &str) -> ~str {
unsafe { unsafe::slice_bytes(s, 0, len(s)) }
}
/**
* Convert a byte to a UTF-8 string
*
@ -159,7 +163,7 @@ fn push_char(&s: ~str, ch: char) {
let new_len = len + nb;
reserve_at_least(s, new_len);
let off = len;
do as_buf(s) |buf| {
do as_buf(s) |buf, _len| {
let buf: *mut u8 = ::unsafe::reinterpret_cast(buf);
if nb == 1u {
*ptr::mut_offset(buf, off) =
@ -245,8 +249,8 @@ fn push_str_no_overallocate(&lhs: ~str, rhs: &str) {
let llen = lhs.len();
let rlen = rhs.len();
reserve(lhs, llen + rlen);
do as_buf(lhs) |lbuf| {
do unpack_slice(rhs) |rbuf, _rlen| {
do as_buf(lhs) |lbuf, _llen| {
do as_buf(rhs) |rbuf, _rlen| {
let dst = ptr::offset(lbuf, llen);
ptr::memcpy(dst, rbuf, rlen);
}
@ -261,8 +265,8 @@ fn push_str(&lhs: ~str, rhs: &str) {
let llen = lhs.len();
let rlen = rhs.len();
reserve_at_least(lhs, llen + rlen);
do as_buf(lhs) |lbuf| {
do unpack_slice(rhs) |rbuf, _rlen| {
do as_buf(lhs) |lbuf, _llen| {
do as_buf(rhs) |rbuf, _rlen| {
let dst = ptr::offset(lbuf, llen);
ptr::memcpy(dst, rbuf, rlen);
}
@ -290,7 +294,7 @@ fn push_str(&lhs: ~str, rhs: &str) {
}
/// Concatenate a vector of strings, placing a given separator between each
pure fn connect(v: &[~str], sep: ~str) -> ~str {
pure fn connect(v: &[~str], sep: &str) -> ~str {
let mut s = ~"", first = true;
for vec::each(v) |ss| {
if first { first = false; } else { unchecked { push_str(s, sep); } }
@ -335,30 +339,28 @@ fn shift_char(&s: ~str) -> char {
fn unshift_char(&s: ~str, ch: char) { s = from_char(ch) + s; }
/// Returns a string with leading whitespace removed
pure fn trim_left(+s: ~str) -> ~str {
pure fn trim_left(s: &str) -> ~str {
alt find(s, |c| !char::is_whitespace(c)) {
none { ~"" }
some(first) {
if first == 0u { s }
else unsafe { unsafe::slice_bytes(s, first, len(s)) }
unsafe { unsafe::slice_bytes(s, first, len(s)) }
}
}
}
/// Returns a string with trailing whitespace removed
pure fn trim_right(+s: ~str) -> ~str {
pure fn trim_right(s: &str) -> ~str {
alt rfind(s, |c| !char::is_whitespace(c)) {
none { ~"" }
some(last) {
let {next, _} = char_range_at(s, last);
if next == len(s) { s }
else unsafe { unsafe::slice_bytes(s, 0u, next) }
unsafe { unsafe::slice_bytes(s, 0u, next) }
}
}
}
/// Returns a string with leading and trailing whitespace removed
pure fn trim(+s: ~str) -> ~str { trim_left(trim_right(s)) }
pure fn trim(s: &str) -> ~str { trim_left(trim_right(s)) }
/*
Section: Transforming strings
@ -369,9 +371,9 @@ fn shift_char(&s: ~str) -> char {
*
* The result vector is not null-terminated.
*/
pure fn bytes(s: ~str) -> ~[u8] {
pure fn bytes(s: &str) -> ~[u8] {
unsafe {
let mut s_copy = s;
let mut s_copy = from_slice(s);
let mut v: ~[u8] = ::unsafe::transmute(s_copy);
vec::unsafe::set_len(v, len(s));
ret v;
@ -381,7 +383,7 @@ fn shift_char(&s: ~str) -> char {
/// Work with the string as a byte slice, not including trailing null.
#[inline(always)]
pure fn byte_slice<T>(s: &str, f: fn(v: &[u8]) -> T) -> T {
do unpack_slice(s) |p,n| {
do as_buf(s) |p,n| {
unsafe { vec::unsafe::form_slice(p, n-1u, f) }
}
}
@ -622,7 +624,7 @@ fn shift_char(&s: ~str) -> char {
*
* The original string with all occurances of `from` replaced with `to`
*/
pure fn replace(s: ~str, from: ~str, to: ~str) -> ~str {
pure fn replace(s: &str, from: &str, to: &str) -> ~str {
let mut result = ~"", first = true;
do iter_between_matches(s, from) |start, end| {
if first { first = false; } else { unchecked {push_str(result, to); }}
@ -1277,7 +1279,7 @@ fn is_alphanumeric(s: &str) -> bool {
/// Returns the string length/size in bytes not counting the null terminator
pure fn len(s: &str) -> uint {
do unpack_slice(s) |_p, n| { n - 1u }
do as_buf(s) |_p, n| { n - 1u }
}
/// Returns the number of characters that a string holds
@ -1288,7 +1290,7 @@ fn is_alphanumeric(s: &str) -> bool {
*/
/// Determines if a vector of bytes contains valid UTF-8
pure fn is_utf8(v: &[u8]) -> bool {
pure fn is_utf8(v: &[const u8]) -> bool {
let mut i = 0u;
let total = vec::len::<u8>(v);
while i < total {
@ -1636,43 +1638,44 @@ fn is_alphanumeric(s: &str) -> bool {
}
}
/**
* Work with the byte buffer of a string.
*
* Allows for unsafe manipulation of strings, which is useful for foreign
* interop.
*/
pure fn as_buf<T>(s: ~str, f: fn(*u8) -> T) -> T {
as_bytes(s, |v| unsafe { vec::as_buf(v, f) })
}
/**
* Work with the byte buffer of a string as a null-terminated C string.
*
* Allows for unsafe manipulation of strings, which is useful for foreign
* interop, without copying the original string.
* interop. This is similar to `str::as_buf`, but guarantees null-termination.
* If the given slice is not already null-terminated, this function will
* allocate a temporary, copy the slice, null terminate it, and pass
* that instead.
*
* # Example
*
* ~~~
* let s = str::as_buf("PATH", { |path_buf| libc::getenv(path_buf) });
* let s = str::as_c_str("PATH", { |path| libc::getenv(path) });
* ~~~
*/
pure fn as_c_str<T>(s: ~str, f: fn(*libc::c_char) -> T) -> T {
as_buf(s, |buf| f(buf as *libc::c_char))
pure fn as_c_str<T>(s: &str, f: fn(*libc::c_char) -> T) -> T {
do as_buf(s) |buf, len| {
// NB: len includes the trailing null.
assert len > 0;
if unsafe { *(ptr::offset(buf,len-1)) != 0 } {
as_c_str(from_slice(s), f)
} else {
f(buf as *libc::c_char)
}
}
}
/**
* Work with the byte buffer and length of a slice.
*
* The unpacked length is one byte longer than the 'official' indexable
* The given length is one byte longer than the 'official' indexable
* length of the string. This is to permit probing the byte past the
* indexable area for a null byte, as is the case in slices pointing
* to full strings, or suffixes of them.
*/
#[inline(always)]
pure fn unpack_slice<T>(s: &str, f: fn(*u8, uint) -> T) -> T {
pure fn as_buf<T>(s: &str, f: fn(*u8, uint) -> T) -> T {
unsafe {
let v : *(*u8,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
let (buf,len) = *v;
@ -1783,10 +1786,10 @@ unsafe fn from_buf(buf: *u8) -> ~str {
}
/// Create a Rust string from a *u8 buffer of the given length
unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str {
let mut v: ~[u8] = ~[];
unsafe fn from_buf_len(buf: *const u8, len: uint) -> ~str {
let mut v: ~[mut u8] = ~[mut];
vec::reserve(v, len + 1u);
vec::as_buf(v, |b| ptr::memcpy(b, buf, len));
vec::as_buf(v, |b, _len| ptr::memcpy(b, buf as *u8, len));
vec::unsafe::set_len(v, len);
vec::push(v, 0u8);
@ -1804,25 +1807,15 @@ unsafe fn from_c_str_len(c_str: *libc::c_char, len: uint) -> ~str {
from_buf_len(::unsafe::reinterpret_cast(c_str), len)
}
/**
* Converts a vector of bytes to a string.
*
* Does not verify that the vector contains valid UTF-8.
*/
unsafe fn from_bytes(+v: ~[const u8]) -> ~str {
unsafe {
let mut vcopy = ::unsafe::transmute(v);
vec::push(vcopy, 0u8);
::unsafe::transmute(vcopy)
}
}
/// Converts a vector of bytes to a string.
unsafe fn from_bytes(v: &[const u8]) -> ~str {
do vec::as_const_buf(v) |buf, len| {
from_buf_len(buf, len)
}
}
/**
* Converts a byte to a string.
*
* Does not verify that the byte is valid UTF-8.
*/
unsafe fn from_byte(u: u8) -> ~str { unsafe::from_bytes(~[u]) }
/// Converts a byte to a string.
unsafe fn from_byte(u: u8) -> ~str { unsafe::from_bytes([u]) }
/**
* Takes a bytewise (not UTF-8) slice from a string.
@ -1835,14 +1828,14 @@ unsafe fn from_byte(u: u8) -> ~str { unsafe::from_bytes(~[u]) }
* If end is greater than the length of the string.
*/
unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> ~str {
do unpack_slice(s) |sbuf, n| {
do as_buf(s) |sbuf, n| {
assert (begin <= end);
assert (end <= n);
let mut v = ~[];
vec::reserve(v, end - begin + 1u);
unsafe {
do vec::as_buf(v) |vbuf| {
do vec::as_buf(v) |vbuf, _vlen| {
let src = ptr::offset(sbuf, begin);
ptr::memcpy(vbuf, src, end - begin);
}
@ -2683,7 +2676,7 @@ fn test_as_bytes_fail() {
#[test]
fn test_as_buf() {
let a = ~"Abcdefg";
let b = as_buf(a, |buf| {
let b = as_buf(a, |buf, _l| {
assert unsafe { *buf } == 65u8;
100
});
@ -2693,7 +2686,7 @@ fn test_as_buf() {
#[test]
fn test_as_buf_small() {
let a = ~"A";
let b = as_buf(a, |buf| {
let b = as_buf(a, |buf, _l| {
assert unsafe { *buf } == 65u8;
100
});
@ -2704,12 +2697,26 @@ fn test_as_buf_small() {
fn test_as_buf2() {
unsafe {
let s = ~"hello";
let sb = as_buf(s, |b| b);
let sb = as_buf(s, |b, _l| b);
let s_cstr = unsafe::from_buf(sb);
assert (eq(s_cstr, s));
}
}
#[test]
fn test_as_buf_3() {
let a = ~"hello";
do as_buf(a) |buf, len| {
unsafe {
assert a[0] == 'h' as u8;
assert *buf == 'h' as u8;
assert len == 6u;
assert *ptr::offset(buf,4u) == 'o' as u8;
assert *ptr::offset(buf,5u) == 0u8;
}
}
}
#[test]
fn vec_str_conversions() {
let s1: ~str = ~"All mimsy were the borogoves";
@ -2952,20 +2959,6 @@ fn test_each_char() {
assert found_b;
}
#[test]
fn test_unpack_slice() {
let a = ~"hello";
do unpack_slice(a) |buf, len| {
unsafe {
assert a[0] == 'h' as u8;
assert *buf == 'h' as u8;
assert len == 6u;
assert *ptr::offset(buf,4u) == 'o' as u8;
assert *ptr::offset(buf,5u) == 0u8;
}
}
}
#[test]
fn test_escape_unicode() {
assert escape_unicode(~"abc") == ~"\\x61\\x62\\x63";

View File

@ -161,7 +161,7 @@ fn from_str_radix(buf: ~str, radix: u64) -> option<u64> {
*/
fn to_str(num: T, radix: uint) -> ~str {
do to_str_bytes(false, num, radix) |slice| {
do vec::unpack_slice(slice) |p, len| {
do vec::as_buf(slice) |p, len| {
unsafe { str::unsafe::from_buf_len(p, len) }
}
}
@ -206,7 +206,7 @@ fn digit(n: T) -> u8 {
// in-bounds, no extra cost.
unsafe {
do vec::unpack_slice(buf) |p, len| {
do vec::as_buf(buf) |p, len| {
let mp = p as *mut u8;
let mut i = len;
let mut n = num;

View File

@ -81,8 +81,7 @@
export windowed;
export as_buf;
export as_mut_buf;
export unpack_slice;
export unpack_const_slice;
export as_const_buf;
export unsafe;
export u8;
export extensions;
@ -113,12 +112,12 @@ fn vec_from_buf_shared(++t: *sys::type_desc,
/// Returns true if a vector contains no elements
pure fn is_empty<T>(v: &[const T]) -> bool {
unpack_const_slice(v, |_p, len| len == 0u)
as_const_buf(v, |_p, len| len == 0u)
}
/// Returns true if a vector contains some elements
pure fn is_not_empty<T>(v: &[const T]) -> bool {
unpack_const_slice(v, |_p, len| len > 0u)
as_const_buf(v, |_p, len| len > 0u)
}
/// Returns true if two vectors have the same length
@ -177,7 +176,7 @@ fn reserve_at_least<T>(&v: ~[const T], n: uint) {
/// Returns the length of a vector
#[inline(always)]
pure fn len<T>(&&v: &[const T]) -> uint {
unpack_const_slice(v, |_p, len| len)
as_const_buf(v, |_p, len| len)
}
/**
@ -317,7 +316,7 @@ fn reserve_at_least<T>(&v: ~[const T], n: uint) {
pure fn view<T>(v: &[T], start: uint, end: uint) -> &[T] {
assert (start <= end);
assert (end <= len(v));
do unpack_slice(v) |p, _len| {
do as_buf(v) |p, _len| {
unsafe {
::unsafe::reinterpret_cast(
(ptr::offset(p, start), (end - start) * sys::size_of::<T>()))
@ -329,7 +328,7 @@ fn reserve_at_least<T>(&v: ~[const T], n: uint) {
pure fn mut_view<T>(v: &[mut T], start: uint, end: uint) -> &[mut T] {
assert (start <= end);
assert (end <= len(v));
do unpack_slice(v) |p, _len| {
do as_buf(v) |p, _len| {
unsafe {
::unsafe::reinterpret_cast(
(ptr::offset(p, start), (end - start) * sys::size_of::<T>()))
@ -341,7 +340,7 @@ fn reserve_at_least<T>(&v: ~[const T], n: uint) {
pure fn const_view<T>(v: &[const T], start: uint, end: uint) -> &[const T] {
assert (start <= end);
assert (end <= len(v));
do unpack_slice(v) |p, _len| {
do as_buf(v) |p, _len| {
unsafe {
::unsafe::reinterpret_cast(
(ptr::offset(p, start), (end - start) * sys::size_of::<T>()))
@ -481,7 +480,7 @@ fn unshift<T>(&v: ~[T], +x: T) {
}
fn consume<T>(+v: ~[T], f: fn(uint, +T)) unsafe {
do unpack_slice(v) |p, ln| {
do as_buf(v) |p, ln| {
for uint::range(0, ln) |i| {
let x <- *ptr::offset(p, i);
f(i, x);
@ -529,13 +528,13 @@ fn push_slow<T>(&v: ~[const T], +initval: T) {
// Unchecked vector indexing
#[inline(always)]
unsafe fn ref<T: copy>(v: &[const T], i: uint) -> T {
unpack_slice(v, |p, _len| *ptr::offset(p, i))
as_buf(v, |p, _len| *ptr::offset(p, i))
}
#[inline(always)]
unsafe fn ref_set<T: copy>(v: &[mut T], i: uint, +val: T) {
let mut box = some(val);
do unpack_mut_slice(v) |p, _len| {
do as_mut_buf(v) |p, _len| {
let mut box2 = none;
box2 <-> box;
rusti::move_val_init(*ptr::mut_offset(p, i), option::unwrap(box2));
@ -555,7 +554,7 @@ fn push_all<T: copy>(&v: ~[const T], rhs: &[const T]) {
fn push_all_move<T>(&v: ~[const T], -rhs: ~[const T]) {
reserve(v, v.len() + rhs.len());
unsafe {
do unpack_slice(rhs) |p, len| {
do as_buf(rhs) |p, len| {
for uint::range(0, len) |i| {
let x <- *ptr::offset(p, i);
push(v, x);
@ -1056,7 +1055,7 @@ fn reverse<T>(v: ~[mut T]) {
*/
#[inline(always)]
pure fn iter_between<T>(v: &[T], start: uint, end: uint, f: fn(T)) {
do unpack_slice(v) |base_ptr, len| {
do as_buf(v) |base_ptr, len| {
assert start <= end;
assert end <= len;
unsafe {
@ -1078,7 +1077,7 @@ fn reverse<T>(v: ~[mut T]) {
*/
#[inline(always)]
pure fn each<T>(v: &[T], f: fn(T) -> bool) {
do vec::unpack_slice(v) |p, n| {
do vec::as_buf(v) |p, n| {
let mut n = n;
let mut p = p;
while n > 0u {
@ -1098,7 +1097,7 @@ fn reverse<T>(v: ~[mut T]) {
*/
#[inline(always)]
pure fn eachi<T>(v: &[T], f: fn(uint, T) -> bool) {
do vec::unpack_slice(v) |p, n| {
do vec::as_buf(v) |p, n| {
let mut i = 0u;
let mut p = p;
while i < n {
@ -1118,7 +1117,7 @@ fn reverse<T>(v: ~[mut T]) {
*/
#[inline(always)]
pure fn reach<T>(v: &[T], blk: fn(T) -> bool) {
do vec::unpack_slice(v) |p, n| {
do vec::as_buf(v) |p, n| {
let mut i = 1;
while i <= n {
unsafe {
@ -1136,7 +1135,7 @@ fn reverse<T>(v: ~[mut T]) {
*/
#[inline(always)]
pure fn reachi<T>(v: &[T], blk: fn(uint, T) -> bool) {
do vec::unpack_slice(v) |p, n| {
do vec::as_buf(v) |p, n| {
let mut i = 1;
while i <= n {
unsafe {
@ -1247,18 +1246,9 @@ fn iter2<U, T>(v1: &[U], v2: &[T], f: fn(U, T)) {
* Allows for unsafe manipulation of vector contents, which is useful for
* foreign interop.
*/
fn as_buf<E,T>(v: &[E], f: fn(*E) -> T) -> T {
unpack_slice(v, |buf, _len| f(buf))
}
fn as_mut_buf<E,T>(v: &[mut E], f: fn(*mut E) -> T) -> T {
unpack_mut_slice(v, |buf, _len| f(buf))
}
/// Work with the buffer and length of a slice.
#[inline(always)]
pure fn unpack_slice<T,U>(s: &[const T],
f: fn(*T, uint) -> U) -> U {
pure fn as_buf<T,U>(s: &[const T],
f: fn(*T, uint) -> U) -> U {
unsafe {
let v : *(*T,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
let (buf,len) = *v;
@ -1266,27 +1256,27 @@ fn as_mut_buf<E,T>(v: &[mut E], f: fn(*mut E) -> T) -> T {
}
}
/// Work with the buffer and length of a slice.
/// Similar to `as_buf` but passing a `*const T`
#[inline(always)]
pure fn unpack_const_slice<T,U>(s: &[const T],
f: fn(*const T, uint) -> U) -> U {
unsafe {
let v : *(*const T,uint) =
::unsafe::reinterpret_cast(ptr::addr_of(s));
let (buf,len) = *v;
f(buf, len / sys::size_of::<T>())
pure fn as_const_buf<T,U>(s: &[const T],
f: fn(*const T, uint) -> U) -> U {
do as_buf(s) |p, len| {
unsafe {
let pp : *const T = ::unsafe::reinterpret_cast(p);
f(pp, len)
}
}
}
/// Work with the buffer and length of a slice.
/// Similar to `as_buf` but passing a `*mut T`
#[inline(always)]
pure fn unpack_mut_slice<T,U>(s: &[mut T],
f: fn(*mut T, uint) -> U) -> U {
unsafe {
let v : *(*const T,uint) =
::unsafe::reinterpret_cast(ptr::addr_of(s));
let (buf,len) = *v;
f(buf, len / sys::size_of::<T>())
pure fn as_mut_buf<T,U>(s: &[mut T],
f: fn(*mut T, uint) -> U) -> U {
do as_buf(s) |p, len| {
unsafe {
let pp : *mut T = ::unsafe::reinterpret_cast(p);
f(pp, len)
}
}
}
@ -1605,8 +1595,8 @@ unsafe fn form_slice<T,U>(p: *T, len: uint, f: fn(&& &[T]) -> U) -> U {
* may overlap.
*/
unsafe fn memcpy<T>(dst: &[mut T], src: &[const T], count: uint) {
do unpack_slice(dst) |p_dst, _len_dst| {
do unpack_slice(src) |p_src, _len_src| {
do as_buf(dst) |p_dst, _len_dst| {
do as_buf(src) |p_src, _len_src| {
ptr::memcpy(p_dst, p_src, count)
}
}
@ -1619,8 +1609,8 @@ unsafe fn memcpy<T>(dst: &[mut T], src: &[const T], count: uint) {
* may overlap.
*/
unsafe fn memmove<T>(dst: &[mut T], src: &[const T], count: uint) {
do unpack_slice(dst) |p_dst, _len_dst| {
do unpack_slice(src) |p_src, _len_src| {
do as_buf(dst) |p_dst, _len_dst| {
do as_buf(src) |p_src, _len_src| {
ptr::memmove(p_dst, p_src, count)
}
}

View File

@ -91,7 +91,7 @@ enum ip_get_addr_err {
fn get_addr(++node: ~str, iotask: iotask)
-> result::result<~[ip_addr], ip_get_addr_err> unsafe {
do comm::listen |output_ch| {
do str::unpack_slice(node) |node_ptr, len| {
do str::as_buf(node) |node_ptr, len| {
log(debug, #fmt("slice len %?", len));
let handle = create_uv_getaddrinfo_t();
let handle_ptr = ptr::addr_of(handle);

View File

@ -46,7 +46,7 @@ fn map_slices<A: copy send, B: copy send>(
while base < len {
let end = uint::min(len, base + items_per_task);
// FIXME: why is the ::<A, ()> annotation required here? (#2617)
do vec::unpack_slice::<A, ()>(xs) |p, _len| {
do vec::as_buf::<A, ()>(xs) |p, _len| {
let f = f();
let f = do future_spawn() |copy base| {
unsafe {

View File

@ -821,10 +821,9 @@ unsafe fn ip4_name(src: &sockaddr_in) -> ~str {
// ipv4 addr max size: 15 + 1 trailing null byte
let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8];
let size = 16 as libc::size_t;
do vec::as_buf(dst) |dst_buf| {
do vec::as_buf(dst) |dst_buf, size| {
rustrt::rust_uv_ip4_name(src as *sockaddr_in,
dst_buf, size);
dst_buf, size as libc::size_t);
// seems that checking the result of uv_ip4_name
// doesn't work too well..
// you're stuck looking at the value of dst_buf
@ -842,13 +841,12 @@ unsafe fn ip6_name(src: &sockaddr_in6) -> ~str {
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
0u8,0u8,0u8,0u8,0u8,0u8];
let size = 46 as libc::size_t;
do vec::as_buf(dst) |dst_buf| {
do vec::as_buf(dst) |dst_buf, size| {
let src_unsafe_ptr = src as *sockaddr_in6;
log(debug, #fmt("val of src *sockaddr_in6: %? sockaddr_in6: %?",
src_unsafe_ptr, src));
let result = rustrt::rust_uv_ip6_name(src_unsafe_ptr,
dst_buf, size);
dst_buf, size as libc::size_t);
alt result {
0i32 {
str::unsafe::from_buf(dst_buf)

View File

@ -66,7 +66,7 @@ fn align(off: uint, ty: TypeRef) -> uint {
fn struct_tys(ty: TypeRef) -> ~[TypeRef] {
let n = llvm::LLVMCountStructElementTypes(ty);
let elts = vec::from_elem(n as uint, ptr::null());
do vec::as_buf(elts) |buf| {
do vec::as_buf(elts) |buf, _len| {
llvm::LLVMGetStructElementTypes(ty, buf);
}
ret elts;

View File

@ -9,7 +9,7 @@ fn main() {
// huge).
let x = ~[1u,2u,3u];
do vec::unpack_slice(x) |p, _len| {
do vec::as_buf(x) |p, _len| {
let base = p as uint; // base = 0x1230 say
let idx = base / sys::size_of::<uint>(); // idx = 0x0246 say
#error("ov1 base = 0x%x", base);