use crate::error::UVarintError;
pub fn decode_u32(data: &[u8]) -> Result<(usize, u32), UVarintError> {
let mut value: u32 = 0;
for (i, &byte) in data.iter().take(5).enumerate() {
let data_bits = (byte & 0x7F) as u32;
value = value
.checked_add(
data_bits
.checked_shl(i as u32 * 7)
.ok_or(UVarintError::Overflow)?,
)
.ok_or(UVarintError::Overflow)?;
if (byte & 0x80) == 0 {
return Ok((i + 1, value));
}
}
Err(UVarintError::Incomplete)
}
pub fn decode_u64(data: &[u8]) -> Result<(usize, u64), UVarintError> {
let mut value: u64 = 0;
for (i, &byte) in data.iter().take(10).enumerate() {
let data_bits = (byte & 0x7F) as u64;
value = value
.checked_add(
data_bits
.checked_shl(i as u32 * 7)
.ok_or(UVarintError::Overflow)?,
)
.ok_or(UVarintError::Overflow)?;
if (byte & 0x80) == 0 {
return Ok((i + 1, value));
}
}
Err(UVarintError::Incomplete)
}
pub fn decode_u128(data: &[u8]) -> Result<(usize, u128), UVarintError> {
let mut value: u128 = 0;
for (i, &byte) in data.iter().take(19).enumerate() {
let data_bits = (byte & 0x7F) as u128;
value = value
.checked_add(
data_bits
.checked_shl(i as u32 * 7)
.ok_or(UVarintError::Overflow)?,
)
.ok_or(UVarintError::Overflow)?;
if (byte & 0x80) == 0 {
return Ok((i + 1, value));
}
}
Err(UVarintError::Incomplete)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_single_byte_u32_values() {
assert_eq!(decode_u32(&[0x00]).unwrap(), (1, 0));
assert_eq!(decode_u32(&[0x01]).unwrap(), (1, 1));
assert_eq!(decode_u32(&[0x05]).unwrap(), (1, 5));
assert_eq!(decode_u32(&[0x7F]).unwrap(), (1, 127));
}
#[test]
fn test_two_byte_u32_values() {
assert_eq!(decode_u32(&[0x80, 0x01]).unwrap(), (2, 128));
assert_eq!(decode_u32(&[0xAC, 0x02]).unwrap(), (2, 300));
assert_eq!(decode_u32(&[0xFF, 0x7F]).unwrap(), (2, 16_383));
}
#[test]
fn test_single_byte_u64_values() {
assert_eq!(decode_u64(&[0x00]).unwrap(), (1, 0));
assert_eq!(decode_u64(&[0x01]).unwrap(), (1, 1));
assert_eq!(decode_u64(&[0x05]).unwrap(), (1, 5));
assert_eq!(decode_u64(&[0x7F]).unwrap(), (1, 127));
}
#[test]
fn test_two_byte_u64_values() {
assert_eq!(decode_u64(&[0x80, 0x01]).unwrap(), (2, 128));
assert_eq!(decode_u64(&[0xAC, 0x02]).unwrap(), (2, 300));
assert_eq!(decode_u64(&[0xFF, 0x7F]).unwrap(), (2, 16_383));
}
#[test]
fn test_single_byte_u128_values() {
assert_eq!(decode_u128(&[0x00]).unwrap(), (1, 0));
assert_eq!(decode_u128(&[0x01]).unwrap(), (1, 1));
assert_eq!(decode_u128(&[0x05]).unwrap(), (1, 5));
assert_eq!(decode_u128(&[0x7F]).unwrap(), (1, 127));
}
#[test]
fn test_two_byte_u128_values() {
assert_eq!(decode_u128(&[0x80, 0x01]).unwrap(), (2, 128));
assert_eq!(decode_u128(&[0xAC, 0x02]).unwrap(), (2, 300));
assert_eq!(decode_u128(&[0xFF, 0x7F]).unwrap(), (2, 16_383));
}
}