#[inline] #[allow(dead_code)] fn low_bits_of_u64(val: u64) -> u8 { let byte = val & u64::from(core::u8::MAX);
low_bits_of_byte(byte as u8)
}
/// A module for reading signed and unsigned integers that have been LEB128 /// encoded. #[cfg(feature = "read-core")] pubmod read { usesuper::{low_bits_of_byte, CONTINUATION_BIT, SIGN_BIT}; usecrate::read::{Error, Reader, Result};
/// Read bytes until the LEB128 continuation bit is not set. pubfn skip<R: Reader>(r: &mut R) -> Result<()> { loop { let byte = r.read_u8()?; if byte & CONTINUATION_BIT == 0 { return Ok(());
}
}
}
/// Read an unsigned LEB128 number from the given `Reader` and /// return it or an error if reading failed. pubfn unsigned<R: Reader>(r: &mut R) -> Result<u64> { letmut result = 0; letmut shift = 0;
let low_bits = u64::from(low_bits_of_byte(byte));
result |= low_bits << shift;
if byte & CONTINUATION_BIT == 0 { return Ok(result);
}
shift += 7;
}
}
/// Read an LEB128 u16 from the given `Reader` and /// return it or an error if reading failed. pubfn u16<R: Reader>(r: &mut R) -> Result<u16> { let byte = r.read_u8()?; letmut result = u16::from(low_bits_of_byte(byte)); if byte & CONTINUATION_BIT == 0 { return Ok(result);
}
let byte = r.read_u8()?;
result |= u16::from(low_bits_of_byte(byte)) << 7; if byte & CONTINUATION_BIT == 0 { return Ok(result);
}
let byte = r.read_u8()?; if byte > 0x03 { return Err(Error::BadUnsignedLeb128);
}
result += u16::from(byte) << 14;
Ok(result)
}
/// Read a signed LEB128 number from the given `Reader` and /// return it or an error if reading failed. pubfn signed<R: Reader>(r: &mut R) -> Result<i64> { letmut result = 0; letmut shift = 0; let size = 64; letmut byte;
let low_bits = i64::from(low_bits_of_byte(byte));
result |= low_bits << shift;
shift += 7;
if byte & CONTINUATION_BIT == 0 { break;
}
}
if shift < size && (SIGN_BIT & byte) == SIGN_BIT { // Sign extend the result.
result |= !0 << shift;
}
Ok(result)
}
}
/// A module for writing integers encoded as LEB128. #[cfg(feature = "write")] pubmod write { usesuper::{low_bits_of_u64, CONTINUATION_BIT}; use std::io;
/// Write the given unsigned number using the LEB128 encoding to the given /// `std::io::Write`able. Returns the number of bytes written to `w`, or an /// error if writing failed. pubfn unsigned<W>(w: &mut W, mut val: u64) -> Result<usize, io::Error> where
W: io::Write,
{ letmut bytes_written = 0; loop { letmut byte = low_bits_of_u64(val);
val >>= 7; if val != 0 { // More bytes to come, so set the continuation bit.
byte |= CONTINUATION_BIT;
}
let buf = [byte];
w.write_all(&buf)?;
bytes_written += 1;
if val == 0 { return Ok(bytes_written);
}
}
}
/// Return the size of the LEB128 encoding of the given unsigned number. pubfn uleb128_size(mut val: u64) -> usize { letmut size = 0; loop {
val >>= 7;
size += 1; if val == 0 { return size;
}
}
}
/// Write the given signed number using the LEB128 encoding to the given /// `std::io::Write`able. Returns the number of bytes written to `w`, or an /// error if writing failed. pubfn signed<W>(w: &mut W, mut val: i64) -> Result<usize, io::Error> where
W: io::Write,
{ letmut bytes_written = 0; loop { letmut byte = val as u8; // Keep the sign bit for testing
val >>= 6; let done = val == 0 || val == -1; if done {
byte &= !CONTINUATION_BIT;
} else { // Remove the sign bit
val >>= 1; // More bytes to come, so set the continuation bit.
byte |= CONTINUATION_BIT;
}
let buf = [byte];
w.write_all(&buf)?;
bytes_written += 1;
if done { return Ok(bytes_written);
}
}
}
/// Return the size of the LEB128 encoding of the given signed number. pubfn sleb128_size(mut val: i64) -> usize { letmut size = 0; loop {
val >>= 6; let done = val == 0 || val == -1;
val >>= 1;
size += 1; if done { return size;
}
}
}
}
impl<T> ResultExt for Result<T, Error> { fn map_eof(self, input: &[u8]) -> Self { matchself {
Err(Error::UnexpectedEof(id)) => { let id = ReaderOffsetId(id.0 - input.as_ptr() as u64);
Err(Error::UnexpectedEof(id))
}
r => r,
}
}
}
#[test] fn test_low_bits_of_byte() { for i in0..127 {
assert_eq!(i, low_bits_of_byte(i));
assert_eq!(i, low_bits_of_byte(i | CONTINUATION_BIT));
}
}
#[test] fn test_low_bits_of_u64() { for i in0u64..127 {
assert_eq!(i as u8, low_bits_of_u64(1 << 16 | i));
assert_eq!(
i as u8,
low_bits_of_u64(i << 16 | i | (u64::from(CONTINUATION_BIT)))
);
}
}
letmut readable = EndianSlice::new(&buf[..], NativeEndian); let result = read::signed(&mut readable).expect("Should be able to read it back again");
assert_eq!(i, result);
} for i in -513..513 {
inner(i);
}
inner(core::i64::MIN);
}
#[test] fn dogfood_unsigned() { for i in0..1025 { letmut buf = [0u8; 1024];
letmut readable = EndianSlice::new(&buf[..], NativeEndian); let result =
read::unsigned(&mut readable).expect("Should be able to read it back again");
assert_eq!(i, result);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.