use crate::types::{lfs_block_t, lfs_size_t};
#[inline(always)]
pub fn lfs_max(a: u32, b: u32) -> u32 {
if a > b {
a
} else {
b
}
}
#[inline(always)]
pub fn lfs_min(a: u32, b: u32) -> u32 {
if a < b {
a
} else {
b
}
}
#[inline(always)]
pub fn lfs_aligndown(a: u32, alignment: u32) -> u32 {
a - (a % alignment)
}
#[inline(always)]
pub fn lfs_alignup(a: u32, alignment: u32) -> u32 {
lfs_aligndown(a + alignment - 1, alignment)
}
#[inline(always)]
pub fn lfs_npw2(a: u32) -> u32 {
let a = a.wrapping_sub(1);
let s4 = if a > 0xffff { 1 } else { 0 };
let a = a >> (s4 << 4);
let s3 = if a > 0xff { 1 } else { 0 };
let a = a >> (s3 << 3);
let s2 = if a > 0xf { 1 } else { 0 };
let a = a >> (s2 << 2);
let s1 = if a > 0x3 { 1 } else { 0 };
let a = a >> (s1 << 1);
(s4 << 4 | s3 << 3 | s2 << 2 | s1 << 1 | (a >> 1)) + 1
}
#[inline(always)]
pub fn lfs_ctz(a: u32) -> u32 {
lfs_npw2((a & a.wrapping_neg()).wrapping_add(1)) - 1
}
#[inline(always)]
pub fn lfs_popc(a: u32) -> u32 {
let a = a - ((a >> 1) & 0x5555_5555);
let a = (a & 0x3333_3333) + ((a >> 2) & 0x3333_3333);
(((a.wrapping_add(a >> 4)) & 0x0f0f_0f0f).wrapping_mul(0x0101_0101)) >> 24
}
#[inline(always)]
pub fn lfs_scmp(a: u32, b: u32) -> i32 {
(a.wrapping_sub(b)) as i32
}
#[inline(always)]
pub fn lfs_fromle32(a: u32) -> u32 {
u32::from_le(a)
}
#[inline(always)]
pub fn lfs_tole32(a: u32) -> u32 {
a.to_le()
}
#[inline(always)]
pub fn lfs_frombe32(a: u32) -> u32 {
u32::from_be(a)
}
#[inline(always)]
pub fn lfs_tobe32(a: u32) -> u32 {
a.to_be()
}
#[inline(always)]
pub fn lfs_strspn(p: *const u8, c: u8) -> u32 {
if p.is_null() {
return 0;
}
let mut n: u32 = 0;
unsafe {
let mut q = p;
#[cfg(feature = "loop_limits")]
const MAX_STRSPN_ITER: u32 = 4096;
#[cfg(feature = "loop_limits")]
let mut iter: u32 = 0;
while *q == c {
#[cfg(feature = "loop_limits")]
{
if iter >= MAX_STRSPN_ITER {
panic!(
"loop_limits: MAX_STRSPN_ITER ({}) exceeded",
MAX_STRSPN_ITER
);
}
iter += 1;
}
n += 1;
q = q.add(1);
}
}
n
}
#[inline(always)]
pub fn lfs_strcspn(p: *const u8, c: u8) -> u32 {
if p.is_null() {
return 0;
}
let mut n: u32 = 0;
unsafe {
let mut q = p;
#[cfg(feature = "loop_limits")]
const MAX_STRCSPN_ITER: u32 = 4096;
#[cfg(feature = "loop_limits")]
let mut iter: u32 = 0;
while *q != c && *q != 0 {
#[cfg(feature = "loop_limits")]
{
if iter >= MAX_STRCSPN_ITER {
panic!(
"loop_limits: MAX_STRCSPN_ITER ({}) exceeded",
MAX_STRCSPN_ITER
);
}
iter += 1;
}
n += 1;
q = q.add(1);
}
}
n
}
#[inline(always)]
pub fn lfs_path_slice_from_cstr(p: *const u8) -> &'static [u8] {
if p.is_null() {
return &[];
}
unsafe {
let mut len = 0;
while len < 256 && *p.add(len) != 0 {
len += 1;
}
core::slice::from_raw_parts(p, len)
}
}
#[inline(always)]
pub fn lfs_path_namelen(path: &[u8]) -> u32 {
path.iter().position(|&b| b == b'/').unwrap_or(path.len()) as lfs_size_t
}
#[inline(always)]
pub fn lfs_path_islast(path: &[u8]) -> bool {
let namelen = lfs_path_namelen(path) as usize;
let rest = path.get(namelen..).unwrap_or(&[]);
let skip = rest.iter().take_while(|&&b| b == b'/').count();
path.get(namelen + skip).is_none_or(|&b| b == 0)
}
#[inline(always)]
pub fn lfs_path_isdir(path: &[u8]) -> bool {
let namelen = lfs_path_namelen(path) as usize;
path.get(namelen).is_some_and(|&b| b != 0)
}
#[inline(always)]
pub fn lfs_pair_fromle32(pair: &mut [lfs_block_t; 2]) {
pair[0] = lfs_fromle32(pair[0]);
pair[1] = lfs_fromle32(pair[1]);
}
#[inline(always)]
pub fn lfs_pair_tole32(pair: &mut [lfs_block_t; 2]) {
pair[0] = lfs_tole32(pair[0]);
pair[1] = lfs_tole32(pair[1]);
}
#[inline(always)]
pub fn lfs_pair_swap(pair: &mut [lfs_block_t; 2]) {
pair.swap(0, 1);
}
#[inline(always)]
pub fn lfs_pair_isnull(pair: &[lfs_block_t; 2]) -> bool {
use crate::types::LFS_BLOCK_NULL;
pair[0] == LFS_BLOCK_NULL || pair[1] == LFS_BLOCK_NULL
}
#[inline(always)]
pub fn lfs_pair_cmp(paira: &[lfs_block_t; 2], pairb: &[lfs_block_t; 2]) -> i32 {
let eq = paira[0] == pairb[0]
|| paira[1] == pairb[1]
|| paira[0] == pairb[1]
|| paira[1] == pairb[0];
if eq {
0
} else {
1
}
}
#[inline(always)]
pub fn lfs_pair_issync(paira: &[lfs_block_t; 2], pairb: &[lfs_block_t; 2]) -> bool {
(paira[0] == pairb[0] && paira[1] == pairb[1]) || (paira[0] == pairb[1] && paira[1] == pairb[0])
}