use super::common::{advance_byte, read_byte, read_two_le, retrieve_control_bit};
pub(crate) unsafe fn prs_calculate_decompressed_size_impl(mut source: *const u8) -> usize {
let mut control_byte = read_byte(&mut source);
let mut current_bit_position = 0;
let mut file_size = 0;
loop {
if retrieve_control_bit(&mut control_byte, &mut current_bit_position, &mut source) == 1 {
source = source.add(1);
file_size += 1;
continue;
}
if retrieve_control_bit(&mut control_byte, &mut current_bit_position, &mut source) == 1 {
if decode_long_copy(&mut source, &mut file_size) {
break;
}
} else {
decode_short_copy(
&mut control_byte,
&mut current_bit_position,
&mut source,
&mut file_size,
);
}
}
file_size
}
#[inline]
unsafe fn decode_long_copy(source: &mut *const u8, file_size: &mut usize) -> bool {
let offset = read_two_le(source);
if offset == 0 {
return true;
}
let length = offset & 0b111;
let length = if length == 0 {
read_byte(source) + 1
} else {
length + 2
};
*file_size += length;
false
}
#[inline]
unsafe fn decode_short_copy(
control_byte: &mut usize,
current_bit_position: &mut usize,
source: &mut *const u8,
file_size: &mut usize,
) {
let mut length = retrieve_control_bit(control_byte, current_bit_position, source) << 1;
length |= retrieve_control_bit(control_byte, current_bit_position, source);
length += 2;
advance_byte(source);
*file_size += length;
}