mp4ameta 0.13.0

A library for reading and writing iTunes style MPEG-4 audio metadata.
Documentation
use super::*;

pub const HEADER_SIZE: u64 = 12;
pub const ENTRY_SIZE: u64 = 4;

#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Stsz {
    pub state: State,
    /// If this field is set to zero, a list of sizes is read instead.
    pub uniform_sample_size: u32,
    pub sizes: Table<u32>,
}

impl Atom for Stsz {
    const FOURCC: Fourcc = SAMPLE_TABLE_SAMPLE_SIZE;
}

impl ParseAtom for Stsz {
    fn parse_atom(
        reader: &mut (impl Read + Seek),
        _cfg: &ParseConfig<'_>,
        size: Size,
    ) -> crate::Result<Self> {
        let bounds = find_bounds(reader, size)?;
        let (version, _) = head::parse_full(reader)?;

        if version != 0 {
            return unknown_version("sample table sample size (stsz)", version);
        }

        let uniform_sample_size = reader.read_be_u32()?;

        let num_entries = reader.read_be_u32()?;
        let sizes = if uniform_sample_size == 0 {
            let table_size = ENTRY_SIZE * num_entries as u64;
            expect_size("Sample table sample size (stsz)", size, HEADER_SIZE + table_size)?;

            reader.skip(table_size as i64)?;
            Table::Shallow {
                pos: bounds.content_pos() + HEADER_SIZE,
                num_entries,
            }
        } else {
            expect_size("Sample table sample size (stsz)", size, HEADER_SIZE)?;
            Table::Full(Vec::new())
        };

        Ok(Self {
            state: State::Existing(bounds),
            uniform_sample_size,
            sizes,
        })
    }
}

impl AtomSize for Stsz {
    fn size(&self) -> Size {
        let content_len = HEADER_SIZE + ENTRY_SIZE * self.sizes.len() as u64;
        Size::from(content_len)
    }
}

impl WriteAtom for Stsz {
    fn write_atom(&self, writer: &mut impl Write, _changes: &[Change<'_>]) -> crate::Result<()> {
        self.write_head(writer)?;
        head::write_full(writer, 0, [0; 3])?;

        writer.write_be_u32(self.uniform_sample_size)?;
        writer.write_be_u32(self.sizes.len() as u32)?;

        match &self.sizes {
            Table::Shallow { .. } => unreachable!(),
            Table::Full(sizes) => {
                for s in sizes.iter() {
                    writer.write_be_u32(*s)?;
                }
            }
        }

        Ok(())
    }
}

impl LeafAtomCollectChanges for Stsz {
    fn state(&self) -> &State {
        &self.state
    }

    fn atom_ref(&self) -> AtomRef<'_> {
        AtomRef::Stsz(self)
    }
}