use std::io::{
Result,
Write,
};
pub trait Leb128WriteExt: Write {
fn write_uleb_u8(&mut self, value: u8) -> Result<()>;
fn write_uleb_u16(&mut self, value: u16) -> Result<()>;
fn write_uleb_u32(&mut self, value: u32) -> Result<()>;
fn write_uleb_u64(&mut self, value: u64) -> Result<()>;
fn write_uleb_u128(&mut self, value: u128) -> Result<()>;
fn write_uleb_usize(&mut self, value: usize) -> Result<()>;
fn write_sleb_i8(&mut self, value: i8) -> Result<()>;
fn write_sleb_i16(&mut self, value: i16) -> Result<()>;
fn write_sleb_i32(&mut self, value: i32) -> Result<()>;
fn write_sleb_i64(&mut self, value: i64) -> Result<()>;
fn write_sleb_i128(&mut self, value: i128) -> Result<()>;
fn write_sleb_isize(&mut self, value: isize) -> Result<()>;
}
impl<T> Leb128WriteExt for T
where
T: Write + ?Sized,
{
#[inline]
fn write_uleb_u8(&mut self, value: u8) -> Result<()> {
write_uleb(self, value as u128)
}
#[inline]
fn write_uleb_u16(&mut self, value: u16) -> Result<()> {
write_uleb(self, value as u128)
}
#[inline]
fn write_uleb_u32(&mut self, value: u32) -> Result<()> {
write_uleb(self, value as u128)
}
#[inline]
fn write_uleb_u64(&mut self, value: u64) -> Result<()> {
write_uleb(self, value as u128)
}
#[inline]
fn write_uleb_u128(&mut self, value: u128) -> Result<()> {
write_uleb(self, value)
}
#[inline]
fn write_uleb_usize(&mut self, value: usize) -> Result<()> {
write_uleb(self, value as u128)
}
#[inline]
fn write_sleb_i8(&mut self, value: i8) -> Result<()> {
write_sleb(self, value as i128)
}
#[inline]
fn write_sleb_i16(&mut self, value: i16) -> Result<()> {
write_sleb(self, value as i128)
}
#[inline]
fn write_sleb_i32(&mut self, value: i32) -> Result<()> {
write_sleb(self, value as i128)
}
#[inline]
fn write_sleb_i64(&mut self, value: i64) -> Result<()> {
write_sleb(self, value as i128)
}
#[inline]
fn write_sleb_i128(&mut self, value: i128) -> Result<()> {
write_sleb(self, value)
}
#[inline]
fn write_sleb_isize(&mut self, value: isize) -> Result<()> {
write_sleb(self, value as i128)
}
}
fn write_uleb<T>(writer: &mut T, value: u128) -> Result<()>
where
T: Write + ?Sized,
{
let mut remaining = value;
while remaining > 0x7f {
writer.write_all(&[((remaining as u8) & 0x7f) | 0x80])?;
remaining >>= 7;
}
writer.write_all(&[remaining as u8])
}
fn write_sleb<T>(writer: &mut T, value: i128) -> Result<()>
where
T: Write + ?Sized,
{
let mut remaining = value;
loop {
let byte = (remaining as u8) & 0x7f;
remaining >>= 7;
let is_done = (remaining == 0 && byte & 0x40 == 0) || (remaining == -1 && byte & 0x40 != 0);
if is_done {
return writer.write_all(&[byte]);
}
writer.write_all(&[byte | 0x80])?;
}
}