mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-11-10 06:34:18 +00:00
Make everything in ogg_pager fallible
This commit is contained in:
parent
a25680f8e2
commit
1068d707b2
3 changed files with 118 additions and 94 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "ogg_pager"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
authors = ["Serial <69764315+Serial-ATA@users.noreply.github.com>"]
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
|
|
@ -1,69 +1,69 @@
|
|||
#[rustfmt::skip]
|
||||
const CRC_LOOKUP_ARRAY : &[u32] = &[
|
||||
0x0000_0000, 0x04c1_1db7, 0x0982_3b6e, 0x0d43_26d9,
|
||||
0x1304_76dc, 0x17c5_6b6b, 0x1a86_4db2, 0x1e47_5005,
|
||||
0x2608_edb8, 0x22c9_f00f, 0x2f8a_d6d6, 0x2b4b_cb61,
|
||||
0x350c_9b64, 0x31cd_86d3, 0x3c8e_a00a, 0x384f_bdbd,
|
||||
0x4c11_db70, 0x48d0_c6c7, 0x4593_e01e, 0x4152_fda9,
|
||||
0x5f15_adac, 0x5bd4_b01b, 0x5697_96c2, 0x5256_8b75,
|
||||
0x6a19_36c8, 0x6ed8_2b7f, 0x639b_0da6, 0x675a_1011,
|
||||
0x791d_4014, 0x7ddc_5da3, 0x709f_7b7a, 0x745e_66cd,
|
||||
0x9823_b6e0, 0x9ce2_ab57, 0x91a1_8d8e, 0x9560_9039,
|
||||
0x8b27_c03c, 0x8fe6_dd8b, 0x82a5_fb52, 0x8664_e6e5,
|
||||
0xbe2b_5b58, 0xbaea_46ef, 0xb7a9_6036, 0xb368_7d81,
|
||||
0xad2f_2d84, 0xa9ee_3033, 0xa4ad_16ea, 0xa06c_0b5d,
|
||||
0xd432_6d90, 0xd0f3_7027, 0xddb0_56fe, 0xd971_4b49,
|
||||
0xc736_1b4c, 0xc3f7_06fb, 0xceb4_2022, 0xca75_3d95,
|
||||
0xf23a_8028, 0xf6fb_9d9f, 0xfbb8_bb46, 0xff79_a6f1,
|
||||
0xe13e_f6f4, 0xe5ff_eb43, 0xe8bc_cd9a, 0xec7d_d02d,
|
||||
0x3486_7077, 0x3047_6dc0, 0x3d04_4b19, 0x39c5_56ae,
|
||||
0x2782_06ab, 0x2343_1b1c, 0x2e00_3dc5, 0x2ac1_2072,
|
||||
0x128e_9dcf, 0x164f_8078, 0x1b0c_a6a1, 0x1fcd_bb16,
|
||||
0x018a_eb13, 0x054b_f6a4, 0x0808_d07d, 0x0cc9_cdca,
|
||||
0x7897_ab07, 0x7c56_b6b0, 0x7115_9069, 0x75d4_8dde,
|
||||
0x6b93_dddb, 0x6f52_c06c, 0x6211_e6b5, 0x66d0_fb02,
|
||||
0x5e9f_46bf, 0x5a5e_5b08, 0x571d_7dd1, 0x53dc_6066,
|
||||
0x4d9b_3063, 0x495a_2dd4, 0x4419_0b0d, 0x40d8_16ba,
|
||||
0xaca5_c697, 0xa864_db20, 0xa527_fdf9, 0xa1e6_e04e,
|
||||
0xbfa1_b04b, 0xbb60_adfc, 0xb623_8b25, 0xb2e2_9692,
|
||||
0x8aad_2b2f, 0x8e6c_3698, 0x832f_1041, 0x87ee_0df6,
|
||||
0x99a9_5df3, 0x9d68_4044, 0x902b_669d, 0x94ea_7b2a,
|
||||
0xe0b4_1de7, 0xe475_0050, 0xe936_2689, 0xedf7_3b3e,
|
||||
0xf3b0_6b3b, 0xf771_768c, 0xfa32_5055, 0xfef3_4de2,
|
||||
0xc6bc_f05f, 0xc27d_ede8, 0xcf3e_cb31, 0xcbff_d686,
|
||||
0xd5b8_8683, 0xd179_9b34, 0xdc3a_bded, 0xd8fb_a05a,
|
||||
0x690c_e0ee, 0x6dcd_fd59, 0x608e_db80, 0x644f_c637,
|
||||
0x7a08_9632, 0x7ec9_8b85, 0x738a_ad5c, 0x774b_b0eb,
|
||||
0x4f04_0d56, 0x4bc5_10e1, 0x4686_3638, 0x4247_2b8f,
|
||||
0x5c00_7b8a, 0x58c1_663d, 0x5582_40e4, 0x5143_5d53,
|
||||
0x251d_3b9e, 0x21dc_2629, 0x2c9f_00f0, 0x285e_1d47,
|
||||
0x3619_4d42, 0x32d8_50f5, 0x3f9b_762c, 0x3b5a_6b9b,
|
||||
0x0315_d626, 0x07d4_cb91, 0x0a97_ed48, 0x0e56_f0ff,
|
||||
0x1011_a0fa, 0x14d0_bd4d, 0x1993_9b94, 0x1d52_8623,
|
||||
0xf12f_560e, 0xf5ee_4bb9, 0xf8ad_6d60, 0xfc6c_70d7,
|
||||
0xe22b_20d2, 0xe6ea_3d65, 0xeba9_1bbc, 0xef68_060b,
|
||||
0xd727_bbb6, 0xd3e6_a601, 0xdea5_80d8, 0xda64_9d6f,
|
||||
0xc423_cd6a, 0xc0e2_d0dd, 0xcda1_f604, 0xc960_ebb3,
|
||||
0xbd3e_8d7e, 0xb9ff_90c9, 0xb4bc_b610, 0xb07d_aba7,
|
||||
0xae3a_fba2, 0xaafb_e615, 0xa7b8_c0cc, 0xa379_dd7b,
|
||||
0x9b36_60c6, 0x9ff7_7d71, 0x92b4_5ba8, 0x9675_461f,
|
||||
0x8832_161a, 0x8cf3_0bad, 0x81b0_2d74, 0x8571_30c3,
|
||||
0x5d8a_9099, 0x594b_8d2e, 0x5408_abf7, 0x50c9_b640,
|
||||
0x4e8e_e645, 0x4a4f_fbf2, 0x470c_dd2b, 0x43cd_c09c,
|
||||
0x7b82_7d21, 0x7f43_6096, 0x7200_464f, 0x76c1_5bf8,
|
||||
0x6886_0bfd, 0x6c47_164a, 0x6104_3093, 0x65c5_2d24,
|
||||
0x119b_4be9, 0x155a_565e, 0x1819_7087, 0x1cd8_6d30,
|
||||
0x029f_3d35, 0x065e_2082, 0x0b1d_065b, 0x0fdc_1bec,
|
||||
0x3793_a651, 0x3352_bbe6, 0x3e11_9d3f, 0x3ad0_8088,
|
||||
0x2497_d08d, 0x2056_cd3a, 0x2d15_ebe3, 0x29d4_f654,
|
||||
0xc5a9_2679, 0xc168_3bce, 0xcc2b_1d17, 0xc8ea_00a0,
|
||||
0xd6ad_50a5, 0xd26c_4d12, 0xdf2f_6bcb, 0xdbee_767c,
|
||||
0xe3a1_cbc1, 0xe760_d676, 0xea23_f0af, 0xeee2_ed18,
|
||||
0xf0a5_bd1d, 0xf464_a0aa, 0xf927_8673, 0xfde6_9bc4,
|
||||
0x89b8_fd09, 0x8d79_e0be, 0x803a_c667, 0x84fb_dbd0,
|
||||
0x9abc_8bd5, 0x9e7d_9662, 0x933e_b0bb, 0x97ff_ad0c,
|
||||
0xafb0_10b1, 0xab71_0d06, 0xa632_2bdf, 0xa2f3_3668,
|
||||
0xbcb4_666d, 0xb875_7bda, 0xb536_5d03, 0xb1f7_40b4
|
||||
static CRC_LOOKUP_ARRAY: [u32; 256] = [
|
||||
0x0000_0000, 0x04C1_1DB7, 0x0982_3B6E, 0x0D43_26D9,
|
||||
0x1304_76DC, 0x17C5_6B6B, 0x1A86_4DB2, 0x1E47_5005,
|
||||
0x2608_EDB8, 0x22C9_F00F, 0x2F8A_D6D6, 0x2B4B_CB61,
|
||||
0x350C_9B64, 0x31CD_86D3, 0x3C8E_A00A, 0x384F_BDBD,
|
||||
0x4C11_DB70, 0x48D0_C6C7, 0x4593_E01E, 0x4152_FDA9,
|
||||
0x5F15_ADAC, 0x5BD4_B01B, 0x5697_96C2, 0x5256_8B75,
|
||||
0x6A19_36C8, 0x6ED8_2B7F, 0x639B_0DA6, 0x675A_1011,
|
||||
0x791D_4014, 0x7DDC_5DA3, 0x709F_7B7A, 0x745E_66CD,
|
||||
0x9823_B6E0, 0x9CE2_AB57, 0x91A1_8D8E, 0x9560_9039,
|
||||
0x8B27_C03C, 0x8FE6_DD8B, 0x82A5_FB52, 0x8664_E6E5,
|
||||
0xBE2B_5B58, 0xBAEA_46EF, 0xB7A9_6036, 0xB368_7D81,
|
||||
0xAD2F_2D84, 0xA9EE_3033, 0xA4AD_16EA, 0xA06C_0B5D,
|
||||
0xD432_6D90, 0xD0F3_7027, 0xDDB0_56FE, 0xD971_4B49,
|
||||
0xC736_1B4C, 0xC3F7_06FB, 0xCEB4_2022, 0xCA75_3D95,
|
||||
0xF23A_8028, 0xF6FB_9D9F, 0xFBB8_BB46, 0xFF79_A6F1,
|
||||
0xE13E_F6F4, 0xE5FF_EB43, 0xE8BC_CD9A, 0xEC7D_D02D,
|
||||
0x3486_7077, 0x3047_6DC0, 0x3D04_4B19, 0x39C5_56AE,
|
||||
0x2782_06AB, 0x2343_1B1C, 0x2E00_3DC5, 0x2AC1_2072,
|
||||
0x128E_9DCF, 0x164F_8078, 0x1B0C_A6A1, 0x1FCD_BB16,
|
||||
0x018A_EB13, 0x054B_F6A4, 0x0808_D07D, 0x0CC9_CDCA,
|
||||
0x7897_AB07, 0x7C56_B6B0, 0x7115_9069, 0x75D4_8DDE,
|
||||
0x6B93_DDDB, 0x6F52_C06C, 0x6211_E6B5, 0x66D0_FB02,
|
||||
0x5E9F_46BF, 0x5A5E_5B08, 0x571D_7DD1, 0x53DC_6066,
|
||||
0x4D9B_3063, 0x495A_2DD4, 0x4419_0B0D, 0x40D8_16BA,
|
||||
0xACA5_C697, 0xA864_DB20, 0xA527_FDF9, 0xA1E6_E04E,
|
||||
0xBFA1_B04B, 0xBB60_ADFC, 0xB623_8B25, 0xB2E2_9692,
|
||||
0x8AAD_2B2F, 0x8E6C_3698, 0x832F_1041, 0x87EE_0DF6,
|
||||
0x99A9_5DF3, 0x9D68_4044, 0x902B_669D, 0x94EA_7B2A,
|
||||
0xE0B4_1DE7, 0xE475_0050, 0xE936_2689, 0xEDF7_3B3E,
|
||||
0xF3B0_6B3B, 0xF771_768C, 0xFA32_5055, 0xFEF3_4DE2,
|
||||
0xC6BC_F05F, 0xC27D_EDE8, 0xCF3E_CB31, 0xCBFF_D686,
|
||||
0xD5B8_8683, 0xD179_9B34, 0xDC3A_BDED, 0xD8FB_A05A,
|
||||
0x690C_E0EE, 0x6DCD_FD59, 0x608E_DB80, 0x644F_C637,
|
||||
0x7A08_9632, 0x7EC9_8B85, 0x738A_AD5C, 0x774B_B0EB,
|
||||
0x4F04_0D56, 0x4BC5_10E1, 0x4686_3638, 0x4247_2B8F,
|
||||
0x5C00_7B8A, 0x58C1_663D, 0x5582_40E4, 0x5143_5D53,
|
||||
0x251D_3B9E, 0x21DC_2629, 0x2C9F_00F0, 0x285E_1D47,
|
||||
0x3619_4D42, 0x32D8_50F5, 0x3F9B_762C, 0x3B5A_6B9B,
|
||||
0x0315_D626, 0x07D4_CB91, 0x0A97_ED48, 0x0E56_F0FF,
|
||||
0x1011_A0FA, 0x14D0_BD4D, 0x1993_9B94, 0x1D52_8623,
|
||||
0xF12F_560E, 0xF5EE_4BB9, 0xF8AD_6D60, 0xFC6C_70D7,
|
||||
0xE22B_20D2, 0xE6EA_3D65, 0xEBA9_1BBC, 0xEF68_060B,
|
||||
0xD727_BBB6, 0xD3E6_A601, 0xDEA5_80D8, 0xDA64_9D6F,
|
||||
0xC423_CD6A, 0xC0E2_D0DD, 0xCDA1_F604, 0xC960_EBB3,
|
||||
0xBD3E_8D7E, 0xB9FF_90C9, 0xB4BC_B610, 0xB07D_ABA7,
|
||||
0xAE3A_FBA2, 0xAAFB_E615, 0xA7B8_C0CC, 0xA379_DD7B,
|
||||
0x9B36_60C6, 0x9FF7_7D71, 0x92B4_5BA8, 0x9675_461F,
|
||||
0x8832_161A, 0x8CF3_0BAD, 0x81B0_2D74, 0x8571_30C3,
|
||||
0x5D8A_9099, 0x594B_8D2E, 0x5408_ABF7, 0x50C9_B640,
|
||||
0x4E8E_E645, 0x4A4F_FBF2, 0x470C_DD2B, 0x43CD_C09C,
|
||||
0x7B82_7D21, 0x7F43_6096, 0x7200_464F, 0x76C1_5BF8,
|
||||
0x6886_0BFD, 0x6C47_164A, 0x6104_3093, 0x65C5_2D24,
|
||||
0x119B_4BE9, 0x155A_565E, 0x1819_7087, 0x1CD8_6D30,
|
||||
0x029F_3D35, 0x065E_2082, 0x0B1D_065B, 0x0FDC_1BEC,
|
||||
0x3793_A651, 0x3352_BBE6, 0x3E11_9D3F, 0x3AD0_8088,
|
||||
0x2497_D08D, 0x2056_CD3A, 0x2D15_EBE3, 0x29D4_F654,
|
||||
0xC5A9_2679, 0xC168_3BCE, 0xCC2B_1D17, 0xC8EA_00A0,
|
||||
0xD6AD_50A5, 0xD26C_4D12, 0xDF2F_6BCB, 0xDBEE_767C,
|
||||
0xE3A1_CBC1, 0xE760_D676, 0xEA23_F0AF, 0xEEE2_ED18,
|
||||
0xF0A5_BD1D, 0xF464_A0AA, 0xF927_8673, 0xFDE6_9BC4,
|
||||
0x89B8_FD09, 0x8D79_E0BE, 0x803A_C667, 0x84FB_DBD0,
|
||||
0x9ABC_8BD5, 0x9E7D_9662, 0x933E_B0BB, 0x97FF_AD0C,
|
||||
0xAFB0_10B1, 0xAB71_0D06, 0xA632_2BDF, 0xA2F3_3668,
|
||||
0xBCB4_666D, 0xB875_7BDA, 0xB536_5D03, 0xB1F7_40B4,
|
||||
];
|
||||
|
||||
/// Generates a CRC checksum based on the content
|
||||
|
|
|
@ -35,7 +35,6 @@ pub struct Page {
|
|||
pub start: u64,
|
||||
/// The position in the stream the page ended
|
||||
pub end: u64,
|
||||
segment_table: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Page {
|
||||
|
@ -49,7 +48,7 @@ impl Page {
|
|||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// See [`segment_table`]
|
||||
/// `content.len()` > [`MAX_CONTENT_SIZE`]
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -74,8 +73,11 @@ impl Page {
|
|||
sequence_number: u32,
|
||||
content: Vec<u8>,
|
||||
) -> Result<Self> {
|
||||
let len = content.len();
|
||||
let segment_table = segment_table(len)?;
|
||||
let content_len = content.len();
|
||||
|
||||
if content_len > MAX_CONTENT_SIZE {
|
||||
return Err(PageError::TooMuchData);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
content,
|
||||
|
@ -85,16 +87,20 @@ impl Page {
|
|||
seq_num: sequence_number,
|
||||
checksum: 0,
|
||||
start: 0,
|
||||
end: len as u64,
|
||||
segment_table,
|
||||
end: content_len as u64,
|
||||
})
|
||||
}
|
||||
|
||||
/// Convert the Page to Vec<u8> for writing
|
||||
///
|
||||
/// NOTE: This will write the checksum as is. It is likely [Page::gen_crc] will have
|
||||
/// NOTE: This will write the checksum as is. It is likely [`Page::gen_crc`] will have
|
||||
/// to be used prior.
|
||||
pub fn as_bytes(&self) -> Vec<u8> {
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// See [`segment_table`]
|
||||
pub fn as_bytes(&self) -> Result<Vec<u8>> {
|
||||
let mut segment_table = self.segment_table()?;
|
||||
let mut bytes = Vec::new();
|
||||
|
||||
bytes.extend(b"OggS");
|
||||
|
@ -104,11 +110,11 @@ impl Page {
|
|||
bytes.extend(self.serial.to_le_bytes());
|
||||
bytes.extend(self.seq_num.to_le_bytes());
|
||||
bytes.extend(self.checksum.to_le_bytes());
|
||||
bytes.push(self.segment_table.len() as u8);
|
||||
bytes.extend(self.segment_table.iter());
|
||||
bytes.push(segment_table.len() as u8);
|
||||
bytes.append(&mut segment_table);
|
||||
bytes.extend(self.content.iter());
|
||||
|
||||
bytes
|
||||
Ok(bytes)
|
||||
}
|
||||
|
||||
/// Attempts to get a Page from a reader
|
||||
|
@ -176,20 +182,30 @@ impl Page {
|
|||
checksum,
|
||||
start,
|
||||
end,
|
||||
segment_table,
|
||||
})
|
||||
}
|
||||
|
||||
/// Generates the CRC checksum of the page
|
||||
pub fn gen_crc(&mut self) {
|
||||
self.checksum = crc::crc32(&*self.as_bytes());
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// See [`Page::as_bytes`]
|
||||
pub fn gen_crc(&mut self) -> Result<()> {
|
||||
self.checksum = crc::crc32(&*self.as_bytes()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Extends the Page's content, returning another Page if too much data was provided
|
||||
///
|
||||
/// This will do nothing if `content` is greater than the max page size. In this case,
|
||||
/// [`paginate`] should be used.
|
||||
pub fn extend(&mut self, content: &[u8]) -> Option<Page> {
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// *Only applicable if a new page is created*:
|
||||
///
|
||||
/// See [`Page::gen_crc`]
|
||||
pub fn extend(&mut self, content: &[u8]) -> Result<Option<Page>> {
|
||||
let self_len = self.content.len();
|
||||
let content_len = content.len();
|
||||
|
||||
|
@ -197,7 +213,7 @@ impl Page {
|
|||
self.content.extend(content.iter());
|
||||
self.end += content_len as u64;
|
||||
|
||||
return None;
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
if content_len <= MAX_CONTENT_SIZE {
|
||||
|
@ -217,15 +233,14 @@ impl Page {
|
|||
checksum: 0,
|
||||
start: self.end,
|
||||
end: self.start + content.len() as u64,
|
||||
segment_table: vec![],
|
||||
};
|
||||
|
||||
p.gen_crc();
|
||||
p.gen_crc()?;
|
||||
|
||||
return Some(p);
|
||||
return Ok(Some(p));
|
||||
}
|
||||
|
||||
None
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Returns the page's content
|
||||
|
@ -244,13 +259,20 @@ impl Page {
|
|||
}
|
||||
|
||||
/// Returns the page's checksum
|
||||
///
|
||||
/// NOTE: This will not generate a new CRC. It will return
|
||||
/// the CRC as-is. Use [`Page::gen_crc`] to generate a new one.
|
||||
pub fn checksum(&self) -> u32 {
|
||||
self.checksum
|
||||
}
|
||||
|
||||
/// Returns the page's segment table
|
||||
pub fn segment_table(&self) -> &[u8] {
|
||||
self.segment_table.as_slice()
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// See [`segment_table`]
|
||||
pub fn segment_table(&self) -> Result<Vec<u8>> {
|
||||
segment_table(self.content.len())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,8 +319,6 @@ pub fn paginate(packet: &[u8], stream_serial: u32, abgp: u64, flags: u8) -> Vec<
|
|||
pos += page.len() as u64;
|
||||
pos
|
||||
},
|
||||
// Safe to unwrap, since we are working with chunks no bigger than the max page size
|
||||
segment_table: segment_table(page.len()).unwrap(),
|
||||
};
|
||||
|
||||
first_page = false;
|
||||
|
@ -358,7 +378,7 @@ pub fn segment_table(length: usize) -> Result<Vec<u8>> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{paginate, Page};
|
||||
use crate::{paginate, segment_table, Page};
|
||||
use std::io::Cursor;
|
||||
|
||||
#[test]
|
||||
|
@ -375,7 +395,6 @@ mod tests {
|
|||
checksum: 3579522525,
|
||||
start: 0,
|
||||
end: 47,
|
||||
segment_table: vec![0x13],
|
||||
};
|
||||
|
||||
let content = std::fs::read("test_assets/opus_ident_header.page").unwrap();
|
||||
|
@ -394,9 +413,14 @@ mod tests {
|
|||
let len = pages.len();
|
||||
|
||||
assert_eq!(len, 17);
|
||||
let last_page_content = pages.last().unwrap().content();
|
||||
|
||||
assert_eq!(
|
||||
len % 255,
|
||||
*pages.last().unwrap().segment_table.last().unwrap() as usize
|
||||
last_page_content.len() % 255,
|
||||
*segment_table(last_page_content.len())
|
||||
.unwrap()
|
||||
.last()
|
||||
.unwrap() as usize
|
||||
);
|
||||
|
||||
for (i, page) in pages.into_iter().enumerate() {
|
||||
|
|
Loading…
Reference in a new issue