Skip to main content

mp4_edit/atom/leaf/
free.rs

1use std::fmt;
2
3use crate::{
4    atom::{
5        util::{parser::rest_vec, DebugList, DebugUpperHex},
6        FourCC,
7    },
8    parser::ParseAtomData,
9    writer::SerializeAtom,
10    ParseError,
11};
12
13pub const FREE: FourCC = FourCC::new(b"free");
14pub const SKIP: FourCC = FourCC::new(b"skip");
15
16#[derive(Clone)]
17pub struct FreeAtom {
18    /// The atom type (either 'free' or 'skip')
19    pub atom_type: FourCC,
20    /// Size of the free space data
21    pub data_size: usize,
22    /// The actual free space data (usually ignored)
23    pub data: Vec<u8>,
24}
25
26impl fmt::Debug for FreeAtom {
27    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28        f.debug_struct("FreeAtom")
29            .field("atom_type", &self.atom_type)
30            .field("data_size", &self.data_size)
31            .field(
32                "data",
33                &DebugList::new(self.data.iter().map(DebugUpperHex), 10),
34            )
35            .finish()
36    }
37}
38
39impl ParseAtomData for FreeAtom {
40    fn parse_atom_data(atom_type: FourCC, input: &[u8]) -> Result<Self, ParseError> {
41        crate::atom::util::parser::assert_atom_type!(atom_type, FREE, SKIP);
42
43        use crate::atom::util::parser::stream;
44        use winnow::Parser;
45
46        let data = rest_vec.parse(stream(input))?;
47        Ok(FreeAtom {
48            atom_type,
49            data_size: data.len(),
50            data,
51        })
52    }
53}
54
55impl SerializeAtom for FreeAtom {
56    fn atom_type(&self) -> FourCC {
57        self.atom_type
58    }
59
60    fn into_body_bytes(self) -> Vec<u8> {
61        if self.data.is_empty() {
62            vec![0u8; self.data_size]
63        } else {
64            self.data
65        }
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72    use crate::atom::test_utils::test_atom_roundtrip;
73
74    /// Test round-trip for all available free test data files
75    #[test]
76    fn test_free_roundtrip() {
77        test_atom_roundtrip::<FreeAtom>(FREE);
78    }
79}