History

rust: str: add conversion from `CStr` to `CString`

These methods can be used to copy the data in a temporary c string into a separate allocation, so that it can be accessed later even if the original is deallocated. The API in this change mirrors the standard library API for the `&str` and `String` types. The `ToOwned` trait is not implemented because it assumes that allocations are infallible.

Alice Ryhl committed 3 years ago

Commit 66bd7531 parent 4a590811 file · +22 −0Browse files

Unified · Split

rust/kernel/str.rs+22−0
@@ -2,6 +2,7 @@ · 1 unmodified line
22
33 //! String representations.
44
5+use alloc::alloc::AllocError;
56 use alloc::vec::Vec;
67 use core::fmt::{self, Write};
78 use core::ops::{self, Deref, Index};
@@ -199,6 +200,12 @@ impl CStr { · 191 unmodified lines
199200 pub unsafe fn as_str_unchecked(&self) -> &str {
200201 unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
201202 }
203+
204+ /// Convert this [`CStr`] into a [`CString`] by allocating memory and
205+ /// copying over the string data.
206+ pub fn to_cstring(&self) -> Result<CString, AllocError> {
207+ CString::try_from(self)
208+ }
202209 }
203210
204211 impl fmt::Display for CStr {
@@ -584,6 +591,21 @@ impl Deref for CString { · 379 unmodified lines
584591 }
585592 }
586593
594+impl<'a> TryFrom<&'a CStr> for CString {
595+ type Error = AllocError;
596+
597+ fn try_from(cstr: &'a CStr) -> Result<CString, AllocError> {
598+ let mut buf = Vec::new();
599+
600+ buf.try_extend_from_slice(cstr.as_bytes_with_nul())
601+ .map_err(|_| AllocError)?;
602+
603+ // INVARIANT: The `CStr` and `CString` types have the same invariants for
604+ // the string data, and we copied it over without changes.
605+ Ok(CString { buf })
606+ }
607+}
608+
587609 /// A convenience alias for [`core::format_args`].
588610 #[macro_export]
589611 macro_rules! fmt {