ozlrip-decode 0.2.0

OpenZL decoder for ozlrip
Documentation
#![cfg_attr(feature = "paranoid", forbid(unsafe_code))]
#![allow(
    clippy::cast_ptr_alignment,
    reason = "fast bit readers use read_unaligned on byte-derived pointers"
)]

pub(super) fn read_window(bytes: &[u8], byte_pos: usize, needed_bytes: usize) -> Option<u128> {
    #[cfg(not(feature = "paranoid"))]
    {
        if let Some(value) = read_window_fast(bytes, byte_pos, needed_bytes) {
            return Some(value);
        }
    }
    read_window_safe(bytes, byte_pos, needed_bytes)
}

#[cfg(not(feature = "paranoid"))]
pub(super) fn read_window_u32(bytes: &[u8], byte_pos: usize, needed_bytes: usize) -> Option<u32> {
    let remaining = bytes.len().checked_sub(byte_pos)?;
    if needed_bytes <= 4 && remaining >= 4 {
        let ptr = bytes.as_ptr().wrapping_add(byte_pos).cast::<u32>();
        unsafe {
            return Some(u32::from_le(core::ptr::read_unaligned(ptr)));
        }
    }

    let byte_end = byte_pos.checked_add(needed_bytes)?;
    let bytes = bytes.get(byte_pos..byte_end)?;
    let mut value = 0u32;
    for (shift, &byte) in bytes.iter().enumerate() {
        value |= u32::from(byte) << (shift * 8);
    }
    Some(value)
}

#[cfg(feature = "paranoid")]
pub(super) fn read_window_u32(bytes: &[u8], byte_pos: usize, needed_bytes: usize) -> Option<u32> {
    if needed_bytes <= 4
        && let Some(bytes) = bytes.get(byte_pos..byte_pos.checked_add(4)?)
    {
        return Some(u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]));
    }

    let byte_end = byte_pos.checked_add(needed_bytes)?;
    let bytes = bytes.get(byte_pos..byte_end)?;
    let mut value = 0u32;
    for (shift, &byte) in bytes.iter().enumerate() {
        value |= u32::from(byte) << (shift * 8);
    }
    Some(value)
}

fn read_window_safe(bytes: &[u8], byte_pos: usize, needed_bytes: usize) -> Option<u128> {
    let byte_end = byte_pos.checked_add(needed_bytes)?;
    let bytes = bytes.get(byte_pos..byte_end)?;
    let mut value = 0u128;
    for (shift, &byte) in bytes.iter().enumerate() {
        value |= u128::from(byte) << (shift * 8);
    }
    Some(value)
}

#[cfg(not(feature = "paranoid"))]
fn read_window_fast(bytes: &[u8], byte_pos: usize, needed_bytes: usize) -> Option<u128> {
    let remaining = bytes.len().checked_sub(byte_pos)?;
    if needed_bytes <= 8 && remaining >= 8 {
        let ptr = bytes.as_ptr().wrapping_add(byte_pos).cast::<u64>();
        unsafe {
            return Some(u128::from(u64::from_le(core::ptr::read_unaligned(ptr))));
        }
    }
    if needed_bytes <= 16 && remaining >= 16 {
        let ptr = bytes.as_ptr().wrapping_add(byte_pos).cast::<u128>();
        unsafe {
            return Some(u128::from_le(core::ptr::read_unaligned(ptr)));
        }
    }
    None
}