diff --git a/ogg_pager/src/crc.rs b/ogg_pager/src/crc.rs index 79650f56..f6d4e6ac 100644 --- a/ogg_pager/src/crc.rs +++ b/ogg_pager/src/crc.rs @@ -67,11 +67,11 @@ const CRC_LOOKUP_ARRAY : &[u32] = &[ ]; pub fn crc32(page: &[u8]) -> u32 { - let mut crc: u32 = 0; + let mut crc: u32 = 0; - for p in page { - crc = (crc << 8) ^ CRC_LOOKUP_ARRAY[(u32::from(*p) ^ (crc >> 24)) as usize]; - } + for p in page { + crc = (crc << 8) ^ CRC_LOOKUP_ARRAY[(u32::from(*p) ^ (crc >> 24)) as usize]; + } - crc + crc } diff --git a/ogg_pager/src/error.rs b/ogg_pager/src/error.rs index ddd797fd..22fad0ae 100644 --- a/ogg_pager/src/error.rs +++ b/ogg_pager/src/error.rs @@ -5,36 +5,36 @@ pub type Result = std::result::Result; #[derive(Debug)] pub enum PageError { - InvalidVersion, - BadSegmentCount, - MissingMagic, - Io(std::io::Error), + InvalidVersion, + BadSegmentCount, + MissingMagic, + Io(std::io::Error), } impl fmt::Display for PageError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - PageError::InvalidVersion => { - write!(f, "Invalid stream structure version (Should always be 0)") - } - PageError::BadSegmentCount => write!(f, "Page has a segment count < 1"), - PageError::MissingMagic => write!(f, "Page is missing a magic signature"), - PageError::Io(..) => write!(f, "Encountered an std::io::Error"), - } - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + PageError::InvalidVersion => { + write!(f, "Invalid stream structure version (Should always be 0)") + }, + PageError::BadSegmentCount => write!(f, "Page has a segment count < 1"), + PageError::MissingMagic => write!(f, "Page is missing a magic signature"), + PageError::Io(..) => write!(f, "Encountered an std::io::Error"), + } + } } impl Error for PageError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - match *self { - PageError::Io(ref e) => Some(e), - _ => None, - } - } + fn source(&self) -> Option<&(dyn Error + 'static)> { + match *self { + PageError::Io(ref e) => Some(e), + _ => None, + } + } } impl From for PageError { - fn from(err: std::io::Error) -> PageError { - PageError::Io(err) - } -} \ No newline at end of file + fn from(err: std::io::Error) -> PageError { + PageError::Io(err) + } +} diff --git a/ogg_pager/src/lib.rs b/ogg_pager/src/lib.rs index ff389724..e3305c91 100644 --- a/ogg_pager/src/lib.rs +++ b/ogg_pager/src/lib.rs @@ -1,5 +1,5 @@ -mod error; mod crc; +mod error; use std::io::{Read, Seek, SeekFrom}; @@ -9,116 +9,120 @@ pub use error::{PageError, Result}; #[derive(Clone)] pub struct Page { - pub content: Vec, - pub header_type: u8, - pub abgp: u64, - pub serial: u32, - pub seq_num: u32, - pub checksum: u32, - pub start: usize, - pub end: usize, + pub content: Vec, + pub header_type: u8, + pub abgp: u64, + pub serial: u32, + pub seq_num: u32, + pub checksum: u32, + pub start: usize, + pub end: usize, } impl Page { - pub fn as_bytes(&self) -> Vec { - let mut bytes = Vec::new(); - let segments = self.segments(); - let segment_count = [segments.len() as u8]; + pub fn as_bytes(&self) -> Vec { + let mut bytes = Vec::new(); + let segments = self.segments(); + let segment_count = [segments.len() as u8]; - bytes.extend(b"OggS".iter()); - bytes.extend([0_u8].iter()); - bytes.extend(self.header_type.to_le_bytes().iter()); - bytes.extend(self.abgp.to_le_bytes().iter()); - bytes.extend(self.serial.to_le_bytes().iter()); - bytes.extend(self.seq_num.to_le_bytes().iter()); - bytes.extend(self.checksum.to_le_bytes().iter()); - bytes.extend(segment_count.iter()); - bytes.extend(segments.iter()); - bytes.extend(self.content.iter()); + bytes.extend(b"OggS".iter()); + bytes.extend([0_u8].iter()); + bytes.extend(self.header_type.to_le_bytes().iter()); + bytes.extend(self.abgp.to_le_bytes().iter()); + bytes.extend(self.serial.to_le_bytes().iter()); + bytes.extend(self.seq_num.to_le_bytes().iter()); + bytes.extend(self.checksum.to_le_bytes().iter()); + bytes.extend(segment_count.iter()); + bytes.extend(segments.iter()); + bytes.extend(self.content.iter()); - bytes - } + bytes + } - pub fn segments(&self) -> Vec { - let len = self.content.len(); + pub fn segments(&self) -> Vec { + segments(&*self.content) + } - let mut last_len = (len % 255) as u8; - if last_len == 0 { - last_len = 255 - } + pub fn read(mut data: V) -> Result + where + V: Read + Seek, + { + let start = data.seek(SeekFrom::Current(0))? as usize; - let mut needed = len / 255; - if needed != 255 { - needed += 1 - } + let mut sig = [0; 4]; + data.read_exact(&mut sig)?; - let mut segments = Vec::new(); + if &sig != b"OggS" { + return Err(PageError::MissingMagic); + } - for i in 0..needed { - if i + 1 < needed { - segments.push(255) - } else { - segments.push(last_len) - } - } + // Version, always 0 + let version = data.read_u8()?; - segments - } + if version != 0 { + return Err(PageError::InvalidVersion); + } - pub fn read(mut data: V) -> Result - where - V: Read + Seek, - { - let start = data.seek(SeekFrom::Current(0))? as usize; + let header_type = data.read_u8()?; - let mut sig = [0; 4]; - data.read_exact(&mut sig)?; + let abgp = data.read_u64::()?; + let serial = data.read_u32::()?; + let seq_num = data.read_u32::()?; + let checksum = data.read_u32::()?; - if &sig != b"OggS" { - return Err(PageError::MissingMagic); - } + let segments = data.read_u8()?; - // Version, always 0 - let version = data.read_u8()?; + if segments < 1 { + return Err(PageError::BadSegmentCount); + } - if version != 0 { - return Err(PageError::InvalidVersion); - } + let mut segment_table = vec![0; segments as usize]; + data.read_exact(&mut segment_table)?; - let header_type = data.read_u8()?; + let mut content = vec![0; segment_table.iter().map(|&b| b as usize).sum()]; + data.read_exact(&mut content)?; - let abgp = data.read_u64::()?; - let serial = data.read_u32::()?; - let seq_num = data.read_u32::()?; - let checksum = data.read_u32::()?; + let end = data.seek(SeekFrom::Current(0))? as usize; - let segments = data.read_u8()?; + Ok(Page { + content, + header_type, + abgp, + serial, + seq_num, + checksum, + start, + end, + }) + } - if segments < 1 { - return Err(PageError::BadSegmentCount); - } - - let mut segment_table = vec![0; segments as usize]; - data.read_exact(&mut segment_table)?; - - let mut content = vec![0; segment_table.iter().map(|&b| b as usize).sum()]; - data.read_exact(&mut content)?; - - let end = data.seek(SeekFrom::Current(0))? as usize; - - Ok(Page { - content, - header_type, - abgp, - serial, - seq_num, - checksum, - start, - end, - }) - } - - pub fn gen_crc(&mut self) { - self.checksum = crc::crc32(&*self.as_bytes()); - } + pub fn gen_crc(&mut self) { + self.checksum = crc::crc32(&*self.as_bytes()); + } } + +pub fn segments(cont: &[u8]) -> Vec { + let len = cont.len(); + + let mut last_len = (len % 255) as u8; + if last_len == 0 { + last_len = 255 + } + + let mut needed = len / 255; + if needed != 255 { + needed += 1 + } + + let mut segments = Vec::new(); + + for i in 0..needed { + if i + 1 < needed { + segments.push(255) + } else { + segments.push(last_len) + } + } + + segments +} \ No newline at end of file