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