use nom::error::ErrorKind;
use nom::number::complete::u8;
use nom::{Err, IResult};
pub fn uleb128(input: &[u8]) -> IResult<&[u8], u64> {
let mut val: u64 = 0;
let mut shift: u32 = 0;
let mut data = input;
let mut byte: u8;
loop {
(data, byte) = u8(data)?;
let b = (byte & 0x7f) as u64;
val |= b.checked_shl(shift).ok_or(Err::Error(
nom::error::Error::new(input, ErrorKind::TooLarge),
))?;
if byte & 0x80 == 0 {
break;
}
shift += 7;
}
Ok((data, val))
}
pub fn sleb128(input: &[u8]) -> IResult<&[u8], i64> {
let mut val: i64 = 0;
let mut shift: u32 = 0;
let mut data = input;
let mut byte: u8;
loop {
(data, byte) = u8(data)?;
let b = (byte & 0x7f) as i64;
val |= b.checked_shl(shift).ok_or(Err::Error(
nom::error::Error::new(input, ErrorKind::TooLarge),
))?;
shift += 7;
if byte & 0x80 == 0 {
break;
}
}
if shift < i64::BITS && (byte & 0x40) != 0 {
val |= !0 << shift;
}
Ok((data, val))
}