mp4_atom/
coding.rs

1use std::ffi;
2
3use crate::*;
4
5/// Decode a type from a buffer.
6pub trait Decode: Sized {
7    /// Decode the type from the buffer.
8    fn decode<B: Buf>(buf: &mut B) -> Result<Self>;
9
10    /// Helper: Decode exactly size bytes from the buffer.
11    fn decode_exact<B: Buf>(buf: &mut B, size: usize) -> Result<Self> {
12        if buf.remaining() < size {
13            return Err(Error::OutOfBounds);
14        }
15
16        let mut inner = buf.slice(size);
17        let res = Self::decode(&mut inner)?;
18
19        if inner.has_remaining() {
20            return Err(Error::ShortRead);
21        }
22
23        buf.advance(size);
24
25        Ok(res)
26    }
27}
28
29/// Decode a type from a buffer if we have enough data.
30pub trait DecodeMaybe: Sized {
31    fn decode_maybe<B: Buf>(buf: &mut B) -> Result<Option<Self>>;
32}
33
34/// Decode an atom using the provided header
35pub trait DecodeAtom: Sized {
36    fn decode_atom<B: Buf>(header: &Header, buf: &mut B) -> Result<Self>;
37}
38
39/// Encode a type to a buffer.
40//
41// Why not BufMut?
42// Well it's because we need to write the size of each atom.
43// If we use BufMut, we can't seek backwards so we have to calculate it upfront.
44// If we use BufMut or Vec, then we can write 0 for the size, then write the atom, then go back and fix the size.
45pub trait Encode {
46    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()>;
47
48    #[cfg(test)]
49    fn assert_encode_decode(&self)
50    where
51        Self: std::fmt::Debug + PartialEq + Decode,
52    {
53        let mut buf = Vec::new();
54        Self::encode(self, &mut buf).unwrap();
55
56        let mut cursor = std::io::Cursor::new(&buf);
57        let decoded = Self::decode(&mut cursor).unwrap();
58
59        assert_eq!(self, &decoded, "different decoded result");
60    }
61}
62
63impl Decode for u8 {
64    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
65        Ok(Self::from_be_bytes(<[u8; 1]>::decode(buf)?))
66    }
67}
68
69impl Decode for i8 {
70    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
71        Ok(Self::from_be_bytes(<[u8; 1]>::decode(buf)?))
72    }
73}
74
75impl Decode for u16 {
76    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
77        Ok(Self::from_be_bytes(<[u8; 2]>::decode(buf)?))
78    }
79}
80
81impl Decode for i16 {
82    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
83        Ok(Self::from_be_bytes(<[u8; 2]>::decode(buf)?))
84    }
85}
86
87impl Decode for u32 {
88    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
89        Ok(Self::from_be_bytes(<[u8; 4]>::decode(buf)?))
90    }
91}
92
93impl Decode for i32 {
94    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
95        Ok(Self::from_be_bytes(<[u8; 4]>::decode(buf)?))
96    }
97}
98
99impl Decode for u64 {
100    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
101        Ok(Self::from_be_bytes(<[u8; 8]>::decode(buf)?))
102    }
103}
104
105impl Decode for i64 {
106    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
107        Ok(Self::from_be_bytes(<[u8; 8]>::decode(buf)?))
108    }
109}
110
111impl<const N: usize> Decode for [u8; N] {
112    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
113        if buf.remaining() < N {
114            return Err(Error::OutOfBounds);
115        }
116
117        let mut v = [0u8; N];
118        v.copy_from_slice(buf.slice(N));
119        buf.advance(N);
120
121        Ok(v)
122    }
123}
124
125impl<T: Decode> Decode for Vec<T> {
126    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
127        let mut vec = Vec::new();
128        while buf.has_remaining() {
129            let item = T::decode(buf)?;
130            vec.push(item);
131        }
132
133        Ok(vec)
134    }
135}
136
137impl Decode for String {
138    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
139        let mut bytes = Vec::new();
140        while buf.has_remaining() {
141            let byte = u8::decode(buf)?;
142            if byte == 0 {
143                break;
144            }
145
146            bytes.push(byte);
147        }
148
149        let str = ffi::CString::new(bytes).map_err(|err| Error::InvalidString(err.to_string()))?;
150        str.into_string()
151            .map_err(|err| Error::InvalidString(err.to_string()))
152    }
153}
154
155impl Encode for u8 {
156    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
157        self.to_be_bytes().encode(buf)
158    }
159}
160
161impl Encode for i8 {
162    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
163        self.to_be_bytes().encode(buf)
164    }
165}
166
167impl Encode for i16 {
168    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
169        self.to_be_bytes().encode(buf)
170    }
171}
172
173impl Encode for u16 {
174    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
175        self.to_be_bytes().encode(buf)
176    }
177}
178
179impl Encode for u32 {
180    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
181        self.to_be_bytes().encode(buf)
182    }
183}
184
185impl Encode for i32 {
186    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
187        self.to_be_bytes().encode(buf)
188    }
189}
190
191impl Encode for u64 {
192    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
193        self.to_be_bytes().encode(buf)
194    }
195}
196
197impl Encode for i64 {
198    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
199        self.to_be_bytes().encode(buf)
200    }
201}
202
203impl<const N: usize> Encode for [u8; N] {
204    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
205        buf.append_slice(self);
206        Ok(())
207    }
208}
209
210impl<T: Encode> Encode for &[T] {
211    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
212        for item in self.iter() {
213            item.encode(buf)?;
214        }
215
216        Ok(())
217    }
218}
219
220impl<T: Encode> Encode for Option<T> {
221    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
222        match self {
223            Some(v) => v.encode(buf),
224            None => Ok(()),
225        }
226    }
227}
228
229impl Encode for &str {
230    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
231        self.as_bytes().encode(buf)?;
232        0u8.encode(buf)?;
233        Ok(())
234    }
235}
236
237impl<T: Encode> Encode for Vec<T> {
238    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
239        for item in self.iter() {
240            item.encode(buf)?;
241        }
242
243        Ok(())
244    }
245}