1use std::fmt;
2use std::time::Duration;
3
4use chrono::prelude::*;
5
6use crate::annex_c;
7use crate::descriptor::Descriptor;
8use crate::duration_fmt::DurationFmt;
9use crate::error::{Error, Kind as ErrorKind};
10use crate::result::Result;
11use crate::subtable_id::{SubtableID, SubtableIDer};
12
13use super::traits::*;
14
15pub struct EIT<'buf> {
19 buf: &'buf [u8],
20}
21
22impl<'buf> EIT<'buf> {
23 const HEADER_SPECIFIC_SZ: usize = 6;
24 const HEADER_FULL_SZ: usize = HEADER_SZ + SYNTAX_SECTION_SZ + Self::HEADER_SPECIFIC_SZ;
25
26 #[inline(always)]
27 pub fn new(buf: &'buf [u8]) -> EIT<'buf> {
28 EIT { buf }
29 }
30
31 #[inline(always)]
32 pub fn try_new(buf: &'buf [u8]) -> Result<EIT<'buf>> {
33 let s = Self::new(buf);
34 s.validate()?;
35 Ok(s)
36 }
37
38 #[inline(always)]
39 pub fn validate(&self) -> Result<()> {
40 Ok(())
41 }
42
43 #[inline(always)]
45 fn buf_events(&self) -> &'buf [u8] {
46 let lft = Self::HEADER_FULL_SZ;
47 let mut rght = HEADER_SZ + (self.section_length() as usize);
48
49 if rght >= self.buf.len() {
50 rght = self.buf.len();
51 }
52
53 rght -= CRC32_SZ;
54
55 &self.buf[lft..rght]
56 }
57
58 #[inline(always)]
59 pub fn events(&self) -> Cursor<'buf, Event> {
60 Cursor::new(self.buf_events())
61 }
62
63 #[inline(always)]
64 pub fn service_id(&self) -> u16 {
65 self.table_id_extension()
66 }
67}
68
69trait WithEITHeaderSpecific<'buf>: Bufer<'buf> {
70 #[inline(always)]
72 fn b(&self) -> &'buf [u8] {
73 &self.buf()[HEADER_SZ + SYNTAX_SECTION_SZ..]
74 }
75
76 #[inline(always)]
77 fn transport_stream_id(&self) -> u16 {
78 u16::from(self.b()[0]) | u16::from(self.b()[1])
79 }
80
81 #[inline(always)]
82 fn original_network_id(&self) -> u16 {
83 u16::from(self.b()[2]) | u16::from(self.b()[3])
84 }
85
86 #[inline(always)]
87 fn segment_last_section_number(&self) -> u8 {
88 self.b()[4]
89 }
90
91 #[inline(always)]
92 fn last_table_id(&self) -> u8 {
93 self.b()[5]
94 }
95}
96
97impl<'buf> Bufer<'buf> for EIT<'buf> {
98 fn buf(&self) -> &'buf [u8] {
99 self.buf
100 }
101}
102
103impl<'buf> WithHeader<'buf> for EIT<'buf> {}
104impl<'buf> WithTableIDExtension<'buf> for EIT<'buf> {}
105impl<'buf> WithSyntaxSection<'buf> for EIT<'buf> {}
106impl<'buf> WithEITHeaderSpecific<'buf> for EIT<'buf> {}
107impl<'buf> WithCRC32<'buf> for EIT<'buf> {}
108
109impl<'buf> fmt::Debug for EIT<'buf> {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 write!(
112 f,
113 ":EIT (:id {:?} :section-length {:3} :section {}/{})",
114 self.subtable_id(),
115 self.section_length(),
116 self.section_number(),
117 self.last_section_number(),
118 )?;
119
120 write!(f, "\n :events")?;
121 for rese in self.events() {
122 write!(f, "\n ")?;
123 match rese {
124 Ok(e) => {
125 e.fmt(f)?;
126 }
127 Err(err) => {
128 write!(f, "error parse EIT event: {}", err)?;
129 }
130 }
131 }
132
133 Ok(())
134 }
135}
136
137impl<'buf> SubtableIDer for EIT<'buf> {
138 #[inline(always)]
139 fn subtable_id(&self) -> SubtableID {
140 SubtableID::EIT(
141 self.table_id(),
142 self.service_id(),
143 self.transport_stream_id(),
144 self.original_network_id(),
145 self.version_number(),
146 )
147 }
148}
149
150pub struct Event<'buf> {
151 buf: &'buf [u8],
152}
153
154impl<'buf> Event<'buf> {
155 const HEADER_SZ: usize = 12;
156
157 #[inline(always)]
158 pub fn new(buf: &'buf [u8]) -> Event<'buf> {
159 Event { buf }
160 }
161
162 #[inline(always)]
163 pub fn validate(&self) -> Result<()> {
164 if self.buf.len() < Self::HEADER_SZ {
165 Err(Error::new(ErrorKind::Buf(self.buf.len(), Self::HEADER_SZ)))
166 } else if self.buf.len() < self.sz() {
167 Err(Error::new(ErrorKind::Buf(self.buf.len(), self.sz())))
168 } else {
169 Ok(())
170 }
171 }
172
173 #[inline(always)]
174 pub fn event_id(&self) -> u16 {
175 (u16::from(self.buf[0]) << 8) | u16::from(self.buf[1])
176 }
177
178 #[inline(always)]
179 pub fn start_time(&self) -> DateTime<Utc> {
180 annex_c::from_bytes_into_date_time_utc(&self.buf[2..7]).unwrap()
182 }
183
184 #[inline(always)]
185 pub fn duration(&self) -> Duration {
186 annex_c::from_bytes_into_duration(&self.buf[7..10]).unwrap()
188 }
189
190 #[inline(always)]
192 fn buf_descriptors(&self) -> &'buf [u8] {
193 let lft = Self::HEADER_SZ;
194 let mut rght = lft + (self.descriptors_loop_length() as usize);
195
196 if rght >= self.buf.len() {
197 rght = self.buf.len();
198 }
199
200 &self.buf[lft..rght]
201 }
202
203 #[inline(always)]
204 pub fn descriptors(&self) -> Option<Cursor<'buf, Descriptor>> {
205 if self.descriptors_loop_length() != 0 {
206 Some(Cursor::new(self.buf_descriptors()))
207 } else {
208 None
209 }
210 }
211
212 #[inline(always)]
213 pub fn descriptors_loop_length(&self) -> u16 {
214 (u16::from(self.buf[10] & 0b0000_1111) << 8) | u16::from(self.buf[11])
215 }
216}
217
218impl<'buf> Szer for Event<'buf> {
219 #[inline(always)]
220 fn sz(&self) -> usize {
221 Self::HEADER_SZ + (self.descriptors_loop_length() as usize)
222 }
223}
224
225impl<'buf> TryNewer<'buf> for Event<'buf> {
226 #[inline(always)]
227 fn try_new(buf: &'buf [u8]) -> Result<Event<'buf>> {
228 let s = Event::new(buf);
229 s.validate()?;
230 Ok(s)
231 }
232}
233
234impl<'buf> fmt::Debug for Event<'buf> {
235 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236 write!(
237 f,
238 ":event (:start-time {} :duration {})",
239 self.start_time(),
240 DurationFmt::from(self.duration()),
241 )?;
242
243 write!(f, "\n :descriptors")?;
244 match self.descriptors() {
245 Some(descs) => {
246 for resd in descs {
247 write!(f, "\n ")?;
248 match resd {
249 Ok(d) => {
250 d.fmt(f)?;
251 }
252 Err(err) => {
253 write!(f, "error parse descriptor: {}", err)?;
254 }
255 }
256 }
257 }
258 None => write!(f, " ~")?,
259 }
260
261 Ok(())
262 }
263}