boltffi_core 0.22.1

Core runtime types for BoltFFI - high-performance FFI bindings generator
Documentation
use crate::wire::constants::VEC_COUNT_SIZE;

pub unsafe trait Blittable: Copy + Sized {}

unsafe impl Blittable for i8 {}
unsafe impl Blittable for i16 {}
unsafe impl Blittable for i32 {}
unsafe impl Blittable for i64 {}
unsafe impl Blittable for u8 {}
unsafe impl Blittable for u16 {}
unsafe impl Blittable for u32 {}
unsafe impl Blittable for u64 {}
unsafe impl Blittable for f32 {}
unsafe impl Blittable for f64 {}
unsafe impl Blittable for bool {}
unsafe impl Blittable for isize {}
unsafe impl Blittable for usize {}

#[inline]
pub fn encode_blittable_slice<T: Blittable>(slice: &[T], buf: &mut [u8]) -> usize {
    let count = slice.len() as u32;
    buf[..VEC_COUNT_SIZE].copy_from_slice(&count.to_le_bytes());

    if slice.is_empty() {
        return VEC_COUNT_SIZE;
    }

    let byte_count = std::mem::size_of_val(slice);
    unsafe {
        std::ptr::copy_nonoverlapping(
            slice.as_ptr() as *const u8,
            buf.as_mut_ptr().add(VEC_COUNT_SIZE),
            byte_count,
        );
    }
    VEC_COUNT_SIZE + byte_count
}

#[inline]
pub fn blittable_slice_wire_size<T: Blittable>(slice: &[T]) -> usize {
    VEC_COUNT_SIZE + std::mem::size_of_val(slice)
}

#[inline]
pub fn decode_blittable_slice<T: Blittable>(buf: &[u8]) -> Option<Vec<T>> {
    if buf.len() < VEC_COUNT_SIZE {
        return None;
    }

    let count = u32::from_le_bytes([buf[0], buf[1], buf[2], buf[3]]) as usize;
    if count == 0 {
        return Some(Vec::new());
    }

    let byte_count = count * std::mem::size_of::<T>();
    let required_len = VEC_COUNT_SIZE + byte_count;
    if buf.len() < required_len {
        return None;
    }

    let mut result = Vec::<T>::with_capacity(count);
    unsafe {
        std::ptr::copy_nonoverlapping(
            buf.as_ptr().add(VEC_COUNT_SIZE),
            result.as_mut_ptr() as *mut u8,
            byte_count,
        );
        result.set_len(count);
    }
    Some(result)
}

#[inline]
pub fn encode_blittable<T: Blittable>(value: &T, buf: &mut [u8]) -> usize {
    let size = std::mem::size_of::<T>();
    unsafe {
        std::ptr::copy_nonoverlapping(value as *const T as *const u8, buf.as_mut_ptr(), size);
    }
    size
}

#[inline]
pub fn decode_blittable<T: Blittable>(buf: &[u8]) -> Option<T> {
    if buf.len() < std::mem::size_of::<T>() {
        return None;
    }
    Some(unsafe { std::ptr::read_unaligned(buf.as_ptr() as *const T) })
}