mkv_element/functional/
coding.rs

1//! Encoding and decoding Element or other types from buffers in memory.
2use core::slice;
3
4use super::*;
5use crate::{Result, base::Header, element::Element, error::Error};
6
7/// Decode an element from a buffer.
8pub trait Decode: Sized {
9    /// Decode an element from the buffer.
10    fn decode(buf: &mut &[u8]) -> Result<Self>;
11
12    /// Helper: Decode exactly size bytes from the buffer.
13    fn decode_exact(buf: &mut &[u8], size: usize) -> Result<Self> {
14        if buf.remaining() < size {
15            return Err(Error::OutOfBounds);
16        }
17        let mut inner = buf.slice(size);
18        let res = Self::decode(&mut inner)?;
19        if inner.has_remaining() {
20            return Err(Error::ShortRead);
21        }
22        buf.advance(size);
23        Ok(res)
24    }
25}
26
27/// Decode an element using the provided header
28pub trait DecodeElement: Sized + Element {
29    /// Decode an element using the provided header
30    /// implemented for all `Element`s.
31    fn decode_element(header: &Header, buf: &mut &[u8]) -> Result<Self> {
32        let size = *header.size as usize;
33        if size > buf.remaining() {
34            return Err(crate::error::Error::OutOfBounds);
35        }
36        let mut body = buf.slice(size);
37        let element = match Self::decode_body(&mut body) {
38            Ok(e) => e,
39            Err(Error::OutOfBounds) => return Err(Error::OverDecode(Self::ID)),
40            Err(Error::ShortRead) => return Err(Error::UnderDecode(Self::ID)),
41            Err(e) => return Err(e),
42        };
43
44        if body.has_remaining() {
45            return Err(Error::UnderDecode(Self::ID));
46        }
47
48        buf.advance(size);
49        Ok(element)
50    }
51}
52impl<T: Element> DecodeElement for T {}
53
54impl<const N: usize> Decode for [u8; N] {
55    fn decode(buf: &mut &[u8]) -> Result<Self> {
56        if buf.len() < N {
57            return Err(Error::OutOfBounds);
58        }
59        let mut v = [0u8; N];
60        v.copy_from_slice(buf.slice(N));
61        buf.advance(N);
62        Ok(v)
63    }
64}
65
66impl Decode for u8 {
67    fn decode(buf: &mut &[u8]) -> Result<Self> {
68        Ok(Self::from_be_bytes(<[u8; 1]>::decode(buf)?))
69    }
70}
71
72impl Decode for i8 {
73    fn decode(buf: &mut &[u8]) -> Result<Self> {
74        Ok(Self::from_be_bytes(<[u8; 1]>::decode(buf)?))
75    }
76}
77
78impl Decode for u16 {
79    fn decode(buf: &mut &[u8]) -> Result<Self> {
80        Ok(Self::from_be_bytes(<[u8; 2]>::decode(buf)?))
81    }
82}
83
84impl Decode for i16 {
85    fn decode(buf: &mut &[u8]) -> Result<Self> {
86        Ok(Self::from_be_bytes(<[u8; 2]>::decode(buf)?))
87    }
88}
89
90impl Decode for u32 {
91    fn decode(buf: &mut &[u8]) -> Result<Self> {
92        Ok(Self::from_be_bytes(<[u8; 4]>::decode(buf)?))
93    }
94}
95
96impl Decode for i32 {
97    fn decode(buf: &mut &[u8]) -> Result<Self> {
98        Ok(Self::from_be_bytes(<[u8; 4]>::decode(buf)?))
99    }
100}
101
102impl Decode for u64 {
103    fn decode(buf: &mut &[u8]) -> Result<Self> {
104        Ok(Self::from_be_bytes(<[u8; 8]>::decode(buf)?))
105    }
106}
107
108impl Decode for i64 {
109    fn decode(buf: &mut &[u8]) -> Result<Self> {
110        Ok(Self::from_be_bytes(<[u8; 8]>::decode(buf)?))
111    }
112}
113
114impl<T: Decode> Decode for Vec<T> {
115    fn decode(buf: &mut &[u8]) -> Result<Self> {
116        let mut vec = Vec::new();
117        while buf.has_remaining() {
118            let item = T::decode(buf)?;
119            vec.push(item);
120        }
121        Ok(vec)
122    }
123}
124
125impl<T: Decode> Decode for Option<T> {
126    /// # Safety:
127    /// The buffer is not modified during decoding, as we holding a immutable reference to it.
128    ///
129    fn decode(buf: &mut &[u8]) -> Result<Self> {
130        if !buf.has_remaining() {
131            return Ok(None);
132        }
133
134        let initial_len = buf.len();
135        let ptr = buf.as_ptr();
136
137        let mut working_buf = unsafe { slice::from_raw_parts(ptr, initial_len) };
138        let out = T::decode(&mut working_buf)?;
139
140        *buf = working_buf;
141        Ok(Some(out))
142    }
143}
144
145/// Encode an element to a buffer.
146pub trait Encode {
147    /// Encode self to the buffer.
148    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()>;
149}
150
151impl Encode for u8 {
152    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
153        self.to_be_bytes().encode(buf)
154    }
155}
156
157impl Encode for i8 {
158    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
159        self.to_be_bytes().encode(buf)
160    }
161}
162
163impl Encode for i16 {
164    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
165        self.to_be_bytes().encode(buf)
166    }
167}
168
169impl Encode for u16 {
170    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
171        self.to_be_bytes().encode(buf)
172    }
173}
174
175impl Encode for u32 {
176    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
177        self.to_be_bytes().encode(buf)
178    }
179}
180
181impl Encode for i32 {
182    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
183        self.to_be_bytes().encode(buf)
184    }
185}
186
187impl Encode for u64 {
188    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
189        self.to_be_bytes().encode(buf)
190    }
191}
192
193impl Encode for i64 {
194    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
195        self.to_be_bytes().encode(buf)
196    }
197}
198
199impl<const N: usize> Encode for [u8; N] {
200    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
201        buf.append_slice(self);
202        Ok(())
203    }
204}
205
206impl<T: Encode> Encode for &[T] {
207    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
208        for item in self.iter() {
209            item.encode(buf)?;
210        }
211
212        Ok(())
213    }
214}
215
216impl<T: Encode> Encode for Option<T> {
217    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
218        match self {
219            Some(v) => v.encode(buf),
220            None => Ok(()),
221        }
222    }
223}
224
225impl Encode for &str {
226    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
227        self.as_bytes().encode(buf)?;
228        0u8.encode(buf)?;
229        Ok(())
230    }
231}
232
233impl<T: Encode> Encode for Vec<T> {
234    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
235        for item in self.iter() {
236            item.encode(buf)?;
237        }
238
239        Ok(())
240    }
241}
242
243#[cfg(test)]
244mod tests {
245    use super::*;
246    use crate::base::VInt64;
247    use crate::functional::Decode;
248
249    // if decode fails, buf should be unchanged
250    #[test]
251    fn test_option_decode() {
252        let v = VInt64(42);
253        let mut encoded = vec![];
254        v.encode(&mut encoded).unwrap();
255        let mut slice_encoded = &encoded[..];
256
257        let opt_header = Option::<Header>::decode(&mut slice_encoded);
258
259        assert!(opt_header.is_err());
260        assert_ne!(slice_encoded.len(), 0);
261
262        let opt_vint = VInt64::decode(&mut slice_encoded).unwrap();
263        assert_eq!(opt_vint, v);
264    }
265}