taskstats 0.1.1

high-level encapsulation of Linux's per-task statistics interface
Documentation
use super::raw::{nlmsghdr, NLMSG_LENGTH};
use super::Serialize;
use zerocopy::LayoutVerified;

#[derive(Debug)]
pub struct NetlinkMessage<P> {
    pub ty: u16,
    pub flags: u16,
    pub seq: u32,
    pub pid: u32,
    pub payload: P,
}

impl<P: Serialize> Serialize for NetlinkMessage<P> {
    fn len(&self) -> u32 {
        NLMSG_LENGTH(self.payload.len())
    }

    fn serialize(&self, buf: &mut [u8]) {
        let header_len = NLMSG_LENGTH(0) as usize;
        let (header, payload) = buf.split_at_mut(header_len);
        let mut header = LayoutVerified::<_, nlmsghdr>::new(header).expect("invalid buffer");
        header.nlmsg_len = self.len();
        header.nlmsg_type = self.ty;
        header.nlmsg_flags = self.flags;
        header.nlmsg_seq = self.seq;
        header.nlmsg_pid = self.pid;
        self.payload.serialize(payload);
    }
}

impl<'a> NetlinkMessage<&'a [u8]> {
    pub fn deserialize(buf: &'a [u8]) -> Self {
        let header_len = NLMSG_LENGTH(0) as usize;
        let (header, payload) = buf.split_at(header_len);
        let header = LayoutVerified::<_, nlmsghdr>::new(header).expect("invalid buffer");
        Self {
            ty: header.nlmsg_type,
            flags: header.nlmsg_flags,
            seq: header.nlmsg_seq,
            pid: header.nlmsg_pid,
            payload,
        }
    }
}