Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,6 @@ mod are `PacketReader` and `PacketWriter`.
#[cfg(test)]
mod test;

macro_rules! tri {
($e:expr) => {
match $e {
Ok(val) => val,
Err(err) => return Err(err.into()),
}
};
}

mod crc;
pub mod reading;
pub mod writing;
Expand Down
69 changes: 34 additions & 35 deletions src/reading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,9 @@ impl PageParser {
pub fn new_with_parse_opts(header_buf :[u8; 27], parse_opts :impl Into<Arc<PageParsingOptions>>) -> Result<(PageParser, usize), OggReadError> {
let mut header_rdr = Cursor::new(header_buf);
header_rdr.set_position(4);
let stream_structure_version = tri!(header_rdr.read_u8());
let stream_structure_version = header_rdr.read_u8()?;
if stream_structure_version != 0 {
tri!(Err(OggReadError::InvalidStreamStructVer(stream_structure_version)));
return Err(OggReadError::InvalidStreamStructVer(stream_structure_version));
}
let header_type_flag = header_rdr.read_u8().unwrap();
let absgp = header_rdr.read_u64::<LittleEndian>().unwrap();
Expand Down Expand Up @@ -336,7 +336,7 @@ impl PageParser {

// 3. Compare to the extracted one
if self.checksum != hash_calculated {
tri!(Err(OggReadError::HashMismatch(self.checksum, hash_calculated)));
return Err(OggReadError::HashMismatch(self.checksum, hash_calculated));
}
}
self.segments_or_packets_buf = packet_data;
Expand Down Expand Up @@ -471,11 +471,11 @@ impl BasePacketReader {
Entry::Occupied(mut o) => {
let inf = o.get_mut();
if pg_prs.bi.first_page {
tri!(Err(OggReadError::InvalidData));
return Err(OggReadError::InvalidData);
}
if pg_prs.bi.starts_with_continued != inf.bi.ends_with_continued {
if !self.has_seeked {
tri!(Err(OggReadError::InvalidData));
return Err(OggReadError::InvalidData);
} else {
// If we have seeked, we are more tolerant here,
// and just drop the continued packet's content.
Expand Down Expand Up @@ -517,7 +517,7 @@ impl BasePacketReader {
if !self.has_seeked {
if !pg_prs.bi.first_page || pg_prs.bi.starts_with_continued {
// If we haven't seeked, this is an error.
tri!(Err(OggReadError::InvalidData));
return Err(OggReadError::InvalidData);
}
} else {
if !pg_prs.bi.first_page {
Expand Down Expand Up @@ -635,7 +635,7 @@ impl UntilPageHeaderReader {
// and must well fit into an i32 (needs to be stored in SeekNeeded)
let mut buf :[u8; 1024] = [0; 1024];

let rd_len = tri!(rdr.read(if self.read_amount < 27 {
let rd_len = rdr.read(if self.read_amount < 27 {
// This is an optimisation for the most likely case:
// the next page directly follows the current read position.
// Then it would be a waste to read more than the needed amount.
Expand All @@ -647,7 +647,7 @@ impl UntilPageHeaderReader {
SeekNeeded(_) => return Ok(Res::SeekNeeded),
Found => return Ok(Res::Found),
}
}));
})?;

if rd_len == 0 {
// Reached EOF. This means we're in one of these cases:
Expand All @@ -672,7 +672,7 @@ impl UntilPageHeaderReader {
if self.read_amount > read_amount_max {
// Exhaustive searching for the capture pattern
// has returned no ogg capture pattern.
tri!(Err(OggReadError::NoCapturePatternFound));
return Err(OggReadError::NoCapturePatternFound);
}

let rd_buf = &buf[0 .. rd_len];
Expand Down Expand Up @@ -733,7 +733,7 @@ impl UntilPageHeaderReader {
match self.mode {
Searching | FoundWithNeeded(_) => Ok(Res::ReadNeeded),
SeekNeeded(offs) => {
tri!(skr.seek(SeekFrom::Current(offs as i64)));
skr.seek(SeekFrom::Current(offs as i64))?;
self.mode = Found;
Ok(Res::Found)
},
Expand Down Expand Up @@ -806,9 +806,8 @@ impl<T :io::Read + io::Seek> PacketReader<T> {
if let Some(pck) = self.base_pck_rdr.read_packet() {
return Ok(Some(pck));
}
let page = tri!(self.read_ogg_page());
match page {
Some(page) => tri!(self.base_pck_rdr.push_page(page)),
match self.read_ogg_page()? {
Some(page) => self.base_pck_rdr.push_page(page)?,
None => return Ok(None),
}
}
Expand All @@ -819,10 +818,10 @@ impl<T :io::Read + io::Seek> PacketReader<T> {
/// returns an Err(_) if the physical stream has ended.
/// This function is useful if you expect a new packet to come.
pub fn read_packet_expected(&mut self) -> Result<Packet, OggReadError> {
match tri!(self.read_packet()) {
match self.read_packet()? {
Some(p) => Ok(p),
None => tri!(Err(Error::new(ErrorKind::UnexpectedEof,
"Expected ogg packet but found end of physical stream"))),
None => Err(Error::new(ErrorKind::UnexpectedEof,
"Expected ogg packet but found end of physical stream").into()),
}
}

Expand All @@ -837,7 +836,7 @@ impl<T :io::Read + io::Seek> PacketReader<T> {
fn read_until_pg_header(&mut self) -> Result<Option<[u8; 27]>, OggReadError> {
let mut r = UntilPageHeaderReader::new();
use self::UntilPageHeaderResult::*;
let mut res = tri!(r.do_read(&mut self.rdr));
let mut res = r.do_read(&mut self.rdr)?;
loop {
res = match res {
Eof => return Ok(None),
Expand All @@ -847,8 +846,8 @@ impl<T :io::Read + io::Seek> PacketReader<T> {
self.read_some_pg = true;
break
},
ReadNeeded => tri!(r.do_read(&mut self.rdr)),
SeekNeeded => tri!(r.do_seek(&mut self.rdr))
ReadNeeded => r.do_read(&mut self.rdr)?,
SeekNeeded => r.do_seek(&mut self.rdr)?,
}
}
Ok(Some(r.into_header()))
Expand All @@ -860,22 +859,22 @@ impl<T :io::Read + io::Seek> PacketReader<T> {
/// is at the current reader position.
/// Instead it searches until it finds the capture pattern.
fn read_ogg_page(&mut self) -> Result<Option<OggPage>, OggReadError> {
let header_buf :[u8; 27] = match tri!(self.read_until_pg_header()) {
let header_buf :[u8; 27] = match self.read_until_pg_header()? {
Some(s) => s,
None if self.read_some_pg => return Ok(None),
None => return Err(OggReadError::NoCapturePatternFound)
};
let (mut pg_prs, page_segments) = tri!(PageParser::new_with_parse_opts(header_buf, Arc::clone(&self.pg_parse_opts)));
let (mut pg_prs, page_segments) = PageParser::new_with_parse_opts(header_buf, Arc::clone(&self.pg_parse_opts))?;

let mut segments_buf = vec![0; page_segments]; // TODO fix this, we initialize memory for NOTHING!!! Out of some reason, this is seen as "unsafe" by rustc.
tri!(self.rdr.read_exact(&mut segments_buf));
self.rdr.read_exact(&mut segments_buf)?;

let page_siz = pg_prs.parse_segments(segments_buf);

let mut packet_data = vec![0; page_siz];
tri!(self.rdr.read_exact(&mut packet_data));
self.rdr.read_exact(&mut packet_data)?;

Ok(Some(tri!(pg_prs.parse_packet_data(packet_data))))
Ok(Some(pg_prs.parse_packet_data(packet_data)?))
}

/// Seeks the underlying reader
Expand All @@ -885,7 +884,7 @@ impl<T :io::Read + io::Seek> PacketReader<T> {
///
/// This also flushes all the unread packets in the queue.
pub fn seek_bytes(&mut self, pos :SeekFrom) -> Result<u64, Error> {
let r = tri!(self.rdr.seek(pos));
let r = self.rdr.seek(pos)?;
// Reset the internal state
self.base_pck_rdr.update_after_seek();
return Ok(r);
Expand All @@ -912,14 +911,14 @@ impl<T :io::Read + io::Seek> PacketReader<T> {
macro_rules! found {
($pos:expr) => {{
// println!("found: {}", $pos);
tri!(self.rdr.seek(SeekFrom::Start($pos)));
self.rdr.seek(SeekFrom::Start($pos))?;
self.base_pck_rdr.update_after_seek();
return Ok(true);
}};
}
macro_rules! bt {
($e:expr) => {{
match tri!($e) {
match $e? {
Some(s) => s,
None => return Ok(false),
}
Expand Down Expand Up @@ -965,7 +964,7 @@ impl<T :io::Read + io::Seek> PacketReader<T> {
let mut pg;
let mut continued_pck_start = None;
loop {
pos = tri!(self.rdr.seek(SeekFrom::Current(0)));
pos = self.rdr.seek(SeekFrom::Current(0))?;
pg = bt!(self.read_ogg_page());
/*println!("absgp {} serial {} wh {} pe {} @ {}",
pg.0.bi.absgp, pg.0.bi.sequence_num,
Expand Down Expand Up @@ -1007,7 +1006,7 @@ impl<T :io::Read + io::Seek> PacketReader<T> {

// First, find initial "boundaries"
// Seek to the start of the file to get the starting boundary
tri!(self.rdr.seek(SeekFrom::Start(0)));
self.rdr.seek(SeekFrom::Start(0))?;
let (mut begin_pos, mut begin_pg) = pg_read_match_serial!();

// If the goal is the beginning, we are done.
Expand All @@ -1019,7 +1018,7 @@ impl<T :io::Read + io::Seek> PacketReader<T> {
// Seek to the end of the file to get the ending boundary
// TODO the 200 KB is just a guessed number, any ideas
// to improve it?
tri!(seek_before_end(&mut self.rdr, 200 * 1024));
seek_before_end(&mut self.rdr, 200 * 1024)?;
let (mut end_pos, mut end_pg) = pg_read_until_end_or_goal!(pos_goal);

// Then perform the bisection
Expand All @@ -1031,7 +1030,7 @@ impl<T :io::Read + io::Seek> PacketReader<T> {
}
// Perform the bisection step
let pos_to_seek = begin_pos + (end_pos - begin_pos) / 2;
tri!(self.rdr.seek(SeekFrom::Start(pos_to_seek)));
self.rdr.seek(SeekFrom::Start(pos_to_seek))?;
let (pos, pg) = pg_read_match_serial!();
/*println!("seek {} {} . {} @ {} {} . {}",
ab_of(&begin_pg), ab_of(&end_pg), ab_of(&pg),
Expand All @@ -1045,9 +1044,9 @@ impl<T :io::Read + io::Seek> PacketReader<T> {
let mut pos;
let mut pg;
let mut last_packet_end_pos = begin_pos;
tri!(self.rdr.seek(SeekFrom::Start(begin_pos)));
self.rdr.seek(SeekFrom::Start(begin_pos))?;
loop {
pos = tri!(self.rdr.stream_position());
pos = self.rdr.stream_position()?;
pg = bt!(self.read_ogg_page());
/*println!("absgp {} pck_start {} whole_pck {} pck_end {} @ {} {}",
ab_of(&pg), pg.has_packet_start(), pg.has_whole_packet(),
Expand Down Expand Up @@ -1088,9 +1087,9 @@ impl<T :io::Read + io::Seek> PacketReader<T> {
// util function
fn seek_before_end<T :io::Read + io::Seek>(mut rdr :T,
offs :u64) -> Result<u64, OggReadError> {
let end_pos = tri!(rdr.seek(SeekFrom::End(0)));
let end_pos = rdr.seek(SeekFrom::End(0))?;
let end_pos_to_seek = ::std::cmp::min(end_pos, offs);
return Ok(tri!(rdr.seek(SeekFrom::End(-(end_pos_to_seek as i64)))));
return Ok(rdr.seek(SeekFrom::End(-(end_pos_to_seek as i64)))?);
}

#[cfg(feature = "async")]
Expand Down
37 changes: 18 additions & 19 deletions src/writing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,13 @@ impl <'writer, T :io::Write> PacketWriter<'writer, T> {
if segment_i + 1 < needed_segments {
// We have to flush a page, but we know there are more to come...
pg.pck_this_overflow_idx = Some((segment_i + 1) * 255);
tri!(PacketWriter::write_page(&mut self.wtr, serial, pg,
false));
PacketWriter::write_page(&mut self.wtr, serial, pg,
false)?;
} else {
// We have to write a page end, and it's the very last
// we need to write
tri!(PacketWriter::write_page(&mut self.wtr,
serial, pg, is_end_stream));
PacketWriter::write_page(&mut self.wtr,
serial, pg, is_end_stream)?;
// Not actually required
// (it is always None except if we set it to Some directly
// before we call write_page)
Expand All @@ -185,8 +185,8 @@ impl <'writer, T :io::Write> PacketWriter<'writer, T> {
}
if (inf != PacketWriteEndInfo::NormalPacket) && !at_page_end {
// Write a page end
tri!(PacketWriter::write_page(&mut self.wtr, serial, pg,
is_end_stream));
PacketWriter::write_page(&mut self.wtr, serial, pg,
is_end_stream)?;

pg.pck_last_overflow_idx = None;

Expand All @@ -202,13 +202,13 @@ impl <'writer, T :io::Write> PacketWriter<'writer, T> {
{
// The page header with everything but the lacing values:
let mut hdr_cur = Cursor::new(Vec::with_capacity(27));
tri!(hdr_cur.write_all(&[0x4f, 0x67, 0x67, 0x53, 0x00]));
hdr_cur.write_all(&[0x4f, 0x67, 0x67, 0x53, 0x00])?;
let mut flags :u8 = 0;
if pg.pck_last_overflow_idx.is_some() { flags |= 0x01; }
if pg.first_page { flags |= 0x02; }
if last_page { flags |= 0x04; }

tri!(hdr_cur.write_u8(flags));
hdr_cur.write_u8(flags)?;

let pck_data = &pg.cur_pg_data;

Expand All @@ -220,14 +220,13 @@ impl <'writer, T :io::Write> PacketWriter<'writer, T> {
}
}

tri!(hdr_cur.write_u64::<LittleEndian>(last_finishing_pck_absgp));
tri!(hdr_cur.write_u32::<LittleEndian>(serial));
tri!(hdr_cur.write_u32::<LittleEndian>(pg.sequence_num));
hdr_cur.write_u64::<LittleEndian>(last_finishing_pck_absgp)?;
hdr_cur.write_u32::<LittleEndian>(serial)?;
hdr_cur.write_u32::<LittleEndian>(pg.sequence_num)?;

// checksum, calculated later on :)
tri!(hdr_cur.write_u32::<LittleEndian>(0));

tri!(hdr_cur.write_u8(pg.segment_cnt));
hdr_cur.write_u32::<LittleEndian>(0)?;
hdr_cur.write_u8(pg.segment_cnt)?;

let mut hash_calculated :u32;

Expand Down Expand Up @@ -256,12 +255,12 @@ impl <'writer, T :io::Write> PacketWriter<'writer, T> {
// Don't do excessive checking here (that the seek
// succeeded & we are at the right pos now).
// It's hopefully not required.
tri!(hdr_cur.seek(SeekFrom::Start(22)));
tri!(hdr_cur.write_u32::<LittleEndian>(hash_calculated));
hdr_cur.seek(SeekFrom::Start(22))?;
hdr_cur.write_u32::<LittleEndian>(hash_calculated)?;

// Now all is done, write the stuff!
tri!(wtr.write_all(hdr_cur.get_ref()));
tri!(wtr.write_all(pg_lacing));
wtr.write_all(hdr_cur.get_ref())?;
wtr.write_all(pg_lacing)?;
for (idx, (pck, _)) in pck_data.iter().enumerate() {
let mut start :usize = 0;
if idx == 0 { if let Some(idx) = pg.pck_last_overflow_idx {
Expand All @@ -273,7 +272,7 @@ impl <'writer, T :io::Write> PacketWriter<'writer, T> {
end = idx;
}
}
tri!(wtr.write_all(&pck[start .. end]));
wtr.write_all(&pck[start .. end])?;
}
}

Expand Down