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: {:?}, bytes: {:?} }}", kind, body.len(), body),
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    Meta,
126        Hdlr,
127        Pitm,
128        Iloc,
129        Iinf,
130        Iprp,
131            Ipco,
132                Auxc,
133                Clap,
134                Imir,
135                Irot,
136                Iscl,
137                Ispe,
138                Pixi,
139                Rref,
140            Ipma,
141        Iref,
142        Idat,
143        Ilst,
144            Covr,
145            Desc,
146            Name,
147            Year,
148    Moov,
149        Mvhd,
150        Udta,
151            Skip,
152        Trak,
153            Tkhd,
154            Mdia,
155                Mdhd,
156                Minf,
157                    Stbl,
158                        Stsd,
159                            Avc1,
160                                Avcc,
161                                Btrt,
162                                Ccst,
163                                Colr,
164                                Pasp,
165                                Taic,
166                            Hev1, Hvc1,
167                                Hvcc,
168                            Mp4a,
169                                Esds,
170                            Tx3g,
171                            Vp08, Vp09,
172                                VpcC,
173                            Av01,
174                                Av1c,
175                            Opus,
176                                Dops,
177                            Uncv,
178                                Cmpd,
179                                UncC,
180                        Stts,
181                        Stsc,
182                        Stsz,
183                        Stss,
184                        Stco,
185                        Co64,
186                        Ctts,
187                        Saio,
188                        Saiz,
189                    Dinf,
190                        Dref,
191                    Smhd,
192                    Vmhd,
193            Edts,
194                Elst,
195        Mvex,
196            Mehd,
197            Trex,
198    Emsg,
199    Moof,
200        Mfhd,
201        Traf,
202            Tfhd,
203            Tfdt,
204            Trun,
205    Mdat,
206    Free,
207}
208
209impl ReadFrom for Any {
210    fn read_from<R: Read>(r: &mut R) -> Result<Self> {
211        <Option<Any> as ReadFrom>::read_from(r)?.ok_or(Error::UnexpectedEof)
212    }
213}
214
215impl ReadFrom for Option<Any> {
216    fn read_from<R: Read>(r: &mut R) -> Result<Self> {
217        let header = match <Option<Header> as ReadFrom>::read_from(r)? {
218            Some(header) => header,
219            None => return Ok(None),
220        };
221
222        let body = &mut header.read_body(r)?;
223        Ok(Some(Any::decode_atom(&header, body)?))
224    }
225}
226
227impl ReadAtom for Any {
228    fn read_atom<R: Read>(header: &Header, r: &mut R) -> Result<Self> {
229        let body = &mut header.read_body(r)?;
230        Any::decode_atom(header, body)
231    }
232}