about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2013-09-26 22:49:10 -0700
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2013-09-26 22:49:10 -0700
commitb1ee87f402f929689fc028010c450184f661db3b (patch)
tree7f4542f6c5176d823330512ec1f863a5b4c46058 /src/libstd
parent2d878033fd77f13a41bb9142ba2a4e9b976d0089 (diff)
downloadrust-b1ee87f402f929689fc028010c450184f661db3b.tar.gz
rust-b1ee87f402f929689fc028010c450184f661db3b.zip
std: simplify vec.with_c_str
This also fixes a bug in `vec.with_c_str_unchecked` where we
were not calling `.to_c_str_unchecked()` for long strings.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/c_str.rs48
1 files changed, 20 insertions, 28 deletions
diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs
index e789e9a3bf1..acfa02a4def 100644
--- a/src/libstd/c_str.rs
+++ b/src/libstd/c_str.rs
@@ -71,6 +71,7 @@ use ptr;
 use str::StrSlice;
 use str;
 use vec::{CopyableVector, ImmutableVector, MutableVector};
+use vec;
 use unstable::intrinsics;
 
 /// Resolution options for the `null_byte` condition
@@ -283,41 +284,32 @@ impl<'self> ToCStr for &'self [u8] {
     }
 
     fn with_c_str<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
-        if self.len() < BUF_LEN {
-            do self.as_imm_buf |self_buf, self_len| {
-                unsafe {
-                    let mut buf: [u8, .. BUF_LEN] = intrinsics::uninit();
-
-                    do buf.as_mut_buf |buf, _| {
-                        ptr::copy_memory(buf, self_buf, self_len);
-                        *ptr::mut_offset(buf, self_len as int) = 0;
-
-                        check_for_null(*self, buf as *mut libc::c_char);
-
-                        f(buf as *libc::c_char)
-                    }
-                }
-            }
-        } else {
-            self.to_c_str().with_ref(f)
-        }
+        unsafe { with_c_str(*self, true, f) }
     }
 
     unsafe fn with_c_str_unchecked<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
-        if self.len() < BUF_LEN {
-            do self.as_imm_buf |self_buf, self_len| {
-                let mut buf: [u8, .. BUF_LEN] = intrinsics::uninit();
+        with_c_str(*self, false, f)
+    }
+}
 
-                do buf.as_mut_buf |buf, _| {
-                    ptr::copy_memory(buf, self_buf, self_len);
-                    *ptr::mut_offset(buf, self_len as int) = 0;
+// Unsafe function that handles possibly copying the &[u8] into a stack array.
+unsafe fn with_c_str<T>(v: &[u8], checked: bool, f: &fn(*libc::c_char) -> T) -> T {
+    if v.len() < BUF_LEN {
+        let mut buf: [u8, .. BUF_LEN] = intrinsics::uninit();
+        vec::bytes::copy_memory(buf, v, v.len());
+        buf[v.len()] = 0;
 
-                    f(buf as *libc::c_char)
-                }
+        do buf.as_mut_buf |buf, _| {
+            if checked {
+                check_for_null(v, buf as *mut libc::c_char);
             }
-        } else {
-            self.to_c_str().with_ref(f)
+
+            f(buf as *libc::c_char)
         }
+    } else if checked {
+        v.to_c_str().with_ref(f)
+    } else {
+        v.to_c_str_unchecked().with_ref(f)
     }
 }