Add string::raw::from_buf

This commit is contained in:
Adolfo Ochagavía 2014-07-22 17:55:12 +02:00 committed by Alex Crichton
parent 684479ab91
commit 75a0062d88
5 changed files with 47 additions and 35 deletions

View File

@ -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;
@ -573,19 +570,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`

View File

@ -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<S: Str> Add<S, String> 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<u8>`
/// * 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<u8>) -> 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<u8>) -> 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");

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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)
}
}