git_index/extension/
index_entry_offset_table.rs

1use crate::{extension, extension::Signature, util::read_u32};
2
3#[derive(Debug, Clone, Copy)]
4pub struct Offset {
5    pub from_beginning_of_file: u32,
6    pub num_entries: u32,
7}
8
9pub const SIGNATURE: Signature = *b"IEOT";
10
11pub fn decode(data: &[u8]) -> Option<Vec<Offset>> {
12    let (version, mut data) = read_u32(data)?;
13    match version {
14        1 => {}
15        _unknown => return None,
16    }
17
18    let entry_size = 4 + 4;
19    let num_offsets = data.len() / entry_size;
20    if num_offsets == 0 || data.len() % entry_size != 0 {
21        return None;
22    }
23
24    let mut out = Vec::with_capacity(entry_size);
25    for _ in 0..num_offsets {
26        let (offset, chunk) = read_u32(data)?;
27        let (num_entries, chunk) = read_u32(chunk)?;
28        out.push(Offset {
29            from_beginning_of_file: offset,
30            num_entries,
31        });
32        data = chunk;
33    }
34    debug_assert!(data.is_empty());
35
36    out.into()
37}
38
39pub fn find(extensions: &[u8], object_hash: git_hash::Kind) -> Option<Vec<Offset>> {
40    extension::Iter::new_without_checksum(extensions, object_hash)?
41        .find_map(|(sig, ext_data)| (sig == SIGNATURE).then_some(ext_data))
42        .and_then(decode)
43}