#[doc(hidden)] #[inline] pubfn low_bits_of_u64(val: u64) -> u8 { let byte = val & (std::u8::MAX as u64);
low_bits_of_byte(byte as u8)
}
/// A module for reading LEB128-encoded signed and unsigned integers. pubmod read { usesuper::{low_bits_of_byte, CONTINUATION_BIT, SIGN_BIT}; use std::fmt; use std::io;
/// An error type for reading LEB128-encoded values. #[derive(Debug)] pubenum Error { /// There was an underlying IO error.
IoError(io::Error), /// The number being read is larger than can be represented.
Overflow,
}
impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { match *self {
Error::IoError(ref e) => e.fmt(f),
Error::Overflow => {
write!(f, "The number being read is larger than can be represented")
}
}
}
}
/// Read an unsigned LEB128-encoded number from the `std::io::Read` stream /// `r`. /// /// On success, return the number. pubfn unsigned<R>(r: &mut R) -> Result<u64, Error> where
R: ?Sized + io::Read,
{ letmut result = 0; letmut shift = 0;
let low_bits = low_bits_of_byte(buf[0]) as u64;
result |= low_bits << shift;
if buf[0] & CONTINUATION_BIT == 0 { return Ok(result);
}
shift += 7;
}
}
/// Read a signed LEB128-encoded number from the `std::io::Read` stream `r`. /// /// On success, return the number. pubfn signed<R>(r: &mut R) -> Result<i64, Error> where
R: ?Sized + io::Read,
{ letmut result = 0; letmut shift = 0; let size = 64; letmut byte;
let low_bits = low_bits_of_byte(byte) as i64;
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 LEB128-encoded signed and unsigned integers. pubmod write { usesuper::{low_bits_of_u64, CONTINUATION_BIT}; use std::io;
/// Write `val` to the `std::io::Write` stream `w` as an unsigned LEB128 value. /// /// On success, return the number of bytes written to `w`. pubfn unsigned<W>(w: &mut W, mut val: u64) -> Result<usize, io::Error> where
W: ?Sized + 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);
}
}
}
/// Write `val` to the `std::io::Write` stream `w` as a signed LEB128 value. /// /// On success, return the number of bytes written to `w`. pubfn signed<W>(w: &mut W, mut val: i64) -> Result<usize, io::Error> where
W: ?Sized + 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);
}
}
}
}
#[cfg(test)] mod tests { usesuper::*; use std; use std::io;
#[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 | (CONTINUATION_BIT as u64))
);
}
}
// Examples from the DWARF 4 standard, section 7.6, figure 22. #[test] fn test_read_unsigned() { let buf = [2u8]; letmut readable = &buf[..];
assert_eq!( 2,
read::unsigned(&mut readable).expect("Should read number")
);
letmut readable = &buf[..]; 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(std::i64::MIN);
}
#[test] fn dogfood_unsigned() { for i in0..1025 { letmut buf = [0u8; 1024];
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.