use crate::error::*;
fn remove_zeroes(bytes: &[u8]) -> Result<&[u8], BerError> {
match bytes {
[0] => Ok(bytes),
[0, rest @ ..] => remove_zeroes(rest),
_ => Ok(bytes),
}
}
pub(crate) fn decode_array_uint8(bytes: &[u8]) -> Result<[u8; 8], BerError> {
if is_highest_bit_set(bytes) {
return Err(BerError::IntegerNegative);
}
let input = remove_zeroes(bytes)?;
if input.len() > 8 {
return Err(BerError::IntegerTooLarge);
}
let mut output = [0u8; 8];
assert!(input.len() <= 8);
output[8_usize.saturating_sub(input.len())..].copy_from_slice(input);
Ok(output)
}
pub(crate) fn decode_array_uint4(bytes: &[u8]) -> Result<[u8; 4], BerError> {
if is_highest_bit_set(bytes) {
return Err(BerError::IntegerNegative);
}
let input = remove_zeroes(bytes)?;
if input.len() > 4 {
return Err(BerError::IntegerTooLarge);
}
let mut output = [0u8; 4];
assert!(input.len() <= 4);
output[4_usize.saturating_sub(input.len())..].copy_from_slice(input);
Ok(output)
}
pub(crate) fn decode_array_int8(input: &[u8]) -> Result<[u8; 8], BerError> {
let input = remove_zeroes(input)?;
if input.len() > 8 {
return Err(BerError::IntegerTooLarge);
}
let mut output = [0xFFu8; 8];
let offset = 8_usize.saturating_sub(input.len());
output[offset..].copy_from_slice(input);
Ok(output)
}
pub(crate) fn decode_array_int4(input: &[u8]) -> Result<[u8; 4], BerError> {
let input = remove_zeroes(input)?;
if input.len() > 4 {
return Err(BerError::IntegerTooLarge);
}
let mut output = [0xFFu8; 4];
let offset = 4_usize.saturating_sub(input.len());
output[offset..].copy_from_slice(input);
Ok(output)
}
#[inline]
pub(crate) fn is_highest_bit_set(bytes: &[u8]) -> bool {
bytes
.get(0)
.map(|byte| byte & 0b10000000 != 0)
.unwrap_or(false)
}