From 347383b97e5e026e30f2a6877072c1e1431d6a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Sat, 19 Jul 2014 11:34:51 +0200 Subject: [PATCH 1/8] Remove OwnedStr trait This trait was only implemented by `String`. It provided the methods `into_bytes` and `append`, both of which **are already implemented as normal methods** of `String` (not as trait methods). This change improves the consistency of strings. This shouldn't break any code, except if somebody has implemented `OwnedStr` for a user-defined type. --- src/libcollections/str.rs | 29 ----------------------------- src/libstd/ascii.rs | 2 +- src/libstd/os.rs | 4 ---- src/libstd/prelude.rs | 2 +- 4 files changed, 2 insertions(+), 35 deletions(-) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 48bc492e25ce4..3cd368b59bce5 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -601,11 +601,6 @@ pub mod raw { from_utf8_owned(vec![u]) } - /// Sets the length of a string - /// - /// This will explicitly set the size of the string, without actually - /// modifying its buffers, so it is up to the caller to ensure that - /// the string is actually the specified size. #[test] fn test_from_buf_len() { use slice::ImmutableVector; @@ -783,30 +778,6 @@ impl<'a> StrAllocating for &'a str { } } -/// Methods for owned strings -pub trait OwnedStr { - /// Consumes the string, returning the underlying byte buffer. - /// - /// The buffer does not have a null terminator. - fn into_bytes(self) -> Vec; - - /// Pushes the given string onto this string, returning the concatenation of the two strings. - fn append(self, rhs: &str) -> String; -} - -impl OwnedStr for String { - #[inline] - fn into_bytes(self) -> Vec { - unsafe { mem::transmute(self) } - } - - #[inline] - fn append(mut self, rhs: &str) -> String { - self.push_str(rhs); - self - } -} - #[cfg(test)] mod tests { use std::iter::AdditiveIterator; diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 02cb5dd245b7c..bcc0761d92a3a 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -20,7 +20,7 @@ use iter::Iterator; use mem; use option::{Option, Some, None}; use slice::{ImmutableVector, MutableVector, Vector}; -use str::{OwnedStr, Str, StrAllocating, StrSlice}; +use str::{Str, StrAllocating, StrSlice}; use string::String; use to_string::IntoStr; use vec::Vec; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 96d3b3e3e6a53..7d95c52cb46a6 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -56,8 +56,6 @@ use vec::Vec; use c_str::ToCStr; #[cfg(unix)] use libc::c_char; -#[cfg(windows)] -use str::OwnedStr; /// Get the number of cores available pub fn num_cpus() -> uint { @@ -708,8 +706,6 @@ pub fn self_exe_name() -> Option { #[cfg(windows)] fn load_self() -> Option> { - use str::OwnedStr; - unsafe { use os::win32::fill_utf16_buf_and_decode; fill_utf16_buf_and_decode(|buf, sz| { diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 0fa223305a669..454064b6db918 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -76,7 +76,7 @@ #[doc(no_inline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath}; #[doc(no_inline)] pub use ptr::RawPtr; #[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek}; -#[doc(no_inline)] pub use str::{Str, StrVector, StrSlice, OwnedStr}; +#[doc(no_inline)] pub use str::{Str, StrVector, StrSlice}; #[doc(no_inline)] pub use str::{IntoMaybeOwned, StrAllocating, UnicodeStrSlice}; #[doc(no_inline)] pub use to_string::{ToString, IntoStr}; #[doc(no_inline)] pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4}; From 1a4b888b6f8977fc1187baf79e81367268f0cb2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Sat, 19 Jul 2014 12:08:34 +0200 Subject: [PATCH 2/8] Deprecated `str::raw::from_c_str` Use `string::raw::from_buf` instead [breaking-change] --- src/libcollections/str.rs | 15 +++------------ src/libcoretest/ptr.rs | 16 +++++++--------- src/librustc/middle/trans/type_.rs | 11 +++++------ src/librustuv/lib.rs | 6 +++--- src/libstd/os.rs | 2 +- src/test/run-pass/const-str-ptr.rs | 2 +- 6 files changed, 20 insertions(+), 32 deletions(-) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 3cd368b59bce5..9d2c9c495a627 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -555,9 +555,9 @@ impl<'a> fmt::Show for MaybeOwned<'a> { /// Unsafe operations pub mod raw { - use core::prelude::*; use core::mem; use core::raw::Slice; + use core::ptr::RawPtr; use string::String; use vec::Vec; @@ -575,7 +575,8 @@ pub mod raw { result } - /// Create a Rust string from a null-terminated C string + /// Deprecated. Use `CString::as_str().unwrap().to_string()` + #[deprecated = "Use CString::as_str().unwrap().to_string()"] pub unsafe fn from_c_str(c_string: *const i8) -> String { let mut buf = String::new(); let mut len = 0; @@ -1346,16 +1347,6 @@ mod tests { [0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]); } - #[test] - fn test_raw_from_c_str() { - unsafe { - let a = vec![65, 65, 65, 65, 65, 65, 65, 0]; - let b = a.as_ptr(); - let c = raw::from_c_str(b); - assert_eq!(c, String::from_str("AAAAAAA")); - } - } - #[test] fn test_as_bytes() { // no null diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs index 2a4ef5e275d20..9058ae56c45e4 100644 --- a/src/libcoretest/ptr.rs +++ b/src/libcoretest/ptr.rs @@ -11,8 +11,8 @@ use core::ptr::*; use libc::c_char; use core::mem; -use std::str; use libc; +use std::c_str::CString; #[test] fn test() { @@ -186,9 +186,8 @@ fn test_ptr_array_each_with_len() { let mut ctr = 0; let mut iteration_count = 0; array_each_with_len(arr.as_ptr(), arr.len(), |e| { - let actual = str::raw::from_c_str(e); - let expected = str::raw::from_c_str(expected_arr[ctr].as_ptr()); - assert_eq!(actual.as_slice(), expected.as_slice()); + let actual = CString::new(e, false); + assert_eq!(actual.as_str(), expected_arr[ctr].as_str()); ctr += 1; iteration_count += 1; }); @@ -217,9 +216,8 @@ fn test_ptr_array_each() { let mut ctr = 0u; let mut iteration_count = 0u; array_each(arr_ptr, |e| { - let actual = str::raw::from_c_str(e); - let expected = str::raw::from_c_str(expected_arr[ctr].as_ptr()); - assert_eq!(actual.as_slice(), expected.as_slice()); + let actual = CString::new(e, false); + assert_eq!(actual.as_str(), expected_arr[ctr].as_str()); ctr += 1; iteration_count += 1; }); @@ -232,7 +230,7 @@ fn test_ptr_array_each() { fn test_ptr_array_each_with_len_null_ptr() { unsafe { array_each_with_len(0 as *const *const libc::c_char, 1, |e| { - str::raw::from_c_str(e); + CString::new(e, false).as_str().unwrap(); }); } } @@ -241,7 +239,7 @@ fn test_ptr_array_each_with_len_null_ptr() { fn test_ptr_array_each_null_ptr() { unsafe { array_each(0 as *const *const libc::c_char, |e| { - str::raw::from_c_str(e); + CString::new(e, false).as_str().unwrap(); }); } } diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 573965108ad94..3833d4cd0c854 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -19,11 +19,10 @@ use middle::trans::context::CrateContext; use syntax::ast; use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel}; -use std::c_str::ToCStr; +use std::c_str::{CString, ToCStr}; use std::mem; use std::cell::RefCell; use std::collections::HashMap; -use std::str::raw::from_c_str; use libc::{c_uint, c_void, free}; @@ -334,9 +333,9 @@ impl TypeNames { pub fn type_to_string(&self, ty: Type) -> String { unsafe { let s = llvm::LLVMTypeToString(ty.to_ref()); - let ret = from_c_str(s); + let ret = CString::new(s, false).as_str().unwrap().to_string(); free(s as *mut c_void); - ret.to_string() + ret } } @@ -348,9 +347,9 @@ impl TypeNames { pub fn val_to_string(&self, val: ValueRef) -> String { unsafe { let s = llvm::LLVMValueToString(val); - let ret = from_c_str(s); + let ret = CString::new(s, false).as_str().unwrap().to_string(); free(s as *mut c_void); - ret.to_string() + ret } } } diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs index 2c2e134d882cb..dc43a68e64d09 100644 --- a/src/librustuv/lib.rs +++ b/src/librustuv/lib.rs @@ -55,6 +55,7 @@ extern crate libc; extern crate alloc; use libc::{c_int, c_void}; +use std::c_str::CString; use std::fmt; use std::mem; use std::ptr; @@ -62,7 +63,6 @@ use std::rt::local::Local; use std::rt::rtio; use std::rt::rtio::{IoResult, IoError}; use std::rt::task::{BlockedTask, Task}; -use std::str::raw::from_c_str; use std::task; pub use self::async::AsyncWatcher; @@ -363,7 +363,7 @@ impl UvError { let inner = match self { &UvError(a) => a }; let name_str = uvll::uv_err_name(inner); assert!(name_str.is_not_null()); - from_c_str(name_str).to_string() + CString::new(name_str, false).as_str().unwrap().to_string() } } @@ -372,7 +372,7 @@ impl UvError { let inner = match self { &UvError(a) => a }; let desc_str = uvll::uv_strerror(inner); assert!(desc_str.is_not_null()); - from_c_str(desc_str).to_string() + CString::new(desc_str, false).as_str().unwrap().to_string() } } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 7d95c52cb46a6..b68c907af60f2 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -998,7 +998,7 @@ pub fn error_string(errnum: uint) -> String { fail!("strerror_r failure"); } - str::raw::from_c_str(p as *const c_char).into_string() + ::c_str::CString::new(p as *const c_char, false).as_str().unwrap().to_string() } } diff --git a/src/test/run-pass/const-str-ptr.rs b/src/test/run-pass/const-str-ptr.rs index 6790e237e2634..57d262d3268a1 100644 --- a/src/test/run-pass/const-str-ptr.rs +++ b/src/test/run-pass/const-str-ptr.rs @@ -24,6 +24,6 @@ pub fn main() { assert!(*(&B[0] as *const u8) == A[0]); let bar = str::raw::from_utf8(A).to_c_str(); - assert_eq!(str::raw::from_c_str(bar.as_ptr()), "hi".to_string()); + assert_eq!(bar.as_str(), "hi".to_c_str().as_str()); } } From 5c6d1c860095dd876a3b58d6a664a9f0f101fd28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Sat, 19 Jul 2014 12:23:47 +0200 Subject: [PATCH 3/8] Deprecated `str::raw::from_utf8_owned` Replaced by `string::raw::from_utf8` [breaking-change] --- src/libcollections/str.rs | 9 ++++----- src/libcollections/string.rs | 13 +++++++++++++ src/libserialize/base64.rs | 4 ++-- src/libserialize/hex.rs | 4 ++-- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 9d2c9c495a627..82f3ac21aa7e6 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -559,7 +559,7 @@ pub mod raw { use core::raw::Slice; use core::ptr::RawPtr; - use string::String; + use string::{mod, String}; use vec::Vec; pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes}; @@ -590,11 +590,10 @@ pub mod raw { buf } - /// Converts an owned vector of bytes to a new owned string. This assumes - /// that the utf-8-ness of the vector has already been validated - #[inline] + /// Deprecated. Replaced by `string::raw::from_utf8` + #[deprecated = "Use string::raw::from_utf8"] pub unsafe fn from_utf8_owned(v: Vec) -> String { - mem::transmute(v) + string::raw::from_utf8(v) } /// Converts a byte to a string. diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index b19bef685901f..95640be122fa8 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -570,6 +570,19 @@ impl Add for String { } } +pub mod raw { + use super::String; + use vec::Vec; + + /// Converts a vector of bytes to a new `String` without checking if + /// it contains valid UTF-8. This is unsafe because it assumes that + /// the utf-8-ness of the vector has already been validated. + #[inline] + pub unsafe fn from_utf8(bytes: Vec) -> String { + String { vec: bytes } + } +} + #[cfg(test)] mod tests { use std::prelude::*; diff --git a/src/libserialize/base64.rs b/src/libserialize/base64.rs index 5e8648d355ebf..9a30e87647a83 100644 --- a/src/libserialize/base64.rs +++ b/src/libserialize/base64.rs @@ -11,8 +11,8 @@ // ignore-lexer-test FIXME #15679 //! Base64 binary-to-text encoding -use std::str; use std::fmt; +use std::string; /// Available encoding character sets pub enum CharacterSet { @@ -148,7 +148,7 @@ impl<'a> ToBase64 for &'a [u8] { } unsafe { - str::raw::from_utf8_owned(v) + string::raw::from_utf8(v) } } } diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs index d6a029c583cd2..fa5b3ca4040d0 100644 --- a/src/libserialize/hex.rs +++ b/src/libserialize/hex.rs @@ -11,8 +11,8 @@ // ignore-lexer-test FIXME #15679 //! Hex binary-to-text encoding -use std::str; use std::fmt; +use std::string; /// A trait for converting a value to hexadecimal encoding pub trait ToHex { @@ -47,7 +47,7 @@ impl<'a> ToHex for &'a [u8] { } unsafe { - str::raw::from_utf8_owned(v) + string::raw::from_utf8(v) } } } From 091ce19a2dfa717ea37cff3ff57c8ff2d47102d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Sat, 19 Jul 2014 12:30:35 +0200 Subject: [PATCH 4/8] Deprecated `str::raw::from_byte` Use `string:raw::from_utf8` instead [breaking-change] --- src/libcollections/str.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 82f3ac21aa7e6..f247ee170e7cd 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -596,9 +596,10 @@ pub mod raw { string::raw::from_utf8(v) } - /// Converts a byte to a string. + /// Deprecated. Use `String::from_bytes` + #[deprecated = "Use String::from_bytes"] pub unsafe fn from_byte(u: u8) -> String { - from_utf8_owned(vec![u]) + String::from_bytes(vec![u]) } #[test] From f8cd834c373c735db16435ffa3f519ff431042a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Sun, 20 Jul 2014 12:08:40 +0200 Subject: [PATCH 5/8] Deprecated `str::raw::from_buf_len` Replaced by `string::raw::from_buf_len` [breaking-change] --- src/libcollections/str.rs | 29 ++++++----------------------- src/libcollections/string.rs | 25 +++++++++++++++++++++++++ src/librustc/metadata/loader.rs | 4 ++-- src/librustdoc/html/markdown.rs | 3 ++- src/libstd/os.rs | 10 +++++----- src/test/run-pass/const-str-ptr.rs | 6 +++--- 6 files changed, 43 insertions(+), 34 deletions(-) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index f247ee170e7cd..de10b5bbbb232 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -558,21 +558,16 @@ pub mod raw { use core::mem; use core::raw::Slice; use core::ptr::RawPtr; - use string::{mod, String}; use vec::Vec; pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes}; pub use core::str::raw::{slice_unchecked}; - /// Create a Rust string from a *u8 buffer of the given length + /// Deprecated. Replaced by `string::raw::from_buf_len` + #[deprecated = "Use string::raw::from_buf_len"] pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> String { - let mut result = String::new(); - result.push_bytes(mem::transmute(Slice { - data: buf, - len: len, - })); - result + string::raw::from_buf_len(buf, len) } /// Deprecated. Use `CString::as_str().unwrap().to_string()` @@ -596,22 +591,10 @@ pub mod raw { string::raw::from_utf8(v) } - /// Deprecated. Use `String::from_bytes` - #[deprecated = "Use String::from_bytes"] + /// Deprecated. Use `string::raw::from_utf8` + #[deprecated = "Use string::raw::from_utf8"] pub unsafe fn from_byte(u: u8) -> String { - String::from_bytes(vec![u]) - } - - #[test] - fn test_from_buf_len() { - use slice::ImmutableVector; - - unsafe { - let a = vec![65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8]; - let b = a.as_ptr(); - let c = from_buf_len(b, 3u); - assert_eq!(c, String::from_str("AAA")); - } + string::raw::from_utf8(vec![u]) } } diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 95640be122fa8..e7c788f51f425 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -571,6 +571,9 @@ impl Add for String { } pub mod raw { + use core::mem; + use core::raw::Slice; + use super::String; use vec::Vec; @@ -581,6 +584,20 @@ pub mod raw { pub unsafe fn from_utf8(bytes: Vec) -> String { String { vec: bytes } } + + /// Create a Rust string from a *u8 buffer of the given length + /// + /// This function is unsafe because of two reasons: + /// * A raw pointer is dereferenced and transmuted to `&[u8]` + /// * The slice is not checked to see whether it contains valid UTF-8 + pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> String { + use slice::CloneableVector; + let slice: &[u8] = mem::transmute(Slice { + data: buf, + len: len, + }); + self::from_utf8(slice.to_vec()) + } } #[cfg(test)] @@ -740,6 +757,14 @@ mod tests { String::from_str("\uFFFD𐒋\uFFFD")); } + #[test] + fn test_from_buf_len() { + unsafe { + let a = vec![65u8, 65, 65, 65, 65, 65, 65, 0]; + assert_eq!(super::raw::from_buf_len(a.as_ptr(), 3), String::from_str("AAA")); + } + } + #[test] fn test_push_bytes() { let mut s = String::from_str("ABC"); diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index e7d52ef3b3d6c..1811c4f8612f0 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -233,7 +233,7 @@ use std::io; use std::mem; use std::ptr; use std::slice; -use std::str; +use std::string; use std::collections::{HashMap, HashSet}; use flate; @@ -772,7 +772,7 @@ fn get_metadata_section_imp(os: abi::Os, filename: &Path) -> Result fmt::Result { "".to_string() } else { unsafe { - str::raw::from_buf_len((*text).data, (*text).size as uint) + string::raw::from_buf_len((*text).data, (*text).size as uint) } }; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index b68c907af60f2..6120d897a258d 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -47,9 +47,9 @@ use ptr; use result::{Err, Ok, Result}; use slice::{Vector, ImmutableVector, MutableVector, ImmutableEqVector}; use str::{Str, StrSlice, StrAllocating}; -use str; use string::String; use sync::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst}; +use to_str::ToString; use vec::Vec; #[cfg(unix)] @@ -135,7 +135,7 @@ pub fn getcwd() -> Path { fail!(); } } - Path::new(String::from_utf16(str::truncate_utf16_at_nul(buf)) + Path::new(String::from_utf16(::str::truncate_utf16_at_nul(buf)) .expect("GetCurrentDirectoryW returned invalid UTF-16")) } @@ -413,7 +413,7 @@ pub fn setenv(n: &str, v: T) { fn _setenv(n: &str, v: &[u8]) { let n: Vec = n.utf16_units().collect(); let n = n.append_one(0); - let v: Vec = str::from_utf8(v).unwrap().utf16_units().collect(); + let v: Vec = ::str::from_utf8(v).unwrap().utf16_units().collect(); let v = v.append_one(0); unsafe { @@ -1045,7 +1045,7 @@ pub fn error_string(errnum: uint) -> String { return format!("OS Error {} (FormatMessageW() returned error {})", errnum, fm_err); } - let msg = String::from_utf16(str::truncate_utf16_at_nul(buf)); + let msg = String::from_utf16(::str::truncate_utf16_at_nul(buf)); match msg { Some(msg) => format!("OS Error {}: {}", errnum, msg), None => format!("OS Error {} (FormatMessageW() returned invalid UTF-16)", errnum), @@ -1202,7 +1202,7 @@ fn real_args() -> Vec { // Push it onto the list. let opt_s = slice::raw::buf_as_slice(ptr as *const _, len, |buf| { - String::from_utf16(str::truncate_utf16_at_nul(buf)) + String::from_utf16(::str::truncate_utf16_at_nul(buf)) }); opt_s.expect("CommandLineToArgvW returned invalid UTF-16") }); diff --git a/src/test/run-pass/const-str-ptr.rs b/src/test/run-pass/const-str-ptr.rs index 57d262d3268a1..0fef3dd4aac24 100644 --- a/src/test/run-pass/const-str-ptr.rs +++ b/src/test/run-pass/const-str-ptr.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::str; +use std::{str, string}; static A: [u8, ..2] = ['h' as u8, 'i' as u8]; static B: &'static [u8, ..2] = &A; @@ -18,8 +18,8 @@ pub fn main() { unsafe { let foo = &A as *const u8; assert_eq!(str::raw::from_utf8(A), "hi"); - assert_eq!(str::raw::from_buf_len(foo, A.len()), "hi".to_string()); - assert_eq!(str::raw::from_buf_len(C, B.len()), "hi".to_string()); + assert_eq!(string::raw::from_buf_len(foo, A.len()), "hi".to_string()); + assert_eq!(string::raw::from_buf_len(C, B.len()), "hi".to_string()); assert!(*C == A[0]); assert!(*(&B[0] as *const u8) == A[0]); From ed2c99b01c042f37f72ee2e32abfec2560b8207b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Mon, 21 Jul 2014 20:44:56 +0200 Subject: [PATCH 6/8] Deprecated `String::from_raw_parts` Replaced by `string::raw::from_parts` [breaking-change] --- src/libcollections/str.rs | 3 ++- src/libcollections/string.rs | 27 +++++++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index de10b5bbbb232..4219dc09d59ad 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -558,7 +558,8 @@ pub mod raw { use core::mem; use core::raw::Slice; use core::ptr::RawPtr; - use string::{mod, String}; + use string; + use string::String; use vec::Vec; pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes}; diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index e7c788f51f425..3e523d4fb57a6 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -49,14 +49,6 @@ impl String { } } - /// Creates a new string buffer from length, capacity, and a pointer. - #[inline] - pub unsafe fn from_raw_parts(length: uint, capacity: uint, ptr: *mut u8) -> String { - String { - vec: Vec::from_raw_parts(length, capacity, ptr), - } - } - /// Creates a new string buffer from the given string. #[inline] pub fn from_str(string: &str) -> String { @@ -65,6 +57,13 @@ impl String { } } + /// Deprecated. Replaced by `string::raw::from_parts` + #[inline] + #[deprecated = "Replaced by string::raw::from_parts"] + pub unsafe fn from_raw_parts(length: uint, capacity: uint, ptr: *mut u8) -> String { + raw::from_parts(length, capacity, ptr) + } + #[allow(missing_doc)] #[deprecated = "obsoleted by the removal of ~str"] #[inline] @@ -577,6 +576,18 @@ pub mod raw { use super::String; use vec::Vec; + /// Creates a new `String` from length, capacity, and a pointer. + /// + /// This is unsafe because: + /// * We call `Vec::from_raw_parts` to get a `Vec` + /// * We assume that the `Vec` contains valid UTF-8 + #[inline] + pub unsafe fn from_parts(length: uint, capacity: uint, ptr: *mut u8) -> String { + String { + vec: Vec::from_raw_parts(length, capacity, ptr), + } + } + /// Converts a vector of bytes to a new `String` without checking if /// it contains valid UTF-8. This is unsafe because it assumes that /// the utf-8-ness of the vector has already been validated. From 604274d4f5f06ab24d9d95ea82369d81900b81fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Tue, 22 Jul 2014 16:02:54 +0200 Subject: [PATCH 7/8] Fix travis errors --- src/libstd/os.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 6120d897a258d..2cd69442b0154 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -49,7 +49,7 @@ use slice::{Vector, ImmutableVector, MutableVector, ImmutableEqVector}; use str::{Str, StrSlice, StrAllocating}; use string::String; use sync::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst}; -use to_str::ToString; +use to_string::ToString; use vec::Vec; #[cfg(unix)] From 0bd6caa12e8dc5809ec5d701368bf43b91c6f8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Tue, 22 Jul 2014 17:55:12 +0200 Subject: [PATCH 8/8] Add `string::raw::from_buf` --- src/libcollections/str.rs | 18 ++--------- src/libcollections/string.rs | 48 ++++++++++++++++++++++-------- src/librustc/middle/trans/type_.rs | 7 +++-- src/librustuv/lib.rs | 6 ++-- src/libstd/os.rs | 3 +- 5 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 4219dc09d59ad..10f9ff05b8703 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -555,9 +555,6 @@ impl<'a> fmt::Show for MaybeOwned<'a> { /// Unsafe operations pub mod raw { - use core::mem; - use core::raw::Slice; - use core::ptr::RawPtr; use string; use string::String; use vec::Vec; @@ -571,19 +568,10 @@ pub mod raw { string::raw::from_buf_len(buf, len) } - /// Deprecated. Use `CString::as_str().unwrap().to_string()` - #[deprecated = "Use CString::as_str().unwrap().to_string()"] + /// Deprecated. Use `string::raw::from_buf` + #[deprecated = "Use string::raw::from_buf"] pub unsafe fn from_c_str(c_string: *const i8) -> String { - let mut buf = String::new(); - let mut len = 0; - while *c_string.offset(len) != 0 { - len += 1; - } - buf.push_bytes(mem::transmute(Slice { - data: c_string, - len: len as uint, - })); - buf + string::raw::from_buf(c_string as *const u8) } /// Deprecated. Replaced by `string::raw::from_utf8` diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 3e523d4fb57a6..3fe46c6282b98 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -61,7 +61,7 @@ impl String { #[inline] #[deprecated = "Replaced by string::raw::from_parts"] pub unsafe fn from_raw_parts(length: uint, capacity: uint, ptr: *mut u8) -> String { - raw::from_parts(length, capacity, ptr) + raw::from_parts(ptr, length, capacity) } #[allow(missing_doc)] @@ -571,6 +571,7 @@ impl Add for String { pub mod raw { use core::mem; + use core::ptr::RawPtr; use core::raw::Slice; use super::String; @@ -582,21 +583,13 @@ pub mod raw { /// * We call `Vec::from_raw_parts` to get a `Vec` /// * We assume that the `Vec` contains valid UTF-8 #[inline] - pub unsafe fn from_parts(length: uint, capacity: uint, ptr: *mut u8) -> String { + pub unsafe fn from_parts(buf: *mut u8, length: uint, capacity: uint) -> String { String { - vec: Vec::from_raw_parts(length, capacity, ptr), + vec: Vec::from_raw_parts(length, capacity, buf), } } - /// Converts a vector of bytes to a new `String` without checking if - /// it contains valid UTF-8. This is unsafe because it assumes that - /// the utf-8-ness of the vector has already been validated. - #[inline] - pub unsafe fn from_utf8(bytes: Vec) -> String { - String { vec: bytes } - } - - /// Create a Rust string from a *u8 buffer of the given length + /// Create `String` from a *u8 buffer of the given length /// /// This function is unsafe because of two reasons: /// * A raw pointer is dereferenced and transmuted to `&[u8]` @@ -609,6 +602,27 @@ pub mod raw { }); self::from_utf8(slice.to_vec()) } + + /// Create a `String` from a null-terminated *u8 buffer + /// + /// This function is unsafe because we dereference memory until we find the NUL character, + /// which is not guaranteed to be present. Additionaly, the slice is not checked to see + /// whether it contains valid UTF-8 + pub unsafe fn from_buf(buf: *const u8) -> String { + let mut len = 0; + while *buf.offset(len) != 0 { + len += 1; + } + self::from_buf_len(buf, len as uint) + } + + /// Converts a vector of bytes to a new `String` without checking if + /// it contains valid UTF-8. This is unsafe because it assumes that + /// the utf-8-ness of the vector has already been validated. + #[inline] + pub unsafe fn from_utf8(bytes: Vec) -> String { + String { vec: bytes } + } } #[cfg(test)] @@ -776,6 +790,16 @@ mod tests { } } + #[test] + fn test_from_buf() { + unsafe { + let a = vec![65, 65, 65, 65, 65, 65, 65, 0]; + let b = a.as_ptr(); + let c = super::raw::from_buf(b); + assert_eq!(c, String::from_str("AAAAAAA")); + } + } + #[test] fn test_push_bytes() { let mut s = String::from_str("ABC"); diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 3833d4cd0c854..e9d92e45f62d9 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -19,8 +19,9 @@ use middle::trans::context::CrateContext; use syntax::ast; use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel}; -use std::c_str::{CString, ToCStr}; +use std::c_str::ToCStr; use std::mem; +use std::string; use std::cell::RefCell; use std::collections::HashMap; @@ -333,7 +334,7 @@ impl TypeNames { pub fn type_to_string(&self, ty: Type) -> String { unsafe { let s = llvm::LLVMTypeToString(ty.to_ref()); - let ret = CString::new(s, false).as_str().unwrap().to_string(); + let ret = string::raw::from_buf(s as *const u8); free(s as *mut c_void); ret } @@ -347,7 +348,7 @@ impl TypeNames { pub fn val_to_string(&self, val: ValueRef) -> String { unsafe { let s = llvm::LLVMValueToString(val); - let ret = CString::new(s, false).as_str().unwrap().to_string(); + let ret = string::raw::from_buf(s as *const u8); free(s as *mut c_void); ret } diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs index dc43a68e64d09..4d23397cd383b 100644 --- a/src/librustuv/lib.rs +++ b/src/librustuv/lib.rs @@ -55,10 +55,10 @@ extern crate libc; extern crate alloc; use libc::{c_int, c_void}; -use std::c_str::CString; use std::fmt; use std::mem; use std::ptr; +use std::string; use std::rt::local::Local; use std::rt::rtio; use std::rt::rtio::{IoResult, IoError}; @@ -363,7 +363,7 @@ impl UvError { let inner = match self { &UvError(a) => a }; let name_str = uvll::uv_err_name(inner); assert!(name_str.is_not_null()); - CString::new(name_str, false).as_str().unwrap().to_string() + string::raw::from_buf(name_str as *const u8) } } @@ -372,7 +372,7 @@ impl UvError { let inner = match self { &UvError(a) => a }; let desc_str = uvll::uv_strerror(inner); assert!(desc_str.is_not_null()); - CString::new(desc_str, false).as_str().unwrap().to_string() + string::raw::from_buf(desc_str as *const u8) } } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 2cd69442b0154..ff99ec176d52d 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -49,7 +49,6 @@ use slice::{Vector, ImmutableVector, MutableVector, ImmutableEqVector}; use str::{Str, StrSlice, StrAllocating}; use string::String; use sync::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst}; -use to_string::ToString; use vec::Vec; #[cfg(unix)] @@ -998,7 +997,7 @@ pub fn error_string(errnum: uint) -> String { fail!("strerror_r failure"); } - ::c_str::CString::new(p as *const c_char, false).as_str().unwrap().to_string() + ::string::raw::from_buf(p as *const u8) } }