1#![forbid(unsafe_code)]
4#![deny(rust_2018_idioms, future_incompatible)]
5
6pub mod sdt;
7
8use mpeg2ts_reader::descriptor::UnknownDescriptor;
9
10use crate::sdt::ServiceDescriptor;
11use encoding::Encoding;
12use std::borrow::Cow;
13use std::fmt;
14
15mpeg2ts_reader::descriptor_enum! {
16 #[derive(Debug)]
21 En300_468Descriptors {
22 Reserved 0|1|36..=63 => UnknownDescriptor,
23 VideoStream 2 => UnknownDescriptor,
24 AudioStream 3 => UnknownDescriptor,
25 Hierarchy 4 => UnknownDescriptor,
26 Registration 5 => UnknownDescriptor,
27 DataStreamAlignment 6 => UnknownDescriptor,
28 TargetBackgroundGrid 7 => UnknownDescriptor,
29 VideoWindow 8 => UnknownDescriptor,
30 CA 9 => UnknownDescriptor,
31 ISO639Language 10 => UnknownDescriptor,
32 SystemClock 11 => UnknownDescriptor,
33 MultiplexBufferUtilization 12 => UnknownDescriptor,
34 Copyright 13 => UnknownDescriptor,
35 MaximumBitrate 14 => UnknownDescriptor,
36 PrivateDataIndicator 15 => UnknownDescriptor,
37 SmoothingBuffer 16 => UnknownDescriptor,
38 STD 17 => UnknownDescriptor,
39 IBP 18 => UnknownDescriptor,
40 IsoIec13818dash6 19..=26 => UnknownDescriptor,
42 MPEG4Video 27 => UnknownDescriptor,
43 MPEG4Audio 28 => UnknownDescriptor,
44 IOD 29 => UnknownDescriptor,
45 SL 30 => UnknownDescriptor,
46 FMC 31 => UnknownDescriptor,
47 ExternalESID 32 => UnknownDescriptor,
48 MuxCode 33 => UnknownDescriptor,
49 FmxBufferSize 34 => UnknownDescriptor,
50 MultiplexBuffer 35 => UnknownDescriptor,
51 UserPrivate 69..=70|103..=254 => UnknownDescriptor,
52
53 NetworkName 0x40 => UnknownDescriptor,
55 ServiceList 0x41 => UnknownDescriptor,
56 Stuffing 0x42 => UnknownDescriptor,
57 SatelliteDeliverySystem 0x43 => UnknownDescriptor,
58 CableDeliverySystem 0x44 => UnknownDescriptor,
59 BouquetName 0x47 => UnknownDescriptor,
60
61 Service ServiceDescriptor::TAG => ServiceDescriptor,
62
63 CountryAvailability 0x49 => UnknownDescriptor,
64 Linkage 0x4A => UnknownDescriptor,
65 NvodReference 0x4B => UnknownDescriptor,
66 TimeShiftedService 0x4C => UnknownDescriptor,
67 ShortEvent 0x4D => UnknownDescriptor,
68 ExtendedEvent 0x4E => UnknownDescriptor,
69 TimeShiftedEvent 0x4F => UnknownDescriptor,
70 Component 0x50 => UnknownDescriptor,
71 Mosaic 0x51 => UnknownDescriptor,
72 StreamIdentifier 0x52 => UnknownDescriptor,
73 CaIdentifier 0x53 => UnknownDescriptor,
74 Content 0x54 => UnknownDescriptor,
75 ParentalRating 0x55 => UnknownDescriptor,
76 Teletext 0x56 => UnknownDescriptor,
77 Telephone 0x57 => UnknownDescriptor,
78 LocalTimeOffset 0x58 => UnknownDescriptor,
79 Subtitling 0x59 => UnknownDescriptor,
80 TerrestrialDeliverySystem 0x5A => UnknownDescriptor,
81 MultilingualNetworkName 0x5B => UnknownDescriptor,
82 MultilingualBouquetName 0x5C => UnknownDescriptor,
83 MultilingualServiceName 0x5D => UnknownDescriptor,
84 MultilingualComponent 0x5E => UnknownDescriptor,
85 PrivateDataSpecifier 0x5F => UnknownDescriptor,
86 ServiceMove 0x60 => UnknownDescriptor,
87 ShortSmoothingBuffer 0x61 => UnknownDescriptor,
88 FrequencyList 0x62 => UnknownDescriptor,
89 PartialTransportStream 0x63 => UnknownDescriptor,
90 DataBroadcast 0x64 => UnknownDescriptor,
91 CaSystem 0x65 => UnknownDescriptor,
92 DataBroadcastId 0x66 => UnknownDescriptor,
93 Forbidden 0xFF => UnknownDescriptor,
94 }
95}
96
97#[derive(Debug)]
99pub enum TextEncoding {
100 Reserved1(u8),
101 Reserved2(u8, u8),
102 Iso88591,
104 Iso88592,
106 Iso88593,
108 Iso88594,
110 Iso88595,
112 Iso88596,
114 Iso88597,
116 Iso88598,
118 Iso88599,
120 Iso885910,
122 Iso885911,
124 Iso885913,
126 Iso885914,
128 Iso885915,
130 Iso10646,
132 KSX1001_2004,
134 GB2312_1980,
136 Big5,
138 UTF8,
140}
141
142pub enum ActualOther<T> {
149 Actual(T),
151 Other(T),
153}
154impl<T> ActualOther<T> {
155 pub fn actual(&self) -> Option<&T> {
156 match self {
157 ActualOther::Actual(ref v) => Some(v),
158 ActualOther::Other(_) => None,
159 }
160 }
161 pub fn other(&self) -> Option<&T> {
162 match self {
163 ActualOther::Actual(_) => None,
164 ActualOther::Other(ref v) => Some(v),
165 }
166 }
167}
168
169#[derive(Debug)]
171pub enum TextError {
172 NotEnoughData { expected: usize, available: usize },
173 DecodeFailure(Cow<'static, str>),
174 UnsupportedEncoding(TextEncoding),
175}
176
177pub struct Text<'buf> {
180 data: &'buf [u8],
181}
182impl<'buf> Text<'buf> {
183 pub fn new(data: &'buf [u8]) -> Result<Text<'buf>, TextError> {
184 if data.is_empty() {
185 Err(TextError::NotEnoughData {
186 expected: 1,
187 available: 0,
188 })
189 } else {
190 Ok(Text { data })
191 }
192 }
193 pub fn encoding(&self) -> TextEncoding {
194 let id = self.data[0];
195 match id {
196 0x20..=0xff => TextEncoding::Iso88591,
197 0x01 => TextEncoding::Iso88595,
198 0x02 => TextEncoding::Iso88596,
199 0x03 => TextEncoding::Iso88597,
200 0x04 => TextEncoding::Iso88598,
201 0x05 => TextEncoding::Iso88599,
202 0x06 => TextEncoding::Iso885910,
203 0x07 => TextEncoding::Iso885911,
204 0x08 => TextEncoding::Reserved1(id),
205 0x09 => TextEncoding::Iso885913,
206 0x0a => TextEncoding::Iso885914,
207 0x0b => TextEncoding::Iso885915,
208 0x0c..=0x0f => TextEncoding::Reserved1(id),
209 0x10 => {
210 let ids = (self.data[1], self.data[2]);
211 match ids {
212 (0x00, 0x00) => TextEncoding::Reserved2(ids.0, ids.1),
213 (0x00, 0x01) => TextEncoding::Iso88591,
214 (0x00, 0x02) => TextEncoding::Iso88592,
215 (0x00, 0x03) => TextEncoding::Iso88593,
216 (0x00, 0x04) => TextEncoding::Iso88594,
217 (0x00, 0x05) => TextEncoding::Iso88595,
218 (0x00, 0x06) => TextEncoding::Iso88596,
219 (0x00, 0x07) => TextEncoding::Iso88597,
220 (0x00, 0x08) => TextEncoding::Iso88598,
221 (0x00, 0x09) => TextEncoding::Iso88599,
222 (0x00, 0x0a) => TextEncoding::Iso885910,
223 (0x00, 0x0b) => TextEncoding::Iso885911,
224 (0x00, 0x0c) => TextEncoding::Reserved2(ids.0, ids.1),
225 (0x00, 0x0d) => TextEncoding::Iso885913,
226 (0x00, 0x0e) => TextEncoding::Iso885914,
227 (0x00, 0x0f) => TextEncoding::Iso885915,
228 _ => TextEncoding::Reserved2(ids.0, ids.1),
229 }
230 }
231 0x11 => TextEncoding::Iso10646,
232 0x12 => TextEncoding::KSX1001_2004,
233 0x13 => TextEncoding::GB2312_1980,
234 0x14 => TextEncoding::Big5,
235 0x15 => TextEncoding::UTF8,
236 0x16..=0x1E => TextEncoding::Reserved1(id),
237 0x1F => unimplemented!("encoding_type_id"),
238 _ => unreachable!(),
239 }
240 }
241 fn buffer(&self) -> Result<&'buf [u8], TextError> {
242 Ok(&self.data[self.enc_prefix_len()?..])
243 }
244 fn enc_prefix_len(&self) -> Result<usize, TextError> {
245 match self.data[0] {
246 0x01..=0x0f | 0x11..=0x1e => Ok(1),
247 0x1f => Ok(2), 0x10 => {
249 if self.data.len() < 3 {
250 Err(TextError::NotEnoughData {
251 expected: 3,
252 available: self.data.len(),
253 })
254 } else {
255 Ok(3)
256 }
257 }
258 0x20..=0xff => Ok(0),
259 _ => unreachable!(),
260 }
261 }
262
263 pub fn to_string(&self, trap: encoding::types::DecoderTrap) -> Result<String, TextError> {
264 let enc = self.encoding();
265 match enc {
266 TextEncoding::Iso88591 => encoding::all::ISO_8859_1
267 .decode(self.buffer()?, trap)
268 .map_err(TextError::DecodeFailure),
269 TextEncoding::Iso88592 => encoding::all::ISO_8859_2
270 .decode(self.buffer()?, trap)
271 .map_err(TextError::DecodeFailure),
272 TextEncoding::Iso88593 => encoding::all::ISO_8859_3
273 .decode(self.buffer()?, trap)
274 .map_err(TextError::DecodeFailure),
275 TextEncoding::Iso88594 => encoding::all::ISO_8859_4
276 .decode(self.buffer()?, trap)
277 .map_err(TextError::DecodeFailure),
278 TextEncoding::Iso88595 => encoding::all::ISO_8859_5
279 .decode(self.buffer()?, trap)
280 .map_err(TextError::DecodeFailure),
281 TextEncoding::Iso88596 => encoding::all::ISO_8859_6
282 .decode(self.buffer()?, trap)
283 .map_err(TextError::DecodeFailure),
284 TextEncoding::Iso88597 => encoding::all::ISO_8859_7
285 .decode(self.buffer()?, trap)
286 .map_err(TextError::DecodeFailure),
287 TextEncoding::Iso88598 => encoding::all::ISO_8859_8
288 .decode(self.buffer()?, trap)
289 .map_err(TextError::DecodeFailure),
290 TextEncoding::Iso88599 => Err(TextError::UnsupportedEncoding(enc)),
291 TextEncoding::Iso885910 => encoding::all::ISO_8859_10
292 .decode(self.buffer()?, trap)
293 .map_err(TextError::DecodeFailure),
294 TextEncoding::Iso885911 => Err(TextError::UnsupportedEncoding(enc)),
295 TextEncoding::Iso885913 => encoding::all::ISO_8859_13
296 .decode(self.buffer()?, trap)
297 .map_err(TextError::DecodeFailure),
298 TextEncoding::Iso885914 => encoding::all::ISO_8859_14
299 .decode(self.buffer()?, trap)
300 .map_err(TextError::DecodeFailure),
301 TextEncoding::Iso885915 => encoding::all::ISO_8859_15
302 .decode(self.buffer()?, trap)
303 .map_err(TextError::DecodeFailure),
304 TextEncoding::Reserved1(..) => Err(TextError::UnsupportedEncoding(enc)),
305 TextEncoding::Reserved2(..) => Err(TextError::UnsupportedEncoding(enc)),
306 TextEncoding::Iso10646 => Err(TextError::UnsupportedEncoding(enc)),
307 TextEncoding::KSX1001_2004 => Err(TextError::UnsupportedEncoding(enc)),
308 TextEncoding::GB2312_1980 => Err(TextError::UnsupportedEncoding(enc)),
309 TextEncoding::Big5 => encoding::all::BIG5_2003
310 .decode(self.buffer()?, trap)
311 .map_err(TextError::DecodeFailure),
312 TextEncoding::UTF8 => encoding::all::UTF_8
313 .decode(self.buffer()?, trap)
314 .map_err(TextError::DecodeFailure),
315 }
316 }
317}
318impl<'buf> fmt::Debug for Text<'buf> {
319 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
320 fmt::Debug::fmt(&self.to_string(encoding::DecoderTrap::Replace), f)
321 }
322}