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.
Showing the changes to rust/kernel (1 of 1 file). Show all
Unified · Split
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | //! String representations. |
| 4 | 4 | |
| 5 | +use alloc::alloc::AllocError; | |
| 5 | 6 | use alloc::vec::Vec; |
| 6 | 7 | use core::fmt::{self, Write}; |
| 7 | 8 | use core::ops::{self, Deref, Index}; |
| @@ -199,6 +200,12 @@ impl CStr { · 191 unmodified lines | ||
| 199 | 200 | pub unsafe fn as_str_unchecked(&self) -> &str { |
| 200 | 201 | unsafe { core::str::from_utf8_unchecked(self.as_bytes()) } |
| 201 | 202 | } |
| 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 | + } | |
| 202 | 209 | } |
| 203 | 210 | |
| 204 | 211 | impl fmt::Display for CStr { |
| @@ -584,6 +591,21 @@ impl Deref for CString { · 379 unmodified lines | ||
| 584 | 591 | } |
| 585 | 592 | } |
| 586 | 593 | |
| 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 | + | |
| 587 | 609 | /// A convenience alias for [`core::format_args`]. |
| 588 | 610 | #[macro_export] |
| 589 | 611 | macro_rules! fmt { |