diff --git a/ogg_pager/src/packets.rs b/ogg_pager/src/packets.rs index 682d29eb..46e56d2c 100644 --- a/ogg_pager/src/packets.rs +++ b/ogg_pager/src/packets.rs @@ -3,6 +3,7 @@ use crate::header::PageHeader; use crate::paginate::paginate; use crate::Page; +use std::fmt::{Debug, Formatter}; use std::io::{Read, Seek, Write}; /// A container for packets in an OGG file @@ -62,6 +63,7 @@ impl Packets { /// let packets = Packets::read_count(&mut file, 2)?; /// # Ok(()) } /// ``` + #[allow(clippy::read_zero_byte_vec)] pub fn read_count(data: &mut R, count: isize) -> Result where R: Read + Seek, @@ -79,6 +81,7 @@ impl Packets { let mut read = 0; let mut packet_size = 0_u64; + let mut packet_bytes_already_read = None; let mut current_packet_content; 'outer: loop { if let Ok((_, segment_table)) = PageHeader::read(data) { @@ -90,11 +93,17 @@ impl Packets { read += 1; } - current_packet_content = vec![0; packet_size as usize]; + let byte_count_to_read = Self::get_byte_count_to_read( + packet_size, + &mut packet_bytes_already_read, + ); + + current_packet_content = vec![0; byte_count_to_read as usize]; data.read_exact(&mut current_packet_content)?; packet_sizes.push(packet_size); packet_size = 0; + packet_bytes_already_read = None; content.append(&mut current_packet_content); @@ -106,8 +115,12 @@ impl Packets { // The packet continues on the next page, write what we can so far if packet_size != 0 { - current_packet_content = vec![0; packet_size as usize]; + let byte_count_to_read = + Self::get_byte_count_to_read(packet_size, &mut packet_bytes_already_read); + + current_packet_content = vec![0; byte_count_to_read as usize]; data.read_exact(&mut current_packet_content)?; + content.append(&mut current_packet_content); } continue; @@ -126,6 +139,25 @@ impl Packets { }) } + fn get_byte_count_to_read( + packet_size: u64, + packet_bytes_already_read: &mut Option, + ) -> u64 { + let byte_count_to_read; + match packet_bytes_already_read { + Some(already_read_bytes_count) => { + byte_count_to_read = packet_size - *already_read_bytes_count; + *packet_bytes_already_read = Some(*already_read_bytes_count + byte_count_to_read); + }, + None => { + byte_count_to_read = packet_size; + *packet_bytes_already_read = Some(packet_size); + }, + }; + + byte_count_to_read + } + /// Gets the packet at a specified index, returning its contents /// /// NOTES: @@ -352,3 +384,12 @@ impl<'a> IntoIterator for &'a Packets { } } } + +impl Debug for Packets { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Packets") + .field("total_bytes", &self.content.len()) + .field("count", &self.packet_sizes.len()) + .finish() + } +}