[][src]Struct abistr::CStrBuf

#[repr(transparent)]pub struct CStrBuf<B> { /* fields omitted */ }

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 NotNulTerminatedErrors) 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]

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]

Create a CStrBuf from data + \0.

pub unsafe fn try_from_without_nul(
    data: &impl AsRef<[u8]> + ?Sized
) -> Result<Self, BufferTooSmallError>
[src]

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 \0s.

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]

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]

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]

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]

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]

impl<B: Ord> Ord for CStrBuf<B>[src]

impl<B: PartialEq> PartialEq<CStrBuf<B>> for CStrBuf<B>[src]

impl<B: PartialOrd> PartialOrd<CStrBuf<B>> for CStrBuf<B>[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]

impl<B> Send for CStrBuf<B> where
    B: Send
[src]

impl<B> Sync for CStrBuf<B> where
    B: Sync
[src]

impl<B> Unpin for CStrBuf<B> where
    B: Unpin
[src]

impl<B> UnwindSafe for CStrBuf<B> where
    B: UnwindSafe
[src]

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.