@@ -2,7 +2,7 @@ use crate::ebml::vint::VInt;
2
2
use crate :: error:: Result ;
3
3
use crate :: macros:: { decode_err, try_vec} ;
4
4
5
- use std:: io:: Read ;
5
+ use std:: io:: { self , Read } ;
6
6
use std:: ops:: { Deref , DerefMut } ;
7
7
8
8
use byteorder:: { BigEndian , ReadBytesExt } ;
@@ -241,15 +241,21 @@ ebml_master_elements! {
241
241
} ,
242
242
}
243
243
244
- #[ derive( Debug ) ]
244
+ const MAX_DEPTH : u8 = 16 ;
245
+ const ROOT_DEPTH : u8 = 1 ;
246
+
247
+ #[ derive( Copy , Clone , Debug ) ]
248
+ struct Depth {
249
+ level : u8 ,
250
+ length : VInt ,
251
+ }
252
+
253
+ #[ derive( Copy , Clone , Debug ) ]
245
254
struct MasterElementContext {
246
255
element : MasterElement ,
247
- remaining_length : VInt ,
256
+ depth : Depth ,
248
257
}
249
258
250
- const MAX_DEPTH : u8 = 16 ;
251
- const ROOT_DEPTH : u8 = 1 ;
252
-
253
259
#[ derive( Debug ) ]
254
260
struct ElementReaderContext {
255
261
depth : u8 ,
@@ -269,8 +275,7 @@ struct ElementReaderContext {
269
275
/// to know which depth to lock the reader at again (if any).
270
276
///
271
277
/// This will **always** be sorted, so the current lock will be at the end.
272
- lock_depths : Vec < u8 > ,
273
- lock_len : VInt ,
278
+ lock_depths : Vec < usize > ,
274
279
}
275
280
276
281
impl Default for ElementReaderContext {
@@ -284,11 +289,41 @@ impl Default for ElementReaderContext {
284
289
max_size_length : 8 ,
285
290
locked : false ,
286
291
lock_depths : Vec :: with_capacity ( MAX_DEPTH as usize ) ,
287
- lock_len : VInt :: ZERO ,
288
292
}
289
293
}
290
294
}
291
295
296
+ impl ElementReaderContext {
297
+ fn current_master ( & self ) -> Option < MasterElementContext > {
298
+ if self . depth == 0 {
299
+ return None ;
300
+ }
301
+
302
+ self . masters . get ( ( self . depth - 1 ) as usize ) . copied ( )
303
+ }
304
+
305
+ fn current_master_length ( & self ) -> VInt {
306
+ assert ! ( self . depth > 0 ) ;
307
+ self . current_master ( )
308
+ . expect ( "should have current master element" )
309
+ . depth
310
+ . length
311
+ }
312
+
313
+ fn propagate_length_change ( & mut self , length : u64 ) {
314
+ for master in & mut self . masters {
315
+ master. depth . length = master. depth . length . saturating_sub ( length) ;
316
+ }
317
+ }
318
+
319
+ fn remaining_lock_length ( & self ) -> VInt {
320
+ assert ! ( self . locked && !self . lock_depths. is_empty( ) ) ;
321
+
322
+ let lock_depth = * self . lock_depths . last ( ) . unwrap ( ) ;
323
+ self . masters [ lock_depth - 1 ] . depth . length
324
+ }
325
+ }
326
+
292
327
#[ derive( Debug ) ]
293
328
pub ( crate ) enum ElementReaderYield {
294
329
Master ( ( ElementIdent , VInt ) ) ,
@@ -321,30 +356,37 @@ impl ElementReaderYield {
321
356
/// An EBML element reader.
322
357
pub struct ElementReader < R > {
323
358
reader : R ,
324
- ctx : ElementReaderContext ,
359
+ pub ( self ) ctx : ElementReaderContext ,
325
360
}
326
361
327
362
impl < R > Read for ElementReader < R >
328
363
where
329
364
R : Read ,
330
365
{
331
- fn read ( & mut self , buf : & mut [ u8 ] ) -> std :: io:: Result < usize > {
366
+ fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
332
367
if self . ctx . locked {
333
- let lock_len = self . ctx . lock_len . value ( ) ;
368
+ let lock_len = self . ctx . remaining_lock_length ( ) . value ( ) ;
334
369
if buf. len ( ) > lock_len as usize {
335
- return Err ( std :: io:: Error :: new (
336
- std :: io:: ErrorKind :: UnexpectedEof ,
370
+ return Err ( io:: Error :: new (
371
+ io:: ErrorKind :: UnexpectedEof ,
337
372
"Cannot read past the end of the current master element" ,
338
373
) ) ;
339
374
}
340
375
}
341
376
342
377
let ret = self . reader . read ( buf) ?;
343
- let len = self . current_master_length ( ) ;
344
- self . set_current_master_length ( len. saturating_sub ( ret as u64 ) ) ;
378
+ if self . ctx . current_master ( ) . is_none ( ) {
379
+ return Ok ( ret) ;
380
+ }
345
381
346
- if self . ctx . locked {
347
- self . ctx . lock_len = self . ctx . lock_len . saturating_sub ( ret as u64 ) ;
382
+ self . ctx . propagate_length_change ( ret as u64 ) ;
383
+
384
+ let current_master = self
385
+ . ctx
386
+ . current_master ( )
387
+ . expect ( "should have current master element" ) ;
388
+ if current_master. depth . length == 0 {
389
+ self . goto_previous_master ( ) ?;
348
390
}
349
391
350
392
Ok ( ret)
@@ -370,42 +412,17 @@ where
370
412
self . ctx . max_size_length = len
371
413
}
372
414
373
- fn current_master ( & self ) -> Option < MasterElement > {
374
- if self . ctx . depth == 0 {
375
- assert ! ( self . ctx. masters. is_empty( ) ) ;
376
- return None ;
377
- }
378
-
379
- Some ( self . ctx . masters [ ( self . ctx . depth - 1 ) as usize ] . element )
380
- }
381
-
382
- fn current_master_length ( & self ) -> VInt {
383
- if self . ctx . depth == 0 {
384
- assert ! ( self . ctx. masters. is_empty( ) ) ;
385
- return VInt :: ZERO ;
386
- }
387
-
388
- self . ctx . masters [ ( self . ctx . depth - 1 ) as usize ] . remaining_length
389
- }
390
-
391
- fn set_current_master_length ( & mut self , length : VInt ) {
392
- if self . ctx . depth == 0 {
393
- assert ! ( self . ctx. masters. is_empty( ) ) ;
394
- return ;
395
- }
396
-
397
- self . ctx . masters [ ( self . ctx . depth - 1 ) as usize ] . remaining_length = length;
398
- }
399
-
400
415
fn push_new_master ( & mut self , master : MasterElement , size : VInt ) -> Result < ( ) > {
416
+ log:: debug!( "New master element: {:?}" , master. id) ;
417
+
401
418
if self . ctx . depth == MAX_DEPTH {
402
419
decode_err ! ( @BAIL Ebml , "Maximum depth reached" ) ;
403
420
}
404
421
405
422
// If we are at the root level, we do not increment the depth
406
423
// since we are not actually inside a master element.
407
424
// For example, we are moving from \EBML to \Segment.
408
- let at_root_level = self . ctx . depth == ROOT_DEPTH && self . current_master_length ( ) == 0 ;
425
+ let at_root_level = self . ctx . depth == ROOT_DEPTH && self . ctx . current_master_length ( ) == 0 ;
409
426
if at_root_level {
410
427
assert_eq ! ( self . ctx. masters. len( ) , 1 ) ;
411
428
self . ctx . masters . clear ( ) ;
@@ -415,20 +432,47 @@ where
415
432
416
433
self . ctx . masters . push ( MasterElementContext {
417
434
element : master,
418
- remaining_length : size,
435
+ depth : Depth {
436
+ level : self . ctx . depth ,
437
+ length : size,
438
+ } ,
419
439
} ) ;
420
440
421
441
Ok ( ( ) )
422
442
}
423
443
444
+ fn goto_previous_master ( & mut self ) -> io:: Result < ( ) > {
445
+ let lock_depth = self
446
+ . ctx
447
+ . lock_depths
448
+ . last ( )
449
+ . copied ( )
450
+ . unwrap_or ( ROOT_DEPTH as usize ) ;
451
+ if lock_depth == self . ctx . depth as usize || self . ctx . depth == 0 {
452
+ return Ok ( ( ) ) ;
453
+ }
454
+
455
+ if self . ctx . depth == ROOT_DEPTH {
456
+ return Err ( io:: Error :: new (
457
+ io:: ErrorKind :: Other ,
458
+ "Cannot go to previous master element, already at root" ,
459
+ ) ) ;
460
+ }
461
+
462
+ while self . ctx . current_master_length ( ) == 0
463
+ && ( self . ctx . depth as usize != lock_depth && self . ctx . depth != ROOT_DEPTH )
464
+ {
465
+ self . ctx . depth -= 1 ;
466
+ let _ = self . ctx . masters . pop ( ) ;
467
+ }
468
+
469
+ Ok ( ( ) )
470
+ }
471
+
424
472
fn goto_next_master ( & mut self ) -> Result < ElementReaderYield > {
425
473
self . exhaust_current_master ( ) ?;
426
474
427
- let header = ElementHeader :: read (
428
- & mut self . reader ,
429
- self . ctx . max_id_length ,
430
- self . ctx . max_size_length ,
431
- ) ?;
475
+ let header = ElementHeader :: read ( self , self . ctx . max_id_length , self . ctx . max_size_length ) ?;
432
476
let Some ( master) = master_elements ( ) . get ( & header. id ) else {
433
477
// We encountered an unknown master element
434
478
return Ok ( ElementReaderYield :: Unknown ( header) ) ;
@@ -439,35 +483,23 @@ where
439
483
Ok ( ElementReaderYield :: Master ( ( master. id , header. size ) ) )
440
484
}
441
485
442
- fn goto_previous_master ( & mut self ) -> Result < ( ) > {
443
- if self . ctx . depth == ROOT_DEPTH || self . ctx . lock_depths . last ( ) == Some ( & self . ctx . depth ) {
444
- decode_err ! ( @BAIL Ebml , "Cannot go to previous master element, already at root" )
445
- }
446
-
447
- self . exhaust_current_master ( ) ?;
448
-
449
- self . ctx . depth -= 1 ;
450
- let _ = self . ctx . masters . pop ( ) ;
451
-
452
- Ok ( ( ) )
453
- }
454
-
455
486
pub ( crate ) fn next ( & mut self ) -> Result < ElementReaderYield > {
456
- let Some ( current_master) = self . current_master ( ) else {
487
+ let Some ( current_master) = self . ctx . current_master ( ) else {
457
488
return self . goto_next_master ( ) ;
458
489
} ;
459
490
460
- if self . ctx . locked && self . ctx . lock_len == 0 {
491
+ if self . ctx . locked && self . ctx . remaining_lock_length ( ) == 0 {
461
492
return Ok ( ElementReaderYield :: Eof ) ;
462
493
}
463
494
464
- if self . current_master_length ( ) == 0 {
495
+ if current_master . depth . length == 0 {
465
496
return self . goto_next_master ( ) ;
466
497
}
467
498
468
499
let header = ElementHeader :: read ( self , self . ctx . max_id_length , self . ctx . max_size_length ) ?;
469
500
470
501
let Some ( ( _, child) ) = current_master
502
+ . element
471
503
. children
472
504
. iter ( )
473
505
. find ( |( id, _) | * id == header. id )
@@ -476,12 +508,11 @@ where
476
508
} ;
477
509
478
510
if child. data_type == ElementDataType :: Master {
479
- self . push_new_master (
480
- * master_elements ( )
481
- . get ( & header. id )
482
- . expect ( "Nested master elements should be defined at this level." ) ,
483
- header. size ,
484
- ) ?;
511
+ let master = * master_elements ( )
512
+ . get ( & header. id )
513
+ . expect ( "Nested master elements should be defined at this level." ) ;
514
+
515
+ self . push_new_master ( master, header. size ) ?;
485
516
486
517
// We encountered a nested master element
487
518
return Ok ( ElementReaderYield :: Master ( ( child. ident , header. size ) ) ) ;
@@ -491,21 +522,19 @@ where
491
522
}
492
523
493
524
pub ( crate ) fn exhaust_current_master ( & mut self ) -> Result < ( ) > {
494
- let master_length = self . current_master_length ( ) . value ( ) ;
495
- if master_length == 0 {
525
+ let Some ( current_master) = self . ctx . current_master ( ) else {
496
526
return Ok ( ( ) ) ;
497
- }
527
+ } ;
498
528
499
- self . skip ( master_length ) ?;
529
+ self . skip ( current_master . depth . length . value ( ) ) ?;
500
530
Ok ( ( ) )
501
531
}
502
532
503
533
pub ( crate ) fn lock ( & mut self ) {
504
534
log:: trace!( "New lock at depth: {}" , self . ctx. depth) ;
505
535
506
536
self . ctx . locked = true ;
507
- self . ctx . lock_len = self . current_master_length ( ) ;
508
- self . ctx . lock_depths . push ( self . ctx . depth ) ;
537
+ self . ctx . lock_depths . push ( self . ctx . depth as usize ) ;
509
538
}
510
539
511
540
pub ( crate ) fn unlock ( & mut self ) {
@@ -520,7 +549,6 @@ where
520
549
} ;
521
550
522
551
log:: trace!( "Moving lock to depth: {}" , last) ;
523
- self . ctx . lock_len = self . ctx . masters [ ( * last - 1 ) as usize ] . remaining_length ;
524
552
}
525
553
526
554
pub ( crate ) fn children ( & mut self ) -> ElementChildIterator < ' _ , R > {
@@ -531,12 +559,12 @@ where
531
559
pub ( crate ) fn skip ( & mut self , length : u64 ) -> Result < ( ) > {
532
560
log:: trace!( "Skipping {} bytes" , length) ;
533
561
534
- let current_master_length = self . current_master_length ( ) ;
562
+ let current_master_length = self . ctx . current_master_length ( ) ;
535
563
if length > current_master_length. value ( ) {
536
564
decode_err ! ( @BAIL Ebml , "Cannot skip past the end of the current master element" )
537
565
}
538
566
539
- std:: io:: copy ( & mut self . by_ref ( ) . take ( length) , & mut std :: io:: sink ( ) ) ?;
567
+ std:: io:: copy ( & mut self . by_ref ( ) . take ( length) , & mut io:: sink ( ) ) ?;
540
568
Ok ( ( ) )
541
569
}
542
570
@@ -688,9 +716,9 @@ where
688
716
. lock_depths
689
717
. last ( )
690
718
. expect ( "a child iterator should always have a lock depth" ) ;
691
- assert ! ( lock_depth <= self . reader. ctx. depth) ;
719
+ assert ! ( lock_depth <= self . reader. ctx. depth as usize ) ;
692
720
693
- self . reader . ctx . masters [ ( lock_depth - 1 ) as usize ] . remaining_length == 0
721
+ self . reader . ctx . remaining_lock_length ( ) == 0
694
722
}
695
723
}
696
724
0 commit comments