1use std::borrow::Borrow;
2
3use crate::*;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub struct EvteSample;
17
18impl EvteSample {
19 pub fn decode<B: Buf>(buf: &mut B) -> Result<Vec<Emib>> {
20 let mut emibs = Vec::new();
21 let mut emeb = None;
22
23 while let Some(header) = Header::decode_maybe(buf)? {
24 let size = header.size.unwrap_or(buf.remaining());
25 if size > buf.remaining() {
26 return Err(Error::OutOfBounds);
27 }
28 let mut body = buf.slice(size);
29
30 match header.kind {
31 Emib::KIND if emeb.is_none() => emibs.push(Emib::decode_body(&mut body)?),
32 Emeb::KIND if emeb.is_none() && emibs.is_empty() => {
33 emeb = Some(Emeb::decode_body(&mut body)?)
34 }
35 kind => return Err(Error::UnexpectedBox(kind)),
36 }
37
38 if body.has_remaining() {
39 return Err(Error::UnderDecode(header.kind));
40 }
41 buf.advance(size);
42 }
43
44 if buf.has_remaining() {
45 Err(Error::ShortRead)
46 } else if emeb.is_none() && emibs.is_empty() {
47 Err(Error::UnexpectedEof)
48 } else {
49 Ok(emibs)
50 }
51 }
52
53 pub fn encode<B: BufMut>(
54 emibs: impl IntoIterator<Item = impl Borrow<Emib>>,
55 buf: &mut B,
56 ) -> Result<()> {
57 let mut wrote_atom = false;
58 for emib in emibs {
59 emib.borrow().encode(buf)?;
60 wrote_atom = true;
61 }
62 if wrote_atom {
63 Ok(())
64 } else {
65 Emeb.encode(buf)
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 fn sample_emib(id: u32) -> Emib {
75 Emib {
76 presentation_time_delta: 0,
77 event_duration: 1000,
78 id,
79 scheme_id_uri: "urn:mpeg:dash:event:2012".into(),
80 value: "".into(),
81 message_data: vec![1, 2, 3],
82 }
83 }
84
85 #[test]
86 fn test_evte_sample_no_emib_roundtrip() {
87 let sample = vec![];
88
89 let mut buf = Vec::new();
90 EvteSample::encode(&sample, &mut buf).unwrap();
91
92 let decoded = EvteSample::decode(&mut buf.as_slice()).expect("failed to decode sample");
93 assert_eq!(decoded, sample);
94 }
95
96 #[test]
97 fn test_evte_sample_single_emib_roundtrip() {
98 let sample = vec![sample_emib(1)];
99
100 let mut buf = Vec::new();
101 EvteSample::encode(&sample, &mut buf).unwrap();
102
103 let decoded = EvteSample::decode(&mut buf.as_slice()).expect("failed to decode sample");
104 assert_eq!(decoded, sample);
105 }
106
107 #[test]
108 fn test_evte_sample_multiple_emib_roundtrip() {
109 let sample = vec![sample_emib(1), sample_emib(2), sample_emib(3)];
111
112 let mut buf = Vec::new();
113 EvteSample::encode(&sample, &mut buf).unwrap();
114
115 let decoded = EvteSample::decode(&mut buf.as_slice()).expect("failed to decode sample");
116 assert_eq!(decoded, sample);
117 }
118
119 #[test]
120 fn test_evte_sample_empty_is_error() {
121 let err = EvteSample::decode(&mut [].as_slice()).unwrap_err();
122 assert!(matches!(err, Error::UnexpectedEof));
123 }
124
125 #[test]
126 fn test_evte_sample_short_read() {
127 let err = EvteSample::decode(&mut [1, 2].as_slice()).unwrap_err();
128 assert!(matches!(err, Error::ShortRead));
129 }
130
131 #[test]
132 fn test_evte_sample_emeb_after_emib_is_error() {
133 let mut buf = Vec::new();
135 sample_emib(1).encode(&mut buf).unwrap();
136 Emeb.encode(&mut buf).unwrap();
137
138 let err = EvteSample::decode(&mut buf.as_slice()).unwrap_err();
139 assert!(matches!(err, Error::UnexpectedBox(kind) if kind == Emeb::KIND));
140 }
141
142 #[test]
143 fn test_evte_sample_invalid_emeb_is_error() {
144 let mut buf = Vec::new();
145
146 let header = Header {
147 kind: Emeb::KIND,
148 size: Some(size_of::<u32>()),
149 };
150 header.encode(&mut buf).unwrap();
151 0u32.encode(&mut buf).unwrap(); let err = EvteSample::decode(&mut buf.as_slice()).unwrap_err();
154 assert!(matches!(err, Error::UnderDecode(kind) if kind == Emeb::KIND));
155 }
156}