@@ -174,7 +174,6 @@ mod fallible {
174
174
use std:: convert:: TryInto as _;
175
175
use std:: io:: Read ;
176
176
use std:: io:: Take ;
177
- use std:: iter:: FromIterator ;
178
177
use std:: iter:: IntoIterator ;
179
178
use vec_push;
180
179
use vec_with_capacity;
@@ -229,6 +228,25 @@ mod fallible {
229
228
inner : Vec < T > ,
230
229
}
231
230
231
+ /// TryVec is a thin wrapper around std::vec::Vec to provide support for
232
+ /// fallible allocation. Though the fallible allocator is only enabled
233
+ /// with the mp4parse_fallible feature, the API differences from stdlib
234
+ /// Vec ensure that all operations which allocate return a Result. For the
235
+ /// most part, this simply means adding a Result return value to Vec
236
+ /// functions which return nothing or a non-Result value. However, Vec
237
+ /// implements some traits whose API cannot communicate failure, but which
238
+ /// do require allocation, so it is important that TryVec does not
239
+ /// implement these traits.
240
+ ///
241
+ /// Specifically, do not implement any of the following traits:
242
+ /// - Clone
243
+ /// - Extend
244
+ /// - From
245
+ /// - FromIterator
246
+ ///
247
+ /// This list may not be exhaustive. Exercise caution when implementing
248
+ /// any new traits to ensure they won't potentially allocate in a way that
249
+ /// can't return a Result to indicate allocation failure.
232
250
impl < T > TryVec < T > {
233
251
pub fn new ( ) -> Self {
234
252
Self { inner : Vec :: new ( ) }
@@ -282,12 +300,20 @@ mod fallible {
282
300
Ok ( ( ) )
283
301
}
284
302
}
303
+
304
+ pub fn resize_with < F > ( & mut self , new_len : usize , f : F ) -> Result < ( ) , ( ) >
305
+ where F : FnMut ( ) -> T
306
+ {
307
+ self . reserve ( new_len) ?;
308
+ self . inner . resize_with ( new_len, f) ;
309
+ Ok ( ( ) )
310
+ }
285
311
}
286
312
287
313
impl < T : Clone > TryVec < TryVec < T > > {
288
314
pub fn concat ( & self ) -> Result < TryVec < T > , ( ) > {
289
315
let size = self . iter ( ) . map ( |v| v. inner . len ( ) ) . sum ( ) ;
290
- let mut result: TryVec < T > = TryVec :: with_capacity ( size) ?;
316
+ let mut result = TryVec :: with_capacity ( size) ?;
291
317
for v in self . iter ( ) {
292
318
result. extend_from_slice ( & v. inner ) ?;
293
319
}
@@ -297,18 +323,11 @@ mod fallible {
297
323
298
324
impl < T : Clone > TryVec < T > {
299
325
pub fn extend_from_slice ( & mut self , other : & [ T ] ) -> Result < ( ) , ( ) > {
326
+ self . reserve ( other. len ( ) ) ?;
300
327
extend_from_slice ( & mut self . inner , other)
301
328
}
302
329
}
303
330
304
- impl < T : Clone > Clone for TryVec < T > {
305
- fn clone ( & self ) -> Self {
306
- Self {
307
- inner : self . inner . clone ( ) ,
308
- }
309
- }
310
- }
311
-
312
331
impl < T > std:: ops:: Deref for TryVec < T > {
313
332
type Target = [ T ] ;
314
333
@@ -317,11 +336,12 @@ mod fallible {
317
336
}
318
337
}
319
338
320
- impl < T > FromIterator < T > for TryVec < T > {
321
- fn from_iter < I : IntoIterator < Item = T > > ( iter : I ) -> Self {
322
- Self {
323
- inner : Vec :: from_iter ( iter) ,
324
- }
339
+ impl < T > IntoIterator for TryVec < T > {
340
+ type Item = T ;
341
+ type IntoIter = std:: vec:: IntoIter < T > ;
342
+
343
+ fn into_iter ( self ) -> Self :: IntoIter {
344
+ self . inner . into_iter ( )
325
345
}
326
346
}
327
347
@@ -1089,7 +1109,7 @@ impl TryFrom<u8> for IlocVersion {
1089
1109
/// See ISO 14496-12:2015 § 8.11.3
1090
1110
/// `base_offset` is omitted since it is integrated into the ranges in `extents`
1091
1111
/// `data_reference_index` is omitted, since only 0 (i.e., this file) is supported
1092
- #[ derive( Clone , Debug ) ]
1112
+ #[ derive( Debug ) ]
1093
1113
struct ItemLocationBoxItem {
1094
1114
item_id : u32 ,
1095
1115
construction_method : ConstructionMethod ,
@@ -1464,9 +1484,8 @@ pub fn read_avif<T: Read>(f: &mut T, context: &mut AvifContext) -> Result<()> {
1464
1484
let primary_item_loc = read_avif_meta ( & mut b) ?;
1465
1485
match primary_item_loc. construction_method {
1466
1486
ConstructionMethod :: File => {
1487
+ primary_item_extents_data. resize_with ( primary_item_loc. extents . len ( ) , Default :: default) ?;
1467
1488
primary_item_extents = Some ( primary_item_loc. extents ) ;
1468
- primary_item_extents_data =
1469
- primary_item_extents. iter ( ) . map ( |_| TryVec :: new ( ) ) . collect ( ) ;
1470
1489
}
1471
1490
_ => return Err ( Error :: Unsupported ( "unsupported construction_method" ) ) ,
1472
1491
}
@@ -1591,11 +1610,11 @@ fn read_avif_meta<T: Read + Offset>(src: &mut BMFFBox<T>) -> Result<ItemLocation
1591
1610
}
1592
1611
1593
1612
if let Some ( loc) = iloc_items
1594
- . iter ( )
1613
+ . into_iter ( )
1595
1614
. flatten ( )
1596
1615
. find ( |loc| loc. item_id == primary_item_id)
1597
1616
{
1598
- Ok ( loc. clone ( ) )
1617
+ Ok ( loc)
1599
1618
} else {
1600
1619
Err ( Error :: InvalidData (
1601
1620
"primary_item_id not present in iloc box" ,
0 commit comments