use crate as libc; use crate::util; use crate::boxed::CBox; use core::slice; use core::ops::{Deref, DerefMut}; //pub struct FromBytesWithNulError {} pub struct CStr { inner: libc::c_char } impl CStr { #[inline] pub unsafe fn from_ptr_unchecked<'a>(p: *const libc::c_char) -> &'a CStr { &*p.cast() } #[inline] pub unsafe fn from_ptr<'a>(p: *const libc::c_char) -> &'a CStr { util::check_ptr(p, 1); CStr::from_ptr_unchecked(p) } #[inline] pub unsafe fn from_mut_ptr_unchecked<'a>(p: *mut libc::c_char) -> &'a mut CStr { &mut *p.cast() } #[inline] pub unsafe fn from_mut_ptr<'a>(p: *mut libc::c_char) -> &'a mut CStr { util::check_ptr(p, 1); CStr::from_mut_ptr_unchecked(p) } #[inline] pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr { CStr::from_ptr_unchecked(bytes.as_ptr().cast()) } // TODO //pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&CStr, FromBytesWithNulError> { //} #[inline] pub fn len(&self) -> usize { unsafe { libc::strlen(self.as_ptr()) as usize } } #[inline] pub const fn as_ptr(&self) -> *const libc::c_char { &self.inner } #[inline] pub fn as_mut_ptr(&mut self) -> *mut libc::c_char { &mut self.inner } #[inline] pub fn as_bytes(&self) -> &[u8] { unsafe { slice::from_raw_parts( self.as_ptr().cast(), self.len(), ) } } #[inline] pub fn as_mut_bytes(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut( self.as_mut_ptr().cast(), self.len(), ) } } #[inline] pub fn to_owned(self: &CStr) -> CString { CString::from(self) } } #[macro_export] macro_rules! cstr { ($s:expr) => ( unsafe { $crate::string::CStr::from_bytes_with_nul_unchecked(concat!($s, "\0").as_bytes()) } ) } pub struct CString { inner: CBox } impl CString { #[inline] pub unsafe fn from_raw_unchecked(p: *mut libc::c_char) -> CString { CString { inner: CBox::from_raw_unchecked(p) } } #[inline] pub unsafe fn from_raw(p: *mut libc::c_char) -> CString { util::check_ptr(p, 1); CString::from_raw_unchecked(p) } #[inline] pub fn into_raw(self) -> *mut libc::c_char { self.inner.into_raw() } } impl Deref for CString { type Target = CStr; #[inline] fn deref(&self) -> &CStr { unsafe { CStr::from_ptr(&*self.inner) } } } impl DerefMut for CString { #[inline] fn deref_mut(&mut self) -> &mut CStr { unsafe { CStr::from_mut_ptr(&mut *self.inner) } } } impl From<&[u8]> for CString { fn from(s: &[u8]) -> CString { unsafe { CString::from_raw_unchecked( util::must_succeed(libc::strndup( s.as_ptr().cast(), s.len() as libc::size_t, )) ) } } } impl From<&str> for CString { #[inline] fn from(s: &str) -> CString { CString::from(s.as_bytes()) } } impl From<&CStr> for CString { #[inline] fn from(s: &CStr) -> CString { unsafe { CString::from_raw_unchecked(util::must_succeed(libc::strdup(s.as_ptr()))) } } }