@@ -107,7 +107,7 @@ ebml_master_elements! {
107
107
Segment : {
108
108
id: 0x1853_8067 ,
109
109
children: [
110
- SeekHead : { 0x114D_9B74 , Master } ,
110
+ // SeekHead: { 0x114D_9B74, Master },
111
111
Info : { 0x1549_A966 , Master } ,
112
112
Cluster : { 0x1F43_B675 , Master } ,
113
113
Tracks : { 0x1654_AE6B , Master } ,
@@ -118,12 +118,12 @@ ebml_master_elements! {
118
118
} ,
119
119
120
120
// segment.seekHead
121
- SeekHead : {
122
- id: 0x114D_9B74 ,
123
- children: [
124
- Seek : { 0x4DBB , Master } ,
125
- ] ,
126
- } ,
121
+ // SeekHead: {
122
+ // id: 0x114D_9B74,
123
+ // children: [
124
+ // Seek: { 0x4DBB, Master },
125
+ // ],
126
+ // },
127
127
128
128
// segment.info
129
129
Info : {
@@ -190,6 +190,33 @@ ebml_master_elements! {
190
190
] ,
191
191
} ,
192
192
193
+ // segment.tags.tag.targets
194
+ Targets : {
195
+ id: 0x63C0 ,
196
+ children: [
197
+ TargetTypeValue : { 0x68CA , UnsignedInt } ,
198
+ TargetType : { 0x63CA , String } ,
199
+ TagTrackUID : { 0x63C5 , UnsignedInt } ,
200
+ TagEditionUID : { 0x63C9 , UnsignedInt } ,
201
+ TagChapterUID : { 0x63C4 , UnsignedInt } ,
202
+ TagAttachmentUID : { 0x63C6 , UnsignedInt } ,
203
+ ] ,
204
+ } ,
205
+
206
+ // segment.tags.tag.simpleTag
207
+ SimpleTag : {
208
+ id: 0x67C8 ,
209
+ children: [
210
+ TagName : { 0x45A3 , Utf8 } ,
211
+ TagLanguage : { 0x447A , String } ,
212
+ TagLanguageBCP47 : { 0x447B , String } ,
213
+ TagDefault : { 0x4484 , UnsignedInt } ,
214
+ TagDefaultBogus : { 0x44B4 , UnsignedInt } ,
215
+ TagString : { 0x4487 , Utf8 } ,
216
+ TagBinary : { 0x4485 , Binary } ,
217
+ ] ,
218
+ } ,
219
+
193
220
// segment.attachments
194
221
Attachments : {
195
222
id: 0x1941_A469 ,
@@ -235,8 +262,13 @@ struct ElementReaderContext {
235
262
/// This is set with [`ElementReader::lock`], and is used to prevent
236
263
/// the reader from reading past the end of the current master element.
237
264
locked : bool ,
238
- /// The depth at which we are locked to
239
- lock_depth : u8 ,
265
+ /// The depths at which we are locked
266
+ ///
267
+ /// When we reach the end of one lock and unlock the reader, we need
268
+ /// to know which depth to lock the reader at again (if any).
269
+ ///
270
+ /// This will **always** be sorted, so the current lock will be at the end.
271
+ lock_depths : Vec < u8 > ,
240
272
lock_len : VInt ,
241
273
}
242
274
@@ -250,7 +282,7 @@ impl Default for ElementReaderContext {
250
282
// https://www.rfc-editor.org/rfc/rfc8794.html#name-ebmlmaxsizelength-element
251
283
max_size_length : 8 ,
252
284
locked : false ,
253
- lock_depth : 0 ,
285
+ lock_depths : Vec :: with_capacity ( MAX_DEPTH as usize ) ,
254
286
lock_len : VInt :: ZERO ,
255
287
}
256
288
}
@@ -285,6 +317,7 @@ impl ElementReaderYield {
285
317
}
286
318
}
287
319
320
+ /// An EBML element reader.
288
321
pub struct ElementReader < R > {
289
322
reader : R ,
290
323
ctx : ElementReaderContext ,
@@ -308,6 +341,11 @@ where
308
341
let ret = self . reader . read ( buf) ?;
309
342
let len = self . current_master_length ( ) ;
310
343
self . set_current_master_length ( len. saturating_sub ( ret as u64 ) ) ;
344
+
345
+ if self . ctx . locked {
346
+ self . ctx . lock_len = self . ctx . lock_len . saturating_sub ( ret as u64 ) ;
347
+ }
348
+
311
349
Ok ( ret)
312
350
}
313
351
}
@@ -355,10 +393,6 @@ where
355
393
return ;
356
394
}
357
395
358
- if self . ctx . locked {
359
- self . ctx . lock_len = length;
360
- }
361
-
362
396
self . ctx . masters [ ( self . ctx . depth - 1 ) as usize ] . remaining_length = length;
363
397
}
364
398
@@ -405,7 +439,7 @@ where
405
439
}
406
440
407
441
fn goto_previous_master ( & mut self ) -> Result < ( ) > {
408
- if self . ctx . depth == 0 || self . ctx . depth == self . ctx . lock_depth {
442
+ if self . ctx . depth == 0 || self . ctx . lock_depths . last ( ) == Some ( & self . ctx . depth ) {
409
443
decode_err ! ( @BAIL Ebml , "Cannot go to previous master element, already at root" )
410
444
}
411
445
@@ -468,10 +502,22 @@ where
468
502
pub ( crate ) fn lock ( & mut self ) {
469
503
self . ctx . locked = true ;
470
504
self . ctx . lock_len = self . current_master_length ( ) ;
505
+ self . ctx . lock_depths . push ( self . ctx . depth ) ;
471
506
}
472
507
473
508
pub ( crate ) fn unlock ( & mut self ) {
474
- self . ctx . locked = false ;
509
+ let _ = self . ctx . lock_depths . pop ( ) ;
510
+
511
+ let [ .., last] = & * self . ctx . lock_depths else {
512
+ // We can only ever *truly* unlock if we are at the root level.
513
+ log:: trace!( "Lock freed" ) ;
514
+
515
+ self . ctx . locked = false ;
516
+ return ;
517
+ } ;
518
+
519
+ log:: trace!( "Moving lock to depth: {}" , last) ;
520
+ self . ctx . lock_len = self . ctx . masters [ ( * last - 1 ) as usize ] . remaining_length ;
475
521
}
476
522
477
523
pub ( crate ) fn children ( & mut self ) -> ElementChildIterator < ' _ , R > {
@@ -595,6 +641,17 @@ where
595
641
}
596
642
}
597
643
644
+ /// An iterator over the children of an EBML master element.
645
+ ///
646
+ /// This is created by calling [`ElementReader::children`].
647
+ ///
648
+ /// This is essentially a fancy wrapper around `ElementReader` that:
649
+ ///
650
+ /// * Automatically skips unknown elements ([`ElementReaderYield::Unknown`]).
651
+ /// * [`Deref`]s to `ElementReader` so you can access the reader's methods.
652
+ /// * Unlocks the reader when dropped.
653
+ /// * If the reader is locked at multiple depths (meaning [`ElementReader::children`] was called
654
+ /// multiple times), it will move the lock to the previously locked depth.
598
655
pub ( crate ) struct ElementChildIterator < ' a , R >
599
656
where
600
657
R : Read ,
@@ -622,10 +679,15 @@ where
622
679
}
623
680
624
681
pub ( crate ) fn master_exhausted ( & self ) -> bool {
625
- let lock_depth = self . reader . ctx . lock_depth ;
626
- assert ! ( lock_depth < self . reader. ctx. depth) ;
627
-
628
- self . reader . ctx . masters [ lock_depth as usize ] . remaining_length == 0
682
+ let lock_depth = * self
683
+ . reader
684
+ . ctx
685
+ . lock_depths
686
+ . last ( )
687
+ . expect ( "a child iterator should always have a lock depth" ) ;
688
+ assert ! ( lock_depth <= self . reader. ctx. depth) ;
689
+
690
+ self . reader . ctx . masters [ ( lock_depth - 1 ) as usize ] . remaining_length == 0
629
691
}
630
692
}
631
693
0 commit comments