151 lines
2.9 KiB
Rust
151 lines
2.9 KiB
Rust
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 as *const CStr)
|
|
}
|
|
|
|
#[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 as *mut CStr)
|
|
}
|
|
|
|
#[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() as *const libc::c_char)
|
|
}
|
|
|
|
// 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() as *const u8,
|
|
self.len(),
|
|
) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn as_mut_bytes(&mut self) -> &mut [u8] {
|
|
unsafe { slice::from_raw_parts_mut(
|
|
self.as_mut_ptr() as *mut u8,
|
|
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<libc::c_char> }
|
|
|
|
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() as *const libc::c_char,
|
|
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())))
|
|
}
|
|
}
|
|
}
|