mp4_atom/
any.rs

1use crate::*;
2
3use std::fmt;
4use std::io::Read;
5
6macro_rules! any {
7    ($($kind:ident,)*) => {
8        /// Any of the supported atoms.
9        #[derive(Clone, PartialEq)]
10        #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11        #[non_exhaustive]
12        pub enum Any {
13            $($kind($kind),)*
14            Unknown(FourCC, Vec<u8>),
15        }
16
17        impl Any {
18            /// Get the kind of the atom.
19            pub fn kind(&self) -> FourCC {
20                match self {
21                    $(Any::$kind(_) => $kind::KIND,)*
22                    Any::Unknown(kind, _) => *kind,
23                }
24            }
25        }
26
27        impl Decode for Any {
28            fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
29                match Self::decode_maybe(buf)? {
30                    Some(any) => Ok(any),
31                    None => Err(Error::OutOfBounds),
32                }
33            }
34        }
35
36        impl DecodeMaybe for Any {
37            fn decode_maybe<B: Buf>(buf: &mut B) -> Result<Option<Self>> {
38                let header = match Header::decode_maybe(buf)? {
39                    Some(header) => header,
40                    None => return Ok(None),
41                };
42
43                let size = header.size.unwrap_or(buf.remaining());
44                if size > buf.remaining() {
45                    return Ok(None);
46                }
47
48                Ok(Some(Self::decode_atom(&header, buf)?))
49            }
50        }
51
52        impl Encode for Any {
53            fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
54                let start = buf.len();
55                0u32.encode(buf)?;
56                self.kind().encode(buf)?;
57
58                match self {
59                    $(Any::$kind(inner) => Atom::encode_body(inner, buf),)*
60                    Any::Unknown(_, data) => data.encode(buf),
61                }?;
62
63                let size: u32 = (buf.len() - start).try_into().map_err(|_| Error::TooLarge(self.kind()))?;
64                buf.set_slice(start, &size.to_be_bytes());
65
66                Ok(())
67            }
68        }
69
70        impl DecodeAtom for Any {
71            /// Decode the atom from a header and payload.
72            fn decode_atom<B: Buf>(header: &Header, buf: &mut B) -> Result<Self> {
73                let size = header.size.unwrap_or(buf.remaining());
74                if size > buf.remaining() {
75                    return Err(Error::OutOfBounds);
76                }
77
78                let mut body = &mut buf.slice(size);
79
80                let atom = match header.kind {
81                    $(_ if header.kind == $kind::KIND => {
82                        Any::$kind(match $kind::decode_body(&mut body) {
83                            Ok(atom) => atom,
84                            Err(Error::OutOfBounds) => return Err(Error::OverDecode($kind::KIND)),
85                            Err(Error::ShortRead) => return Err(Error::UnderDecode($kind::KIND)),
86                            Err(err) => return Err(err),
87                        })
88                    },)*
89                    _ => {
90                        let body = Vec::decode(body)?;
91                        Any::Unknown(header.kind, body)
92                    },
93                };
94
95                if body.has_remaining() {
96                    return Err(Error::UnderDecode(header.kind));
97                }
98
99                buf.advance(size);
100
101                Ok(atom)
102            }
103        }
104
105        impl fmt::Debug for Any {
106            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107                match self {
108                    $(Any::$kind(inner) => inner.fmt(f),)*
109                    Any::Unknown(kind, body) => write!(f, "Unknown {{ kind: {:?}, size: {:?} }}", kind, body.len()),
110                }
111            }
112        }
113
114        $(impl From<$kind> for Any {
115            fn from(inner: $kind) -> Self {
116                Any::$kind(inner)
117            }
118        })*
119    };
120}
121
122any! {
123    Ftyp,
124    Styp,
125    Moov,
126        Mvhd,
127        Udta,
128            Meta,
129                Ilst,
130                    Covr,
131                    Desc,
132                    Name,
133                    Year,
134            Skip,
135        Trak,
136            Tkhd,
137            Mdia,
138                Mdhd,
139                Hdlr,
140                Minf,
141                    Stbl,
142                        Stsd,
143                            Avc1,
144                                Avcc,
145                            Hev1, Hvc1,
146                                Hvcc,
147                            Mp4a,
148                                Esds,
149                            Tx3g,
150                            Vp08, Vp09,
151                                VpcC,
152                            Av01,
153                                Av1c,
154                        Stts,
155                        Stsc,
156                        Stsz,
157                        Stss,
158                        Stco,
159                        Co64,
160                        Ctts,
161                    Dinf,
162                        Dref,
163                    Smhd,
164                    Vmhd,
165            Edts,
166                Elst,
167        Mvex,
168            Mehd,
169            Trex,
170    Emsg,
171    Moof,
172        Mfhd,
173        Traf,
174            Tfhd,
175            Tfdt,
176            Trun,
177    Mdat,
178    Free,
179}
180
181impl ReadFrom for Any {
182    fn read_from<R: Read>(r: &mut R) -> Result<Self> {
183        <Option<Any> as ReadFrom>::read_from(r)?.ok_or(Error::UnexpectedEof)
184    }
185}
186
187impl ReadFrom for Option<Any> {
188    fn read_from<R: Read>(r: &mut R) -> Result<Self> {
189        let header = match <Option<Header> as ReadFrom>::read_from(r)? {
190            Some(header) => header,
191            None => return Ok(None),
192        };
193
194        let body = &mut header.read_body(r)?;
195        Ok(Some(Any::decode_atom(&header, body)?))
196    }
197}
198
199impl ReadAtom for Any {
200    fn read_atom<R: Read>(header: &Header, r: &mut R) -> Result<Self> {
201        let body = &mut header.read_body(r)?;
202        Any::decode_atom(header, body)
203    }
204}