Add missing links for CStr and CString

This commit is contained in:
Guillaume Gomez 2017-05-22 16:55:00 +02:00
parent 81734e0e06
commit 819acb5141

View File

@ -23,18 +23,20 @@ use ptr;
use slice; use slice;
use str::{self, Utf8Error}; use str::{self, Utf8Error};
/// A type representing an owned C-compatible string /// A type representing an owned C-compatible string.
/// ///
/// This type serves the primary purpose of being able to safely generate a /// This type serves the primary purpose of being able to safely generate a
/// C-compatible string from a Rust byte slice or vector. An instance of this /// C-compatible string from a Rust byte slice or vector. An instance of this
/// type is a static guarantee that the underlying bytes contain no interior 0 /// type is a static guarantee that the underlying bytes contain no interior 0
/// bytes and the final byte is 0. /// bytes and the final byte is 0.
/// ///
/// A `CString` is created from either a byte slice or a byte vector. A `u8` /// A `CString` is created from either a byte slice or a byte vector. A [`u8`]
/// slice can be obtained with the `as_bytes` method. Slices produced from a /// slice can be obtained with the `as_bytes` method. Slices produced from a
/// `CString` do *not* contain the trailing nul terminator unless otherwise /// `CString` do *not* contain the trailing nul terminator unless otherwise
/// specified. /// specified.
/// ///
/// [`u8`]: ../primitive.u8.html
///
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
@ -81,12 +83,14 @@ pub struct CString {
/// ///
/// Note that this structure is **not** `repr(C)` and is not recommended to be /// Note that this structure is **not** `repr(C)` and is not recommended to be
/// placed in the signatures of FFI functions. Instead safe wrappers of FFI /// placed in the signatures of FFI functions. Instead safe wrappers of FFI
/// functions may leverage the unsafe `from_ptr` constructor to provide a safe /// functions may leverage the unsafe [`from_ptr`] constructor to provide a safe
/// interface to other consumers. /// interface to other consumers.
/// ///
/// [`from_ptr`]: #method.from_ptr
///
/// # Examples /// # Examples
/// ///
/// Inspecting a foreign C string /// Inspecting a foreign C string:
/// ///
/// ```no_run /// ```no_run
/// use std::ffi::CStr; /// use std::ffi::CStr;
@ -100,7 +104,7 @@ pub struct CString {
/// } /// }
/// ``` /// ```
/// ///
/// Passing a Rust-originating C string /// Passing a Rust-originating C string:
/// ///
/// ```no_run /// ```no_run
/// use std::ffi::{CString, CStr}; /// use std::ffi::{CString, CStr};
@ -116,7 +120,9 @@ pub struct CString {
/// work(&s); /// work(&s);
/// ``` /// ```
/// ///
/// Converting a foreign C string into a Rust `String` /// Converting a foreign C string into a Rust [`String`]:
///
/// [`String`]: ../string/struct.String.html
/// ///
/// ```no_run /// ```no_run
/// use std::ffi::CStr; /// use std::ffi::CStr;
@ -142,14 +148,18 @@ pub struct CStr {
inner: [c_char] inner: [c_char]
} }
/// An error returned from `CString::new` to indicate that a nul byte was found /// An error returned from [`CString::new`] to indicate that a nul byte was found
/// in the vector provided. /// in the vector provided.
///
/// [`CString::new`]: struct.CString.html#method.new
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct NulError(usize, Vec<u8>); pub struct NulError(usize, Vec<u8>);
/// An error returned from `CStr::from_bytes_with_nul` to indicate that a nul /// An error returned from [`CStr::from_bytes_with_nul`] to indicate that a nul
/// byte was found too early in the slice provided or one wasn't found at all. /// byte was found too early in the slice provided or one wasn't found at all.
///
/// [`CStr::from_bytes_with_nul`]: struct.CStr.html#method.from_bytes_with_nul
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "cstr_from_bytes", since = "1.10.0")] #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
pub struct FromBytesWithNulError { pub struct FromBytesWithNulError {
@ -175,8 +185,10 @@ impl FromBytesWithNulError {
} }
} }
/// An error returned from `CString::into_string` to indicate that a UTF-8 error /// An error returned from [`CString::into_string`] to indicate that a UTF-8 error
/// was encountered during the conversion. /// was encountered during the conversion.
///
/// [`CString::into_string`]: struct.CString.html#method.into_string
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "cstring_into", since = "1.7.0")] #[stable(feature = "cstring_into", since = "1.7.0")]
pub struct IntoStringError { pub struct IntoStringError {
@ -224,10 +236,12 @@ impl CString {
/// Creates a C-compatible string from a byte vector without checking for /// Creates a C-compatible string from a byte vector without checking for
/// interior 0 bytes. /// interior 0 bytes.
/// ///
/// This method is equivalent to `new` except that no runtime assertion /// This method is equivalent to [`new`] except that no runtime assertion
/// is made that `v` contains no 0 bytes, and it requires an actual /// is made that `v` contains no 0 bytes, and it requires an actual
/// byte vector, not anything that can be converted to one with Into. /// byte vector, not anything that can be converted to one with Into.
/// ///
/// [`new`]: #method.new
///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
@ -252,9 +266,11 @@ impl CString {
/// # Safety /// # Safety
/// ///
/// This should only ever be called with a pointer that was earlier /// This should only ever be called with a pointer that was earlier
/// obtained by calling `into_raw` on a `CString`. Other usage (e.g. trying to take /// obtained by calling [`into_raw`] on a `CString`. Other usage (e.g. trying to take
/// ownership of a string that was allocated by foreign code) is likely to lead /// ownership of a string that was allocated by foreign code) is likely to lead
/// to undefined behavior or allocator corruption. /// to undefined behavior or allocator corruption.
///
/// [`into_raw`]: #method.into_raw
#[stable(feature = "cstr_memory", since = "1.4.0")] #[stable(feature = "cstr_memory", since = "1.4.0")]
pub unsafe fn from_raw(ptr: *mut c_char) -> CString { pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
let len = libc::strlen(ptr) + 1; // Including the NUL byte let len = libc::strlen(ptr) + 1; // Including the NUL byte
@ -265,19 +281,23 @@ impl CString {
/// Transfers ownership of the string to a C caller. /// Transfers ownership of the string to a C caller.
/// ///
/// The pointer must be returned to Rust and reconstituted using /// The pointer must be returned to Rust and reconstituted using
/// `from_raw` to be properly deallocated. Specifically, one /// [`from_raw`] to be properly deallocated. Specifically, one
/// should *not* use the standard C `free` function to deallocate /// should *not* use the standard C `free` function to deallocate
/// this string. /// this string.
/// ///
/// Failure to call `from_raw` will lead to a memory leak. /// Failure to call [`from_raw`] will lead to a memory leak.
///
/// [`from_raw`]: #method.from_raw
#[stable(feature = "cstr_memory", since = "1.4.0")] #[stable(feature = "cstr_memory", since = "1.4.0")]
pub fn into_raw(self) -> *mut c_char { pub fn into_raw(self) -> *mut c_char {
Box::into_raw(self.into_inner()) as *mut c_char Box::into_raw(self.into_inner()) as *mut c_char
} }
/// Converts the `CString` into a `String` if it contains valid Unicode data. /// Converts the `CString` into a [`String`] if it contains valid Unicode data.
/// ///
/// On failure, ownership of the original `CString` is returned. /// On failure, ownership of the original `CString` is returned.
///
/// [`String`]: ../string/struct.String.html
#[stable(feature = "cstring_into", since = "1.7.0")] #[stable(feature = "cstring_into", since = "1.7.0")]
pub fn into_string(self) -> Result<String, IntoStringError> { pub fn into_string(self) -> Result<String, IntoStringError> {
String::from_utf8(self.into_bytes()) String::from_utf8(self.into_bytes())
@ -299,8 +319,10 @@ impl CString {
vec vec
} }
/// Equivalent to the `into_bytes` function except that the returned vector /// Equivalent to the [`into_bytes`] function except that the returned vector
/// includes the trailing nul byte. /// includes the trailing nul byte.
///
/// [`into_bytes`]: #method.into_bytes
#[stable(feature = "cstring_into", since = "1.7.0")] #[stable(feature = "cstring_into", since = "1.7.0")]
pub fn into_bytes_with_nul(self) -> Vec<u8> { pub fn into_bytes_with_nul(self) -> Vec<u8> {
self.into_inner().into_vec() self.into_inner().into_vec()
@ -315,26 +337,34 @@ impl CString {
&self.inner[..self.inner.len() - 1] &self.inner[..self.inner.len() - 1]
} }
/// Equivalent to the `as_bytes` function except that the returned slice /// Equivalent to the [`as_bytes`] function except that the returned slice
/// includes the trailing nul byte. /// includes the trailing nul byte.
///
/// [`as_bytes`]: #method.as_bytes
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn as_bytes_with_nul(&self) -> &[u8] { pub fn as_bytes_with_nul(&self) -> &[u8] {
&self.inner &self.inner
} }
/// Extracts a `CStr` slice containing the entire string. /// Extracts a [`CStr`] slice containing the entire string.
///
/// [`CStr`]: struct.CStr.html
#[unstable(feature = "as_c_str", issue = "40380")] #[unstable(feature = "as_c_str", issue = "40380")]
pub fn as_c_str(&self) -> &CStr { pub fn as_c_str(&self) -> &CStr {
&*self &*self
} }
/// Converts this `CString` into a boxed `CStr`. /// Converts this `CString` into a boxed [`CStr`].
///
/// [`CStr`]: struct.CStr.html
#[unstable(feature = "into_boxed_c_str", issue = "40380")] #[unstable(feature = "into_boxed_c_str", issue = "40380")]
pub fn into_boxed_c_str(self) -> Box<CStr> { pub fn into_boxed_c_str(self) -> Box<CStr> {
unsafe { mem::transmute(self.into_inner()) } unsafe { mem::transmute(self.into_inner()) }
} }
// Bypass "move out of struct which implements `Drop` trait" restriction. // Bypass "move out of struct which implements [`Drop`] trait" restriction.
///
/// [`Drop`]: ../ops/trait.Drop.html
fn into_inner(self) -> Box<[u8]> { fn into_inner(self) -> Box<[u8]> {
unsafe { unsafe {
let result = ptr::read(&self.inner); let result = ptr::read(&self.inner);
@ -443,7 +473,9 @@ impl Default for Box<CStr> {
impl NulError { impl NulError {
/// Returns the position of the nul byte in the slice that was provided to /// Returns the position of the nul byte in the slice that was provided to
/// `CString::new`. /// [`CString::new`].
///
/// [`CString::new`]: struct.CString.html#method.new
/// ///
/// # Examples /// # Examples
/// ///
@ -518,8 +550,10 @@ impl fmt::Display for FromBytesWithNulError {
} }
impl IntoStringError { impl IntoStringError {
/// Consumes this error, returning original `CString` which generated the /// Consumes this error, returning original [`CString`] which generated the
/// error. /// error.
///
/// [`CString`]: struct.CString.html
#[stable(feature = "cstring_into", since = "1.7.0")] #[stable(feature = "cstring_into", since = "1.7.0")]
pub fn into_cstring(self) -> CString { pub fn into_cstring(self) -> CString {
self.inner self.inner
@ -557,9 +591,9 @@ impl CStr {
/// allows inspection and interoperation of non-owned C strings. This method /// allows inspection and interoperation of non-owned C strings. This method
/// is unsafe for a number of reasons: /// is unsafe for a number of reasons:
/// ///
/// * There is no guarantee to the validity of `ptr` /// * There is no guarantee to the validity of `ptr`.
/// * The returned lifetime is not guaranteed to be the actual lifetime of /// * The returned lifetime is not guaranteed to be the actual lifetime of
/// `ptr` /// `ptr`.
/// * There is no guarantee that the memory pointed to by `ptr` contains a /// * There is no guarantee that the memory pointed to by `ptr` contains a
/// valid nul terminator byte at the end of the string. /// valid nul terminator byte at the end of the string.
/// ///
@ -703,26 +737,30 @@ impl CStr {
/// Converts this C string to a byte slice containing the trailing 0 byte. /// Converts this C string to a byte slice containing the trailing 0 byte.
/// ///
/// This function is the equivalent of `to_bytes` except that it will retain /// This function is the equivalent of [`to_bytes`] except that it will retain
/// the trailing nul instead of chopping it off. /// the trailing nul instead of chopping it off.
/// ///
/// > **Note**: This method is currently implemented as a 0-cost cast, but /// > **Note**: This method is currently implemented as a 0-cost cast, but
/// > it is planned to alter its definition in the future to perform the /// > it is planned to alter its definition in the future to perform the
/// > length calculation whenever this method is called. /// > length calculation whenever this method is called.
///
/// [`to_bytes`]: #method.to_bytes
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn to_bytes_with_nul(&self) -> &[u8] { pub fn to_bytes_with_nul(&self) -> &[u8] {
unsafe { mem::transmute(&self.inner) } unsafe { mem::transmute(&self.inner) }
} }
/// Yields a `&str` slice if the `CStr` contains valid UTF-8. /// Yields a [`&str`] slice if the `CStr` contains valid UTF-8.
/// ///
/// This function will calculate the length of this string and check for /// This function will calculate the length of this string and check for
/// UTF-8 validity, and then return the `&str` if it's valid. /// UTF-8 validity, and then return the [`&str`] if it's valid.
/// ///
/// > **Note**: This method is currently implemented to check for validity /// > **Note**: This method is currently implemented to check for validity
/// > after a 0-cost cast, but it is planned to alter its definition in the /// > after a 0-cost cast, but it is planned to alter its definition in the
/// > future to perform the length calculation in addition to the UTF-8 /// > future to perform the length calculation in addition to the UTF-8
/// > check whenever this method is called. /// > check whenever this method is called.
///
/// [`&str`]: ../primitive.str.html
#[stable(feature = "cstr_to_str", since = "1.4.0")] #[stable(feature = "cstr_to_str", since = "1.4.0")]
pub fn to_str(&self) -> Result<&str, str::Utf8Error> { pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
// NB: When CStr is changed to perform the length check in .to_bytes() // NB: When CStr is changed to perform the length check in .to_bytes()
@ -732,23 +770,29 @@ impl CStr {
str::from_utf8(self.to_bytes()) str::from_utf8(self.to_bytes())
} }
/// Converts a `CStr` into a `Cow<str>`. /// Converts a `CStr` into a [`Cow`]`<`[`str`]`>`.
/// ///
/// This function will calculate the length of this string (which normally /// This function will calculate the length of this string (which normally
/// requires a linear amount of work to be done) and then return the /// requires a linear amount of work to be done) and then return the
/// resulting slice as a `Cow<str>`, replacing any invalid UTF-8 sequences /// resulting slice as a [`Cow`]`<`[`str`]`>`, replacing any invalid UTF-8 sequences
/// with `U+FFFD REPLACEMENT CHARACTER`. /// with `U+FFFD REPLACEMENT CHARACTER`.
/// ///
/// > **Note**: This method is currently implemented to check for validity /// > **Note**: This method is currently implemented to check for validity
/// > after a 0-cost cast, but it is planned to alter its definition in the /// > after a 0-cost cast, but it is planned to alter its definition in the
/// > future to perform the length calculation in addition to the UTF-8 /// > future to perform the length calculation in addition to the UTF-8
/// > check whenever this method is called. /// > check whenever this method is called.
///
/// [`Cow`]: ../borrow/enum.Cow.html
/// [`str`]: ../primitive.str.html
#[stable(feature = "cstr_to_str", since = "1.4.0")] #[stable(feature = "cstr_to_str", since = "1.4.0")]
pub fn to_string_lossy(&self) -> Cow<str> { pub fn to_string_lossy(&self) -> Cow<str> {
String::from_utf8_lossy(self.to_bytes()) String::from_utf8_lossy(self.to_bytes())
} }
/// Converts a `Box<CStr>` into a `CString` without copying or allocating. /// Converts a [`Box`]`<CStr>` into a [`CString`] without copying or allocating.
///
/// [`Box`]: ../boxed/struct.Box.html
/// [`CString`]: struct.CString.html
#[unstable(feature = "into_boxed_c_str", issue = "40380")] #[unstable(feature = "into_boxed_c_str", issue = "40380")]
pub fn into_c_string(self: Box<CStr>) -> CString { pub fn into_c_string(self: Box<CStr>) -> CString {
unsafe { mem::transmute(self) } unsafe { mem::transmute(self) }