Something went wrong. Try again.
Monorepo for Tangled
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172//! a pack data fileuse std::path::Path;
/// The offset to an entry into the pack data file, relative to its beginning.pub type Offset = u64;
/// An identifier to uniquely identify all packs loaded within a known context or namespace.pub type Id = u32;
/// An representing an full- or delta-object within a pack#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]pub struct Entry { /// The entry's header pub header: entry::Header, /// The decompressed size of the entry in bytes. /// /// Note that for non-delta entries this will be the size of the object itself. pub decompressed_size: u64, /// absolute offset to compressed object data in the pack, just behind the entry's header pub data_offset: Offset,}
mod file;pub use file::{Header, decode, verify};///pub mod header;
///pub mod init { pub use super::header::decode::Error;}
///pub mod entry;
///#[cfg(feature = "streaming-input")]pub mod input;
/// Utilities to encode pack data entries and write them to a `Write` implementation to resemble a pack data file.#[cfg(feature = "generate")]pub mod output;
/// A slice into a pack file denoting a pack entry.////// An entry can be decoded into an object.pub type EntryRange = std::ops::Range<Offset>;
/// Supported versions of a pack data file#[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]pub enum Version { /// The default pack data version. /// /// This is the version generated by Git and by `gix-pack` writers. #[default] V2, /// A pack data version accepted by Git and recognized by `gix-pack` readers. /// /// Git does not generate this version, and `gix-pack` writers currently reject it. /// Entries are decoded with the same layout as [`V2`](Version::V2); the difference /// visible to this crate is the version number stored in the pack header. V3,}
/// A pack data file, read from disk on demand rather than held in memory.#[allow(missing_docs)]pub struct File { file: std::fs::File, len: usize, path: std::path::PathBuf, pub id: Id, version: Version, num_objects: u32, hash_len: usize, object_hash: gix_hash::Kind, alloc_limit_bytes: Option<usize>,}
/// Information about the pack data file itselfimpl File { /// The pack data version of this file pub fn version(&self) -> Version { self.version } /// The number of objects stored in this pack data file pub fn num_objects(&self) -> u32 { self.num_objects } /// The length of all pack data, including the pack header and the pack trailer pub fn data_len(&self) -> usize { self.len } /// The kind of hash we use internally. pub fn object_hash(&self) -> gix_hash::Kind { self.object_hash } /// The maximum size of a single allocation caused by user-controlled on-disk pack data. /// /// A value of `None` means no additional limit is enforced. pub fn alloc_limit_bytes(&self) -> Option<usize> { self.alloc_limit_bytes } /// The position of the byte one past the last pack entry, or in other terms, the first byte of the trailing hash. pub fn pack_end(&self) -> usize { self.len - self.hash_len }
/// The path to the pack data file on disk pub fn path(&self) -> &Path { &self.path }
pub(crate) fn read_exact_at(&self, offset: usize, buf: &mut [u8]) -> std::io::Result<()> { use std::os::unix::fs::FileExt; self.file.read_exact_at(buf, offset as u64) }
pub(crate) fn read_span(&self, slice: EntryRange) -> Option<Vec<u8>> { let start = usize::try_from(slice.start).ok()?; let end = usize::try_from(slice.end).ok()?; if start > end || end > self.len { return None; } let mut buf = vec![0u8; end - start]; self.read_exact_at(start, &mut buf).ok()?; Some(buf) }
#[allow(missing_docs)] pub fn read_into(&self, slice: EntryRange, buf: &mut Vec<u8>) -> bool { let (Ok(start), Ok(end)) = (usize::try_from(slice.start), usize::try_from(slice.end)) else { return false; }; if start > end || end > self.len { return false; } buf.clear(); buf.resize(end - start, 0); self.read_exact_at(start, buf).is_ok() }
pub(crate) fn materialized(&self) -> std::io::Result<crate::MMap> { crate::MMap::map(&self.file) }
/// Returns the pack data at the given slice if its range is contained in the pack data. pub fn entry_slice(&self, slice: EntryRange) -> Option<Vec<u8>> { self.read_span(slice) }
/// Returns the CRC32 of the pack data indicated by `pack_offset` and the `size` of the data. /// /// _Note:_ finding the right size is only possible by decompressing /// the pack entry beforehand, or by using the (to be sorted) offsets stored in an index file. /// /// # Panics /// /// If `pack_offset` or `size` are pointing to a range outside of the pack data. pub fn entry_crc32(&self, pack_offset: Offset, size: usize) -> u32 { let buf = self .read_span(pack_offset..pack_offset + size as u64) .expect("entry range within pack data"); gix_features::hash::crc32(&buf) }}
///pub mod delta;