gix_pack/bundle/find.rs
1impl crate::Bundle {
2 /// Find an object with the given [`ObjectId`](gix_hash::ObjectId) and place its data into `out`.
3 /// `inflate` is used to decompress objects, and will be reset before first use, but not after the last use.
4 ///
5 /// [`cache`](crate::cache::DecodeEntry) is used to accelerate the lookup.
6 ///
7 /// **Note** that ref deltas are automatically resolved within this pack only, which makes this implementation unusable
8 /// for thin packs, which by now are expected to be resolved already.
9 pub fn find<'a>(
10 &self,
11 id: &gix_hash::oid,
12 out: &'a mut Vec<u8>,
13 inflate: &mut gix_zlib::Inflate,
14 cache: &mut dyn crate::cache::DecodeEntry,
15 ) -> Result<Option<(gix_object::Data<'a>, crate::data::entry::Location)>, crate::data::decode::Error> {
16 let idx = match self.index.lookup(id) {
17 Some(idx) => idx,
18 None => return Ok(None),
19 };
20 self.get_object_by_index(idx, out, inflate, cache).map(Some)
21 }
22
23 /// Special-use function to get an object given an index previously returned from
24 /// [index::File::](crate::index::File::lookup()).
25 /// `inflate` is used to decompress objects, and will be reset before first use, but not after the last use.
26 ///
27 /// # Panics
28 ///
29 /// If `index` is out of bounds.
30 pub fn get_object_by_index<'a>(
31 &self,
32 idx: u32,
33 out: &'a mut Vec<u8>,
34 inflate: &mut gix_zlib::Inflate,
35 cache: &mut dyn crate::cache::DecodeEntry,
36 ) -> Result<(gix_object::Data<'a>, crate::data::entry::Location), crate::data::decode::Error> {
37 let ofs = self.index.pack_offset_at_index(idx);
38 let pack_entry = self.pack.entry(ofs)?;
39 let header_size = pack_entry.header_size();
40 self.pack
41 .decode_entry(
42 pack_entry,
43 out,
44 inflate,
45 &|id, _out| {
46 let idx = self.index.lookup(id)?;
47 self.pack
48 .entry(self.index.pack_offset_at_index(idx))
49 .ok()
50 .map(crate::data::decode::entry::ResolvedBase::InPack)
51 },
52 cache,
53 )
54 .map(move |r| {
55 (
56 gix_object::Data {
57 kind: r.kind,
58 data: out.as_slice(),
59 object_hash: self.pack.object_hash(),
60 },
61 crate::data::entry::Location {
62 pack_id: self.pack.id,
63 pack_offset: ofs,
64 entry_size: r.compressed_size + header_size,
65 },
66 )
67 })
68 }
69}