git_policy_cli/index/
index_stat.rs1#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
14pub struct StatData {
15 pub ctime_sec: u32,
17 pub ctime_nsec: u32,
19 pub mtime_sec: u32,
21 pub mtime_nsec: u32,
23 pub dev: u32,
25 pub ino: u32,
27 pub uid: u32,
29 pub gid: u32,
31 pub size: u32,
33}
34
35pub fn be32(bytes: &[u8], at: usize) -> Option<u32> {
37 let quad: &[u8] = bytes.get(at..at.checked_add(4)?)?;
38 return Some(u32::from_be_bytes([quad[0], quad[1], quad[2], quad[3]]));
39}
40
41impl StatData {
42 pub fn to_cache_bytes(&self, out: &mut Vec<u8>) {
44 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] {
45 out.extend_from_slice(&value.to_be_bytes());
46 }
47 }
48
49 pub fn from_cache_bytes(bytes: &[u8]) -> Option<StatData> {
51 return Some(StatData {
52 ctime_sec: be32(bytes, 0)?,
53 ctime_nsec: be32(bytes, 4)?,
54 mtime_sec: be32(bytes, 8)?,
55 mtime_nsec: be32(bytes, 12)?,
56 dev: be32(bytes, 16)?,
57 ino: be32(bytes, 20)?,
58 uid: be32(bytes, 24)?,
59 gid: be32(bytes, 28)?,
60 size: be32(bytes, 32)?,
61 });
62 }
63}
64
65pub const CACHE_STAT_LENGTH: usize = 36;
67
68pub fn encode_varint(value: u64, out: &mut Vec<u8>) {
70 let mut reversed: Vec<u8> = vec![(value & 127) as u8];
71 let mut rest: u64 = value >> 7;
72 while rest > 0 {
73 rest -= 1;
74 reversed.push(128 | (rest & 127) as u8);
75 rest >>= 7;
76 }
77 reversed.reverse();
78 out.extend_from_slice(reversed.as_slice());
79}
80
81pub fn decode_varint(bytes: &[u8]) -> Option<(u64, &[u8])> {
83 let mut used: usize = 1;
84 let mut byte: u8 = *bytes.first()?;
85 let mut value: u64 = u64::from(byte & 127);
86 while byte & 128 != 0 {
87 byte = *bytes.get(used)?;
88 used += 1;
89 value = value.checked_add(1)?;
90 if value > (u64::MAX >> 7) {
91 return None;
92 }
93 value = (value << 7) | u64::from(byte & 127);
94 }
95 return Some((value, &bytes[used..]));
96}
97
98#[cfg(test)]
99#[path = "index_stat_tests.rs"]
100mod tests;