gix_pack/data/entry/mod.rs
1use crate::data::Entry;
2
3const _TYPE_EXT1: u8 = 0;
4const COMMIT: u8 = 1;
5const TREE: u8 = 2;
6const BLOB: u8 = 3;
7const TAG: u8 = 4;
8const _TYPE_EXT2: u8 = 5;
9const OFS_DELTA: u8 = 6;
10const REF_DELTA: u8 = 7;
11
12/// A way to uniquely identify the location of an entry within a pack bundle
13#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub struct Location {
16 /// The id of the pack containing the object. It's unique within its frame of reference which is the owning object database.
17 pub pack_id: u32,
18 /// The size of the entry of disk so that the range of bytes of the entry is `pack_offset..pack_offset + entry_size`.
19 pub entry_size: usize,
20 /// The start of the entry in the pack identified by `pack_id`.
21 pub pack_offset: data::Offset,
22}
23
24impl Location {
25 /// Compute a range suitable for lookup in pack data using the [`entry_slice()`][crate::data::File::entry_slice()] method.
26 pub fn entry_range(&self, pack_offset: data::Offset) -> crate::data::EntryRange {
27 pack_offset..pack_offset + self.entry_size as u64
28 }
29}
30
31/// Access
32impl Entry {
33 /// Compute the pack offset to the base entry of the object represented by this entry, or
34 /// return `None` if the distance would underflow or is invalid.
35 pub fn checked_base_pack_offset(&self, distance: u64) -> Option<data::Offset> {
36 Header::verified_base_pack_offset(self.pack_offset(), distance)
37 }
38
39 /// Compute the pack offset to the base entry of the object represented by this entry.
40 ///
41 /// # Panics
42 ///
43 /// Panics if the `distance` will cause an underflow or is invalid.
44 pub fn base_pack_offset(&self, distance: u64) -> data::Offset {
45 self.checked_base_pack_offset(distance)
46 .expect("in-bound distance of deltas")
47 }
48 /// The pack offset at which this entry starts
49 pub fn pack_offset(&self) -> data::Offset {
50 self.data_offset - self.header_size() as u64
51 }
52 /// The amount of bytes used to describe this entry in the pack.
53 ///
54 /// For entries decoded from pack data this returns the actual encoded header length, including
55 /// non-canonical overlong size encodings accepted by Git. This is the length to use for offset
56 /// reconstruction because the header starts at [`Self::pack_offset()`] and the compressed data
57 /// starts at [`Entry::data_offset`].
58 ///
59 /// If [`Entry::encoded_header_size`] is `0`, the actual encoded length is unknown and this falls
60 /// back to [`Header::size()`], which computes the canonical serialized length from the decoded
61 /// header and decompressed size.
62 pub fn header_size(&self) -> usize {
63 if self.encoded_header_size == 0 {
64 self.header.size(self.decompressed_size)
65 } else {
66 self.encoded_header_size.into()
67 }
68 }
69}
70
71///
72pub mod decode;
73
74mod header;
75pub use header::Header;
76
77use crate::data;