From 14f217c4ca976adfe9ca5b13961ee29dee9c84bc Mon Sep 17 00:00:00 2001 From: Gwen Lg Date: Sun, 12 May 2024 20:24:52 +0200 Subject: [PATCH] create dedicated error entries for sub module instead of use a generic `Parse` with a message. --- src/vobsub/mod.rs | 53 +++++++++++++++++++++++++++++++++++++++++++---- src/vobsub/sub.rs | 34 ++++++++++++++---------------- 2 files changed, 64 insertions(+), 23 deletions(-) diff --git a/src/vobsub/mod.rs b/src/vobsub/mod.rs index 930d579..262222d 100644 --- a/src/vobsub/mod.rs +++ b/src/vobsub/mod.rs @@ -100,17 +100,62 @@ pub enum VobSubError { #[error("Error during palette pasing from .idx file")] PaletteError(#[source] NomError), + /// If Scan line offsets values are not correct. + #[error("invalid scan line offsets : start 0 {start_0}, start 1 {start_1}, end {end}")] + InvalidScanLineOffsets { + /// Start 0 + start_0: usize, + /// Start 1 + start_1: usize, + /// End + end: usize, + }, + + /// If the buffer is too Small for parsing a 16-bits value. + #[error("unexpected end of buffer while parsing 16-bit size")] + BufferTooSmallForU16, + + /// If the buffer is too small to parse a subtitle. + #[error("unexpected end of subtitle data")] + UnexpectedEndOfSubtitleData, + + /// If an error happen during `Control sequence` parsing. + #[error("Error with Control sequence parsing.")] + ControlSequence(#[source] NomError), + + /// If the control offset value tried to leads backwards. + #[error("control offset value tried to leads backwards")] + ControlOffsetWentBackwards, + + /// If `control offset` is bigger than packet size. + #[error("control offset is 0x{offset:x}, but packet is only 0x{packet:x} bytes")] + ControlOffsetBiggerThanPacket { + /// Control offset + offset: usize, + /// Packet size + packet: usize, + }, + /// If an error happen during `PES Packet` parsing. #[error("PES packet parsing.")] PESPacket(#[source] NomError), + + /// If the `control packet` is incmplete + #[error("Incomplete control packet")] + IncompleteControlPacket, + + /// Packet is too short, not bigger to read his size. + #[error("Packet is too short")] + PacketTooShort, + + /// If timing info for Subtitle is missing. + #[error("found subtitle without timing into")] + MissingTimingForSubtitle, + /// We could not process a subtitle image. #[error("Could not process subtitle image: {0}")] Image(String), - /// If an error happen during parsing with `nom`. - #[error("Parsing error.")] - NomParsing(#[from] NomError), - /// Io error on a path. #[error("Io error on '{path}'")] Io { diff --git a/src/vobsub/sub.rs b/src/vobsub/sub.rs index 98bb875..462cdb1 100644 --- a/src/vobsub/sub.rs +++ b/src/vobsub/sub.rs @@ -276,9 +276,7 @@ impl fmt::Debug for Subtitle { /// because it has an inconvenient error type. fn parse_be_u16_as_usize(buff: &[u8]) -> Result<(&[u8], usize), VobSubError> { if buff.len() < 2 { - Err(VobSubError::Parse( - "unexpected end of buffer while parsing 16-bit size".into(), - )) + Err(VobSubError::BufferTooSmallForU16) } else { Ok((&buff[2..], usize::from(buff[0]) << 8 | usize::from(buff[1]))) } @@ -291,7 +289,7 @@ fn subtitle(raw_data: &[u8], base_time: f64) -> Result { // Figure out where our control data starts. if raw_data.len() < 2 { - return Err(VobSubError::Parse("unexpected end of subtitle data".into())); + return Err(VobSubError::UnexpectedEndOfSubtitleData); } let (_, initial_control_offset) = parse_be_u16_as_usize(&raw_data[2..])?; @@ -309,18 +307,16 @@ fn subtitle(raw_data: &[u8], base_time: f64) -> Result { loop { trace!("looking for control sequence at: 0x{:x}", control_offset); if control_offset >= raw_data.len() { - return Err(VobSubError::Parse(format!( - "control offset is 0x{:x}, but packet is only 0x{:x} \ - bytes", - control_offset, - raw_data.len() - ))); + return Err(VobSubError::ControlOffsetBiggerThanPacket { + offset: control_offset, + packet: raw_data.len(), + }); } let control_data = &raw_data[control_offset..]; let (_, control) = control_sequence(control_data) .to_result() - .map_err(VobSubError::NomParsing)?; + .map_err(VobSubError::ControlSequence)?; trace!("parsed control sequence: {:?}", &control); @@ -361,7 +357,7 @@ fn subtitle(raw_data: &[u8], base_time: f64) -> Result { let next_control_offset = cast::usize(control.next); match control_offset.cmp(&next_control_offset) { Ordering::Greater => { - return Err(VobSubError::Parse("control offset went backwards".into())); + return Err(VobSubError::ControlOffsetWentBackwards); } Ordering::Equal => { // This points back at us, so we're the last packet. @@ -399,7 +395,11 @@ fn subtitle(raw_data: &[u8], base_time: f64) -> Result { let start_1 = cast::usize(rle_offsets[1]); let end = cast::usize(initial_control_offset + 2); if start_0 > start_1 || start_1 > end { - return Err(VobSubError::Parse("invalid scan line offsets".into())); + return Err(VobSubError::InvalidScanLineOffsets { + start_0, + start_1, + end, + }); } let image = decompress( area.size(), @@ -452,11 +452,7 @@ impl<'a> Iterator for SubtitlesInternal<'a> { // Fetch useful information from our first packet. let pts_dts = match first.pes_packet.header_data.pts_dts { Some(v) => v, - None => { - return Some(Err(VobSubError::Parse( - "found subtitle without timing into".into(), - ))) - } + None => return Some(Err(VobSubError::MissingTimingForSubtitle)), }; let base_time = pts_dts.pts.as_seconds(); let substream_id = first.pes_packet.substream_id; @@ -464,7 +460,7 @@ impl<'a> Iterator for SubtitlesInternal<'a> { // Figure out how many total bytes we'll need to collect from one // or more PES packets, and collect the first chunk into a buffer. if first.pes_packet.data.len() < 2 { - return Some(Err(VobSubError::Parse("packet is too short".into()))); + return Some(Err(VobSubError::PacketTooShort)); } let wanted = usize::from(first.pes_packet.data[0]) << 8 | usize::from(first.pes_packet.data[1]);