nell 0.3.0

Linux netlink interface
Documentation
// Copyright (C) 2020 - Will Glozer. All rights reserved.

use std::marker::PhantomData;
use std::mem::size_of;
use std::ptr::copy_nonoverlapping;
use std::slice;
use crate::sys::{align, Bytes};
use super::Error;

#[derive(Debug, Eq, PartialEq)]
pub struct Buffer<'a> {
    ptr: *mut u8,
    cur: *mut u8,
    len: usize,
    pha: PhantomData<&'a ()>,
}

impl<'a> Buffer<'a> {
    pub fn new(buf: &mut [u8]) -> Self {
        Self {
            ptr: buf.as_mut_ptr(),
            cur: buf.as_mut_ptr(),
            len: buf.len(),
            pha: PhantomData
        }
    }

    pub fn write<T: Bytes>(&mut self, item: &T) -> Result<(), Error> {
        unsafe {
            let size = size_of::<T>();
            let dst  = self.place(size)?.0;
            let src  = item as *const _ as *const u8;
            copy_nonoverlapping(src, dst, size);
            Ok(())
        }
    }

    pub fn copy(&mut self, bytes: &[u8]) -> Result<(), Error> {
        unsafe {
            let size = bytes.len();
            let dst  = self.place(size)?.0;
            copy_nonoverlapping(bytes.as_ptr(), dst, size);
            Ok(())
        }
    }

    pub fn buffer(&mut self, size: usize) -> Result<&mut [u8], Error> {
        unsafe {
            let (ptr, size) = self.place(size)?;
            Ok(slice::from_raw_parts_mut(ptr, size))
        }
    }

    pub fn bytes(&self) -> &'a [u8] {
        unsafe {
            let x = self.cur as usize;
            let y = self.ptr as usize;
            slice::from_raw_parts(self.ptr, x - y)
        }
    }

    fn place(&mut self, size: usize) -> Result<(*mut u8, usize), Error> {
        unsafe {
            let size = align(size);
            self.len = self.len.checked_sub(size).ok_or(Error::Overrun)?;
            let ptr  = self.cur as *mut u8;
            self.cur = self.cur.add(size);
            Ok((ptr, size))
        }
    }
}