Skip to content

Commit 0bd6caa

Browse files
committed
Add string::raw::from_buf
1 parent 604274d commit 0bd6caa

File tree

5 files changed

+47
-35
lines changed

5 files changed

+47
-35
lines changed

src/libcollections/str.rs

+3-15
Original file line numberDiff line numberDiff line change
@@ -555,9 +555,6 @@ impl<'a> fmt::Show for MaybeOwned<'a> {
555555

556556
/// Unsafe operations
557557
pub mod raw {
558-
use core::mem;
559-
use core::raw::Slice;
560-
use core::ptr::RawPtr;
561558
use string;
562559
use string::String;
563560
use vec::Vec;
@@ -571,19 +568,10 @@ pub mod raw {
571568
string::raw::from_buf_len(buf, len)
572569
}
573570

574-
/// Deprecated. Use `CString::as_str().unwrap().to_string()`
575-
#[deprecated = "Use CString::as_str().unwrap().to_string()"]
571+
/// Deprecated. Use `string::raw::from_buf`
572+
#[deprecated = "Use string::raw::from_buf"]
576573
pub unsafe fn from_c_str(c_string: *const i8) -> String {
577-
let mut buf = String::new();
578-
let mut len = 0;
579-
while *c_string.offset(len) != 0 {
580-
len += 1;
581-
}
582-
buf.push_bytes(mem::transmute(Slice {
583-
data: c_string,
584-
len: len as uint,
585-
}));
586-
buf
574+
string::raw::from_buf(c_string as *const u8)
587575
}
588576

589577
/// Deprecated. Replaced by `string::raw::from_utf8`

src/libcollections/string.rs

+36-12
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl String {
6161
#[inline]
6262
#[deprecated = "Replaced by string::raw::from_parts"]
6363
pub unsafe fn from_raw_parts(length: uint, capacity: uint, ptr: *mut u8) -> String {
64-
raw::from_parts(length, capacity, ptr)
64+
raw::from_parts(ptr, length, capacity)
6565
}
6666

6767
#[allow(missing_doc)]
@@ -571,6 +571,7 @@ impl<S: Str> Add<S, String> for String {
571571

572572
pub mod raw {
573573
use core::mem;
574+
use core::ptr::RawPtr;
574575
use core::raw::Slice;
575576

576577
use super::String;
@@ -582,21 +583,13 @@ pub mod raw {
582583
/// * We call `Vec::from_raw_parts` to get a `Vec<u8>`
583584
/// * We assume that the `Vec` contains valid UTF-8
584585
#[inline]
585-
pub unsafe fn from_parts(length: uint, capacity: uint, ptr: *mut u8) -> String {
586+
pub unsafe fn from_parts(buf: *mut u8, length: uint, capacity: uint) -> String {
586587
String {
587-
vec: Vec::from_raw_parts(length, capacity, ptr),
588+
vec: Vec::from_raw_parts(length, capacity, buf),
588589
}
589590
}
590591

591-
/// Converts a vector of bytes to a new `String` without checking if
592-
/// it contains valid UTF-8. This is unsafe because it assumes that
593-
/// the utf-8-ness of the vector has already been validated.
594-
#[inline]
595-
pub unsafe fn from_utf8(bytes: Vec<u8>) -> String {
596-
String { vec: bytes }
597-
}
598-
599-
/// Create a Rust string from a *u8 buffer of the given length
592+
/// Create `String` from a *u8 buffer of the given length
600593
///
601594
/// This function is unsafe because of two reasons:
602595
/// * A raw pointer is dereferenced and transmuted to `&[u8]`
@@ -609,6 +602,27 @@ pub mod raw {
609602
});
610603
self::from_utf8(slice.to_vec())
611604
}
605+
606+
/// Create a `String` from a null-terminated *u8 buffer
607+
///
608+
/// This function is unsafe because we dereference memory until we find the NUL character,
609+
/// which is not guaranteed to be present. Additionaly, the slice is not checked to see
610+
/// whether it contains valid UTF-8
611+
pub unsafe fn from_buf(buf: *const u8) -> String {
612+
let mut len = 0;
613+
while *buf.offset(len) != 0 {
614+
len += 1;
615+
}
616+
self::from_buf_len(buf, len as uint)
617+
}
618+
619+
/// Converts a vector of bytes to a new `String` without checking if
620+
/// it contains valid UTF-8. This is unsafe because it assumes that
621+
/// the utf-8-ness of the vector has already been validated.
622+
#[inline]
623+
pub unsafe fn from_utf8(bytes: Vec<u8>) -> String {
624+
String { vec: bytes }
625+
}
612626
}
613627

614628
#[cfg(test)]
@@ -776,6 +790,16 @@ mod tests {
776790
}
777791
}
778792

793+
#[test]
794+
fn test_from_buf() {
795+
unsafe {
796+
let a = vec![65, 65, 65, 65, 65, 65, 65, 0];
797+
let b = a.as_ptr();
798+
let c = super::raw::from_buf(b);
799+
assert_eq!(c, String::from_str("AAAAAAA"));
800+
}
801+
}
802+
779803
#[test]
780804
fn test_push_bytes() {
781805
let mut s = String::from_str("ABC");

src/librustc/middle/trans/type_.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ use middle::trans::context::CrateContext;
1919
use syntax::ast;
2020
use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel};
2121

22-
use std::c_str::{CString, ToCStr};
22+
use std::c_str::ToCStr;
2323
use std::mem;
24+
use std::string;
2425
use std::cell::RefCell;
2526
use std::collections::HashMap;
2627

@@ -333,7 +334,7 @@ impl TypeNames {
333334
pub fn type_to_string(&self, ty: Type) -> String {
334335
unsafe {
335336
let s = llvm::LLVMTypeToString(ty.to_ref());
336-
let ret = CString::new(s, false).as_str().unwrap().to_string();
337+
let ret = string::raw::from_buf(s as *const u8);
337338
free(s as *mut c_void);
338339
ret
339340
}
@@ -347,7 +348,7 @@ impl TypeNames {
347348
pub fn val_to_string(&self, val: ValueRef) -> String {
348349
unsafe {
349350
let s = llvm::LLVMValueToString(val);
350-
let ret = CString::new(s, false).as_str().unwrap().to_string();
351+
let ret = string::raw::from_buf(s as *const u8);
351352
free(s as *mut c_void);
352353
ret
353354
}

src/librustuv/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ extern crate libc;
5555
extern crate alloc;
5656

5757
use libc::{c_int, c_void};
58-
use std::c_str::CString;
5958
use std::fmt;
6059
use std::mem;
6160
use std::ptr;
61+
use std::string;
6262
use std::rt::local::Local;
6363
use std::rt::rtio;
6464
use std::rt::rtio::{IoResult, IoError};
@@ -363,7 +363,7 @@ impl UvError {
363363
let inner = match self { &UvError(a) => a };
364364
let name_str = uvll::uv_err_name(inner);
365365
assert!(name_str.is_not_null());
366-
CString::new(name_str, false).as_str().unwrap().to_string()
366+
string::raw::from_buf(name_str as *const u8)
367367
}
368368
}
369369

@@ -372,7 +372,7 @@ impl UvError {
372372
let inner = match self { &UvError(a) => a };
373373
let desc_str = uvll::uv_strerror(inner);
374374
assert!(desc_str.is_not_null());
375-
CString::new(desc_str, false).as_str().unwrap().to_string()
375+
string::raw::from_buf(desc_str as *const u8)
376376
}
377377
}
378378

src/libstd/os.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ use slice::{Vector, ImmutableVector, MutableVector, ImmutableEqVector};
4949
use str::{Str, StrSlice, StrAllocating};
5050
use string::String;
5151
use sync::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
52-
use to_string::ToString;
5352
use vec::Vec;
5453

5554
#[cfg(unix)]
@@ -998,7 +997,7 @@ pub fn error_string(errnum: uint) -> String {
998997
fail!("strerror_r failure");
999998
}
1000999

1001-
::c_str::CString::new(p as *const c_char, false).as_str().unwrap().to_string()
1000+
::string::raw::from_buf(p as *const u8)
10021001
}
10031002
}
10041003

0 commit comments

Comments
 (0)