Skip to content

Commit

Permalink
create dedicated error entries for sub module
Browse files Browse the repository at this point in the history
instead of use a generic `Parse` with a message.
  • Loading branch information
gwen-lg committed May 12, 2024
1 parent cdd8b57 commit 14f217c
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 23 deletions.
53 changes: 49 additions & 4 deletions src/vobsub/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
34 changes: 15 additions & 19 deletions src/vobsub/sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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])))
}
Expand All @@ -291,7 +289,7 @@ fn subtitle(raw_data: &[u8], base_time: f64) -> Result<Subtitle, VobSubError> {

// 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..])?;

Expand All @@ -309,18 +307,16 @@ fn subtitle(raw_data: &[u8], base_time: f64) -> Result<Subtitle, VobSubError> {
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);

Expand Down Expand Up @@ -361,7 +357,7 @@ fn subtitle(raw_data: &[u8], base_time: f64) -> Result<Subtitle, VobSubError> {
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.
Expand Down Expand Up @@ -399,7 +395,11 @@ fn subtitle(raw_data: &[u8], base_time: f64) -> Result<Subtitle, VobSubError> {
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(),
Expand Down Expand Up @@ -452,19 +452,15 @@ 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;

// 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]);
Expand Down

0 comments on commit 14f217c

Please sign in to comment.