@@ -75,22 +75,28 @@ impl Outcome {
75
75
/// Decompression of objects
76
76
impl File {
77
77
/// Decompress the given `entry` into `out` and return the amount of bytes read from the pack data.
78
+ /// Note that `inflate` is not reset after usage, but will be reset before using it.
78
79
///
79
80
/// _Note_ that this method does not resolve deltified objects, but merely decompresses their content
80
81
/// `out` is expected to be large enough to hold `entry.size` bytes.
81
82
///
82
83
/// # Panics
83
84
///
84
85
/// If `out` isn't large enough to hold the decompressed `entry`
85
- pub fn decompress_entry ( & self , entry : & data:: Entry , out : & mut [ u8 ] ) -> Result < usize , Error > {
86
+ pub fn decompress_entry (
87
+ & self ,
88
+ entry : & data:: Entry ,
89
+ inflate : & mut zlib:: Inflate ,
90
+ out : & mut [ u8 ] ,
91
+ ) -> Result < usize , Error > {
86
92
assert ! (
87
93
out. len( ) as u64 >= entry. decompressed_size,
88
94
"output buffer isn't large enough to hold decompressed result, want {}, have {}" ,
89
95
entry. decompressed_size,
90
96
out. len( )
91
97
) ;
92
98
93
- self . decompress_entry_from_data_offset ( entry. data_offset , out)
99
+ self . decompress_entry_from_data_offset ( entry. data_offset , inflate , out)
94
100
. map_err ( Into :: into)
95
101
}
96
102
@@ -121,12 +127,14 @@ impl File {
121
127
pub ( crate ) fn decompress_entry_from_data_offset (
122
128
& self ,
123
129
data_offset : data:: Offset ,
130
+ inflate : & mut zlib:: Inflate ,
124
131
out : & mut [ u8 ] ,
125
132
) -> Result < usize , zlib:: inflate:: Error > {
126
133
let offset: usize = data_offset. try_into ( ) . expect ( "offset representable by machine" ) ;
127
134
assert ! ( offset < self . data. len( ) , "entry offset out of bounds" ) ;
128
135
129
- zlib:: Inflate :: default ( )
136
+ inflate. reset ( ) ;
137
+ inflate
130
138
. once ( & self . data [ offset..] , out)
131
139
. map ( |( _status, consumed_in, _consumed_out) | consumed_in)
132
140
}
@@ -135,12 +143,14 @@ impl File {
135
143
pub ( crate ) fn decompress_entry_from_data_offset_2 (
136
144
& self ,
137
145
data_offset : data:: Offset ,
146
+ inflate : & mut zlib:: Inflate ,
138
147
out : & mut [ u8 ] ,
139
148
) -> Result < ( usize , usize ) , zlib:: inflate:: Error > {
140
149
let offset: usize = data_offset. try_into ( ) . expect ( "offset representable by machine" ) ;
141
150
assert ! ( offset < self . data. len( ) , "entry offset out of bounds" ) ;
142
151
143
- zlib:: Inflate :: default ( )
152
+ inflate. reset ( ) ;
153
+ inflate
144
154
. once ( & self . data [ offset..] , out)
145
155
. map ( |( _status, consumed_in, consumed_out) | ( consumed_in, consumed_out) )
146
156
}
@@ -149,6 +159,7 @@ impl File {
149
159
/// space to hold the result object.
150
160
///
151
161
/// The `entry` determines which object to decode, and is commonly obtained with the help of a pack index file or through pack iteration.
162
+ /// `inflate` will be used for decompressing entries, and will not be reset after usage, but before first using it.
152
163
///
153
164
/// `resolve` is a function to lookup objects with the given [`ObjectId`][gix_hash::ObjectId], in case the full object id is used to refer to
154
165
/// a base object, instead of an in-pack offset.
@@ -159,6 +170,7 @@ impl File {
159
170
& self ,
160
171
entry : data:: Entry ,
161
172
out : & mut Vec < u8 > ,
173
+ inflate : & mut zlib:: Inflate ,
162
174
resolve : impl Fn ( & gix_hash:: oid , & mut Vec < u8 > ) -> Option < ResolvedBase > ,
163
175
delta_cache : & mut impl cache:: DecodeEntry ,
164
176
) -> Result < Outcome , Error > {
@@ -172,15 +184,16 @@ impl File {
172
184
. expect ( "size representable by machine" ) ,
173
185
0 ,
174
186
) ;
175
- self . decompress_entry ( & entry, out. as_mut_slice ( ) ) . map ( |consumed_input| {
176
- Outcome :: from_object_entry (
177
- entry. header . as_kind ( ) . expect ( "a non-delta entry" ) ,
178
- & entry,
179
- consumed_input,
180
- )
181
- } )
187
+ self . decompress_entry ( & entry, inflate, out. as_mut_slice ( ) )
188
+ . map ( |consumed_input| {
189
+ Outcome :: from_object_entry (
190
+ entry. header . as_kind ( ) . expect ( "a non-delta entry" ) ,
191
+ & entry,
192
+ consumed_input,
193
+ )
194
+ } )
182
195
}
183
- OfsDelta { .. } | RefDelta { .. } => self . resolve_deltas ( entry, resolve, out, delta_cache) ,
196
+ OfsDelta { .. } | RefDelta { .. } => self . resolve_deltas ( entry, resolve, inflate , out, delta_cache) ,
184
197
}
185
198
}
186
199
@@ -191,6 +204,7 @@ impl File {
191
204
& self ,
192
205
last : data:: Entry ,
193
206
resolve : impl Fn ( & gix_hash:: oid , & mut Vec < u8 > ) -> Option < ResolvedBase > ,
207
+ inflate : & mut zlib:: Inflate ,
194
208
out : & mut Vec < u8 > ,
195
209
cache : & mut impl cache:: DecodeEntry ,
196
210
) -> Result < Outcome , Error > {
@@ -278,6 +292,7 @@ impl File {
278
292
for ( delta_idx, delta) in chain. iter_mut ( ) . rev ( ) . enumerate ( ) {
279
293
let consumed_from_data_offset = self . decompress_entry_from_data_offset (
280
294
delta. data_offset ,
295
+ inflate,
281
296
& mut instructions[ ..delta. decompressed_size ] ,
282
297
) ?;
283
298
let is_last_delta_to_be_applied = delta_idx + 1 == chain_len;
@@ -338,7 +353,7 @@ impl File {
338
353
let base_entry = cursor;
339
354
debug_assert ! ( !base_entry. header. is_delta( ) ) ;
340
355
object_kind = base_entry. header . as_kind ( ) ;
341
- self . decompress_entry_from_data_offset ( base_entry. data_offset , out) ?;
356
+ self . decompress_entry_from_data_offset ( base_entry. data_offset , inflate , out) ?;
342
357
}
343
358
344
359
( first_buffer_size, second_buffer_end)
0 commit comments