xo65 0.1.0

Library for parsing cc65 object files (xo65 format)
Documentation
use crate::parse::{parse_uleb128_at, ParseAt, ParseErrorContext as _, ParseResult};
use crate::xo65::Xo65Bytes;

#[derive(Debug)]
pub struct FileTable<'data> {
    bytes: Xo65Bytes<'data>,

    files: Box<[File]>,
}

impl<'data> FileTable<'data> {
    pub fn as_bytes(&self) -> &'data [u8] {
        self.bytes.as_inner()
    }

    pub fn count(&self) -> usize {
        self.files.len()
    }

    pub fn get(&self, idx: usize) -> Option<&File> {
        self.files.get(idx)
    }

    pub fn iter(
        &self,
    ) -> impl DoubleEndedIterator<Item = &File> + ExactSizeIterator + std::iter::FusedIterator + Clone
    {
        self.files.iter()
    }

    pub(crate) fn parse(bytes: Xo65Bytes<'data>) -> ParseResult<Self> {
        let mut off = 0;

        let count = parse_uleb128_at(&bytes, &mut off)? as usize;
        let mut files = Vec::<File>::with_capacity(count);

        for i in 0..count {
            let file = File::parse_at(&bytes, &mut off)
                .with_context(|| format!("file {i} parse error"))?;
            files.push(file);
        }

        Ok(Self {
            bytes,
            files: files.into(),
        })
    }
}

#[derive(Debug)]
pub struct File {
    name: u32,
    size: u32,
    mtime: i32,
}

impl File {
    pub fn name(&self) -> u32 {
        self.name
    }

    pub fn size(&self) -> u32 {
        self.size
    }

    pub fn mtime(&self) -> i32 {
        self.mtime
    }
}

impl ParseAt<'_> for File {
    fn parse_at(bytes: &Xo65Bytes<'_>, off: &mut usize) -> ParseResult<Self> {
        let name = parse_uleb128_at(bytes, off)?;
        let mtime = i32::parse_at(bytes, off)?;
        let size = parse_uleb128_at(bytes, off)?;

        Ok(Self { name, size, mtime })
    }
}