[−][src]Struct abistr::CStrBuf
CStrBuf<[u8; 128]>
is ABI compatible with [c_char; 128]
.
Safety
There is no guarantee the underlying buffer is \0
terminated, and no reasonable way to create such a guarantee
when the type is used in raw C structure FFI - the underlying C code might not \0
-terminate the buffer, and you
could immediately pass the structure to another C fn without calling a single sanitization function.
If wrapping a C fn that takes a buffer-laden structure as input, you are strongly encouraged to call either
CStrBuf::nul_truncate
, or CStrBuf::validate
(and error out on any NotNulTerminatedError
s) in your safe
fn before passing it to C. Not doing so is almost certain to lead to undefined behavior, although there are some
exceptions where the buffer is not expected to be nul terminated (e.g. some magic marker strings in file headers, as
an example.)
You could also write some gnarly malicious AsRef
/AsMut
impls for B
that e.g. return different buffers when
called multiple times. While I believe I've guarded against unsoundness, such types would likely break guarantees
that you might otherwise rely on for FFI. So... don't.
Implementations
impl<B: AsRef<[u8]> + AsMut<[u8]> + Default> CStrBuf<B>
[src]
pub fn from_truncate(data: &impl AsRef<[u8]> + ?Sized) -> Self
[src]
Create a CStrBuf
from data
+ \0
. Will be truncated (with the \0
) to fit if data
is too long.
Panics
If self.buffer.as_mut().is_empty()
(...did you create a CStrBuf<[u8; 0]>
or something? Weirdo.)
pub unsafe fn from_truncate_without_nul(
data: &impl AsRef<[u8]> + ?Sized
) -> Self
[src]
data: &impl AsRef<[u8]> + ?Sized
) -> Self
Create a CStrBuf
from data
+ \0
. Will be truncated to fit if data
is too long. Not guaranteed to be \0
-terminated!
pub fn try_from(
data: &impl AsRef<[u8]> + ?Sized
) -> Result<Self, BufferTooSmallError>
[src]
data: &impl AsRef<[u8]> + ?Sized
) -> Result<Self, BufferTooSmallError>
Create a CStrBuf
from data
+ \0
.
pub unsafe fn try_from_without_nul(
data: &impl AsRef<[u8]> + ?Sized
) -> Result<Self, BufferTooSmallError>
[src]
data: &impl AsRef<[u8]> + ?Sized
) -> Result<Self, BufferTooSmallError>
Create a CStrBuf
from data
+ \0
. Will succeed even if the \0
doesn't fit.
impl<B: AsRef<[u8]>> CStrBuf<B>
[src]
pub fn buffer(&self) -> &[u8]
[src]
Access the underlying byte buffer of self
pub fn is_empty(&self) -> bool
[src]
Checks if self
is empty (e.g. the first character is \0
.)
pub fn to_bytes(&self) -> &[u8]
[src]
Get the bytes of the string portion of the buffer. This will not contain any \0
characters, and is not guaranteed to have a \0
after the slice!
O(n)
to locate the terminal \0
.
pub fn to_bytes_with_nul(&self) -> Result<&[u8], NotNulTerminatedError>
[src]
Get the bytes of the string portion of the buffer, including the terminal \0
.
Since the buffer might not contain a terminal \0
, this may fail.
You might prefer to_bytes
, which cannot fail.
O(n)
to locate the terminal \0
.
pub fn to_cstr(&self) -> Result<&CStr, NotNulTerminatedError>
[src]
Attempt to convert the buffer to a CStr
, returning Err(NotNulTerminatedError)
instead if the underlying buffer isn't \0
-terminated.
You might prefer to_string_lossy
, which cannot fail, or to_str
, which can fail due to invalid UTF8, but not due to missing \0
s.
O(n)
to locate the terminal \0
.
pub fn to_str(&self) -> Result<&str, Utf8Error>
[src]
Attempt to convert the buffer to a &str
, returning Err(Utf8Error)
instead if the underlying buffer wasn't valid UTF8.
O(n)
to locate the terminal \0
.
pub fn to_string_lossy(&self) -> Cow<'_, str>
[src]
Convert the buffer to a &str
, allocating and replacing invalid UTF8 with U+FFFD REPLACEMENT CHARACTER
if necessary.
O(n)
to locate the terminal \0
.
pub fn validate(&self) -> Result<(), NotNulTerminatedError>
[src]
Ensure the buffer is \0
-terminated, returning Err(NotNulTerminatedError)
otherwise.
O(n)
to locate the terminal \0
.
impl<B: AsMut<[u8]>> CStrBuf<B>
[src]
pub unsafe fn buffer_mut(&mut self) -> &mut [u8]
[src]
Access the underlying byte buffer of self
.
Safety
Many C APIs assume the underlying buffer is \0
-terminated, and this method would let you change that.
However, it's worth noting that CStrBuf
technically makes no such guarantee!
pub fn nul_truncate(&mut self) -> CStrNonNull<'_>
[src]
Ensure the buffer is \0
-terminated by setting the last character to be \0
.
Panics
If self.buffer.as_mut().is_empty()
(...did you create a CStrBuf<[u8; 0]>
or something? Weirdo.)
pub fn set_truncate(
&mut self,
data: &impl AsRef<[u8]> + ?Sized
) -> Result<(), BufferTooSmallError>
[src]
&mut self,
data: &impl AsRef<[u8]> + ?Sized
) -> Result<(), BufferTooSmallError>
Modifies the buffer to contain data
+ \0
.
If data
will not fit, it will be truncated with a final \0
before returning Err(BufferTooSmallError)
.
Panics
If self.buffer.as_mut().is_empty()
(...did you create a CStrBuf<[u8; 0]>
or something? Weirdo.)
pub unsafe fn set_truncate_without_nul(
&mut self,
data: &impl AsRef<[u8]> + ?Sized
) -> Result<(), BufferTooSmallError>
[src]
&mut self,
data: &impl AsRef<[u8]> + ?Sized
) -> Result<(), BufferTooSmallError>
Modifies the buffer to contain data
+ \0
.
If data
will not fit, it will be truncated - without a final \0
- before returning Err(BufferTooSmallError)
.
pub fn try_set(
&mut self,
data: &impl AsRef<[u8]> + ?Sized
) -> Result<(), BufferTooSmallError>
[src]
&mut self,
data: &impl AsRef<[u8]> + ?Sized
) -> Result<(), BufferTooSmallError>
Modifies the buffer to contain data
+ \0
.
If data
+ '\0' will not fit, Err(BufferTooSmallError)
will be returned without modifying the underlying buffer.
pub unsafe fn try_set_without_nul(
&mut self,
data: &impl AsRef<[u8]> + ?Sized
) -> Result<(), BufferTooSmallError>
[src]
&mut self,
data: &impl AsRef<[u8]> + ?Sized
) -> Result<(), BufferTooSmallError>
Modifies the buffer to contain data
(and a \0
- but only if it will fit!)
If data
will not fit, Err(BufferTooSmallError)
will be returned without modifying the underlying buffer.
Trait Implementations
impl<B: Clone> Clone for CStrBuf<B>
[src]
impl<B: Copy> Copy for CStrBuf<B>
[src]
impl<B: AsRef<[u8]>> Debug for CStrBuf<B>
[src]
impl<B: Default> Default for CStrBuf<B>
[src]
impl<B: Eq> Eq for CStrBuf<B>
[src]
impl<B: Hash> Hash for CStrBuf<B>
[src]
pub fn hash<__H: Hasher>(&self, state: &mut __H)
[src]
pub fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
1.3.0[src]
H: Hasher,
impl<B: Ord> Ord for CStrBuf<B>
[src]
pub fn cmp(&self, other: &CStrBuf<B>) -> Ordering
[src]
#[must_use]pub fn max(self, other: Self) -> Self
1.21.0[src]
#[must_use]pub fn min(self, other: Self) -> Self
1.21.0[src]
#[must_use]pub fn clamp(self, min: Self, max: Self) -> Self
1.50.0[src]
impl<B: PartialEq> PartialEq<CStrBuf<B>> for CStrBuf<B>
[src]
impl<B: PartialOrd> PartialOrd<CStrBuf<B>> for CStrBuf<B>
[src]
pub fn partial_cmp(&self, other: &CStrBuf<B>) -> Option<Ordering>
[src]
pub fn lt(&self, other: &CStrBuf<B>) -> bool
[src]
pub fn le(&self, other: &CStrBuf<B>) -> bool
[src]
pub fn gt(&self, other: &CStrBuf<B>) -> bool
[src]
pub fn ge(&self, other: &CStrBuf<B>) -> bool
[src]
impl<B: Pod> Pod for CStrBuf<B>
[src]
impl<B> StructuralEq for CStrBuf<B>
[src]
impl<B> StructuralPartialEq for CStrBuf<B>
[src]
impl<B: Zeroable> Zeroable for CStrBuf<B>
[src]
Auto Trait Implementations
impl<B> RefUnwindSafe for CStrBuf<B> where
B: RefUnwindSafe,
[src]
B: RefUnwindSafe,
impl<B> Send for CStrBuf<B> where
B: Send,
[src]
B: Send,
impl<B> Sync for CStrBuf<B> where
B: Sync,
[src]
B: Sync,
impl<B> Unpin for CStrBuf<B> where
B: Unpin,
[src]
B: Unpin,
impl<B> UnwindSafe for CStrBuf<B> where
B: UnwindSafe,
[src]
B: UnwindSafe,
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T
[src]
pub fn clone_into(&self, target: &mut T)
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,