summaryrefslogtreecommitdiffstats
path: root/vendor/gix-index/src/extension/index_entry_offset_table.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-index/src/extension/index_entry_offset_table.rs')
-rw-r--r--vendor/gix-index/src/extension/index_entry_offset_table.rs43
1 files changed, 43 insertions, 0 deletions
diff --git a/vendor/gix-index/src/extension/index_entry_offset_table.rs b/vendor/gix-index/src/extension/index_entry_offset_table.rs
new file mode 100644
index 000000000..0a0108adf
--- /dev/null
+++ b/vendor/gix-index/src/extension/index_entry_offset_table.rs
@@ -0,0 +1,43 @@
+use crate::{extension, extension::Signature, util::read_u32};
+
+#[derive(Debug, Clone, Copy)]
+pub struct Offset {
+ pub from_beginning_of_file: u32,
+ pub num_entries: u32,
+}
+
+pub const SIGNATURE: Signature = *b"IEOT";
+
+pub fn decode(data: &[u8]) -> Option<Vec<Offset>> {
+ let (version, mut data) = read_u32(data)?;
+ match version {
+ 1 => {}
+ _unknown => return None,
+ }
+
+ let entry_size = 4 + 4;
+ let num_offsets = data.len() / entry_size;
+ if num_offsets == 0 || data.len() % entry_size != 0 {
+ return None;
+ }
+
+ let mut out = Vec::with_capacity(entry_size);
+ for _ in 0..num_offsets {
+ let (offset, chunk) = read_u32(data)?;
+ let (num_entries, chunk) = read_u32(chunk)?;
+ out.push(Offset {
+ from_beginning_of_file: offset,
+ num_entries,
+ });
+ data = chunk;
+ }
+ debug_assert!(data.is_empty());
+
+ out.into()
+}
+
+pub fn find(extensions: &[u8], object_hash: gix_hash::Kind) -> Option<Vec<Offset>> {
+ extension::Iter::new_without_checksum(extensions, object_hash)?
+ .find_map(|(sig, ext_data)| (sig == SIGNATURE).then_some(ext_data))
+ .and_then(decode)
+}