macho2 0.6.2

A better MachO parser library
Documentation
use nom::{number::complete::le_u32, IResult};

use super::{pad_to_size, LCLoadCommand, LoadCommandBase};

#[derive(Debug, PartialEq, Eq)]
pub struct LinkeditDataCommand {
    pub cmd: LCLoadCommand,
    pub cmdsize: u32,
    pub dataoff: u32,
    pub datasize: u32,
}

impl LinkeditDataCommand {
    pub fn parse<'a>(ldcmd: &'a [u8]) -> IResult<&'a [u8], Self> {
        let (cursor, base) = LoadCommandBase::parse(ldcmd)?;
        let (cursor, dataoff) = le_u32(cursor)?;
        let (cursor, datasize) = le_u32(cursor)?;

        Ok((
            cursor,
            LinkeditDataCommand {
                cmd: base.cmd,
                cmdsize: base.cmdsize,
                dataoff,
                datasize,
            },
        ))
    }

    pub fn serialize(&self) -> Vec<u8> {
        let mut buf = Vec::new();
        buf.extend(self.cmd.serialize());
        buf.extend(self.cmdsize.to_le_bytes());
        buf.extend(self.dataoff.to_le_bytes());
        buf.extend(self.datasize.to_le_bytes());
        pad_to_size(&mut buf, self.cmdsize as usize);
        buf
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::command::LCLoadCommand;

    #[test]
    fn test_linkedit_serialise() {
        let cmd = LinkeditDataCommand {
            cmd: LCLoadCommand::LcDyldInfo,
            cmdsize: 16,
            dataoff: 0,
            datasize: 0,
        };

        let serialized = cmd.serialize();
        let deserialized = LinkeditDataCommand::parse(&serialized).unwrap().1;
        assert_eq!(cmd, deserialized);
    }
}