#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct StatData {
pub ctime_sec: u32,
pub ctime_nsec: u32,
pub mtime_sec: u32,
pub mtime_nsec: u32,
pub dev: u32,
pub ino: u32,
pub uid: u32,
pub gid: u32,
pub size: u32,
}
pub fn be32(bytes: &[u8], at: usize) -> Option<u32> {
let quad: &[u8] = bytes.get(at..at.checked_add(4)?)?;
return Some(u32::from_be_bytes([quad[0], quad[1], quad[2], quad[3]]));
}
impl StatData {
pub fn to_cache_bytes(&self, out: &mut Vec<u8>) {
for value in [self.ctime_sec, self.ctime_nsec, self.mtime_sec, self.mtime_nsec, self.dev, self.ino, self.uid, self.gid, self.size] {
out.extend_from_slice(&value.to_be_bytes());
}
}
pub fn from_cache_bytes(bytes: &[u8]) -> Option<StatData> {
return Some(StatData {
ctime_sec: be32(bytes, 0)?,
ctime_nsec: be32(bytes, 4)?,
mtime_sec: be32(bytes, 8)?,
mtime_nsec: be32(bytes, 12)?,
dev: be32(bytes, 16)?,
ino: be32(bytes, 20)?,
uid: be32(bytes, 24)?,
gid: be32(bytes, 28)?,
size: be32(bytes, 32)?,
});
}
}
pub const CACHE_STAT_LENGTH: usize = 36;
pub fn encode_varint(value: u64, out: &mut Vec<u8>) {
let mut reversed: Vec<u8> = vec![(value & 127) as u8];
let mut rest: u64 = value >> 7;
while rest > 0 {
rest -= 1;
reversed.push(128 | (rest & 127) as u8);
rest >>= 7;
}
reversed.reverse();
out.extend_from_slice(reversed.as_slice());
}
pub fn decode_varint(bytes: &[u8]) -> Option<(u64, &[u8])> {
let mut used: usize = 1;
let mut byte: u8 = *bytes.first()?;
let mut value: u64 = u64::from(byte & 127);
while byte & 128 != 0 {
byte = *bytes.get(used)?;
used += 1;
value = value.checked_add(1)?;
if value > (u64::MAX >> 7) {
return None;
}
value = (value << 7) | u64::from(byte & 127);
}
return Some((value, &bytes[used..]));
}
#[cfg(test)]
#[path = "index_stat_tests.rs"]
mod tests;