@@ -377,17 +377,25 @@ impl StructAsBytes for EndTag {
377
377
}
378
378
}
379
379
380
+ /// Iterates the MBI's tags from the first tag to the end tag.
380
381
#[ derive( Clone , Debug ) ]
381
382
pub struct TagIter < ' a > {
383
+ /// Pointer to the next tag. Updated in each iteration.
382
384
pub current : * const Tag ,
383
- phantom : PhantomData < & ' a Tag > ,
385
+ /// The pointer right after the MBI. Used for additional bounds checking.
386
+ end_ptr_exclusive : * const u8 ,
387
+ /// Lifetime capture of the MBI's memory.
388
+ _mem : PhantomData < & ' a ( ) > ,
384
389
}
385
390
386
391
impl < ' a > TagIter < ' a > {
387
- pub fn new ( first : * const Tag ) -> Self {
392
+ /// Creates a new iterator
393
+ pub fn new ( mem : & ' a [ u8 ] ) -> Self {
394
+ assert_eq ! ( mem. as_ptr( ) . align_offset( 8 ) , 0 ) ;
388
395
TagIter {
389
- current : first,
390
- phantom : PhantomData ,
396
+ current : mem. as_ptr ( ) . cast ( ) ,
397
+ end_ptr_exclusive : unsafe { mem. as_ptr ( ) . add ( mem. len ( ) ) } ,
398
+ _mem : PhantomData ,
391
399
}
392
400
}
393
401
}
@@ -396,17 +404,25 @@ impl<'a> Iterator for TagIter<'a> {
396
404
type Item = & ' a Tag ;
397
405
398
406
fn next ( & mut self ) -> Option < & ' a Tag > {
399
- match unsafe { & * self . current } {
407
+ // This never failed so far. But better be safe.
408
+ assert ! ( self . current. cast:: <u8 >( ) < self . end_ptr_exclusive) ;
409
+
410
+ let tag = unsafe { & * self . current } ;
411
+ match tag {
400
412
& Tag {
401
413
// END-Tag
402
414
typ : TagTypeId ( 0 ) ,
403
415
size : 8 ,
404
416
} => None , // end tag
405
417
tag => {
418
+ // We return the tag and update self.current already to the next
419
+ // tag.
420
+
421
+ // next pointer (rounded up to 8-byte alignment)
422
+ let ptr_offset = ( tag. size as usize + 7 ) & !7 ;
423
+
406
424
// go to next tag
407
- let mut tag_addr = self . current as usize ;
408
- tag_addr += ( ( tag. size + 7 ) & !7 ) as usize ; //align at 8 byte
409
- self . current = tag_addr as * const _ ;
425
+ self . current = unsafe { self . current . cast :: < u8 > ( ) . add ( ptr_offset) . cast :: < Tag > ( ) } ;
410
426
411
427
Some ( tag)
412
428
}
0 commit comments