Skip to content

Commit 66bd753

Browse files
Darksonnojeda
authored andcommitted
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. Reviewed-by: Benno Lossin <[email protected]> Signed-off-by: Alice Ryhl <[email protected]> Reviewed-by: Martin Rodriguez Reboredo <[email protected]> Reviewed-by: Andreas Hindborg <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 4a59081 commit 66bd753

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

rust/kernel/str.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
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 {
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 {
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 {

0 commit comments

Comments
 (0)