EBML: Implement integer parsing

Signed-off-by: Serial <69764315+Serial-ATA@users.noreply.github.com>
This commit is contained in:
Serial 2023-11-25 12:36:44 -05:00
parent ca7e3fe237
commit f928d0a51a
No known key found for this signature in database
GPG key ID: DA95198DC17C4568
2 changed files with 35 additions and 9 deletions

View file

@ -299,15 +299,41 @@ where
Ok(())
}
pub(crate) fn read_signed_int(&mut self) -> Result<i64> {
todo!()
pub(crate) fn read_signed_int(&mut self, element_length: u64) -> Result<i64> {
// https://www.rfc-editor.org/rfc/rfc8794.html#section-7.1
// A Signed Integer Element MUST declare a length from zero to eight octets
if element_length > 8 {
decode_err!(@BAIL Ebml, "Invalid size for signed int element")
}
let mut buf = [0; 8];
self.reader
.read_exact(&mut buf[8 - element_length as usize..])?;
let value = u64::from_be_bytes(buf);
// Signed Integers are stored with two's complement notation with the leftmost bit being the sign bit.
let value_width = element_length * 8;
let shift = (64 - value_width) as u32;
Ok((value.wrapping_shl(shift) as i64).wrapping_shr(shift))
}
pub(crate) fn read_unsigned_int(&mut self) -> Result<u64> {
todo!()
pub(crate) fn read_unsigned_int(&mut self, element_length: u64) -> Result<u64> {
// https://www.rfc-editor.org/rfc/rfc8794.html#section-7.2
// An Unsigned Integer Element MUST declare a length from zero to eight octets
if element_length > 8 {
decode_err!(@BAIL Ebml, "Invalid size for unsigned int element")
}
let mut buf = [0; 8];
self.reader
.read_exact(&mut buf[8 - element_length as usize..])?;
Ok(u64::from_be_bytes(buf))
}
pub(crate) fn read_float(&mut self, element_length: u64) -> Result<f64> {
// https://www.rfc-editor.org/rfc/rfc8794.html#section-7.3
// A Float Element MUST declare a length of either zero octets (0 bit),
// four octets (32 bit), or eight octets (64 bit)
Ok(match element_length {
0 => 0.0,
4 => f64::from(self.reader.read_f32::<BigEndian>()?),

View file

@ -94,13 +94,13 @@ where
}
if ident == ElementIdent::EBMLMaxIDLength {
properties.header.max_id_length = element_reader.read_unsigned_int()? as u8;
properties.header.max_id_length = element_reader.read_unsigned_int(size)? as u8;
element_reader.set_max_id_length(properties.header.max_id_length);
continue;
}
if ident == ElementIdent::EBMLMaxSizeLength {
properties.header.max_size_length = element_reader.read_unsigned_int()? as u8;
properties.header.max_size_length = element_reader.read_unsigned_int(size)? as u8;
element_reader.set_max_size_length(properties.header.max_size_length);
continue;
}
@ -114,14 +114,14 @@ where
match ident {
ElementIdent::EBMLVersion => {
properties.header.version = element_reader.read_unsigned_int()?
properties.header.version = element_reader.read_unsigned_int(size)?
},
ElementIdent::EBMLReadVersion => {
properties.header.read_version = element_reader.read_unsigned_int()?
properties.header.read_version = element_reader.read_unsigned_int(size)?
},
ElementIdent::DocType => properties.header.doc_type = element_reader.read_string()?,
ElementIdent::DocTypeVersion => {
properties.header.doc_type_version = element_reader.read_unsigned_int()?
properties.header.doc_type_version = element_reader.read_unsigned_int(size)?
},
_ => element_reader.skip(size)?,
}