1
1
use crate :: config:: ParseOptions ;
2
2
use crate :: ebml:: element_reader:: { ElementChildIterator , ElementIdent , ElementReaderYield } ;
3
- use crate :: ebml:: EbmlTag ;
3
+ use crate :: ebml:: { EbmlTag , TargetType } ;
4
4
use crate :: error:: Result ;
5
5
6
+ use crate :: macros:: decode_err;
6
7
use std:: io:: { Read , Seek } ;
7
8
8
9
pub ( super ) fn read_from < R > (
32
33
while let Some ( child) = children_reader. next ( ) ? {
33
34
match child {
34
35
ElementReaderYield :: Master ( ( ElementIdent :: Targets , _size) ) => {
35
- read_targets ( & mut children_reader. children ( ) ) ?
36
+ let _ = read_targets ( & mut children_reader. children ( ) ) ?;
36
37
} ,
37
- ElementReaderYield :: Master ( ( ElementIdent :: Tag , _size) ) => {
38
+ ElementReaderYield :: Master ( ( ElementIdent :: SimpleTag , _size) ) => {
38
39
read_simple_tag ( & mut children_reader. children ( ) ) ?
39
40
} ,
40
41
_ => unimplemented ! ( "Unhandled child element in \\ Ebml\\ Segment\\ Tags: {child:?}" ) ,
@@ -44,11 +45,75 @@ where
44
45
Ok ( ( ) )
45
46
}
46
47
47
- fn read_targets < R > ( _children_reader : & mut ElementChildIterator < ' _ , R > ) -> Result < ( ) >
48
+ struct Target {
49
+ target_type_value : TargetType ,
50
+ target_type : Option < String > ,
51
+ track_uid : Vec < u64 > ,
52
+ edition_uid : Vec < u64 > ,
53
+ chapter_uid : Vec < u64 > ,
54
+ attachment_uid : Vec < u64 > ,
55
+ }
56
+
57
+ fn read_targets < R > ( children_reader : & mut ElementChildIterator < ' _ , R > ) -> Result < Target >
48
58
where
49
59
R : Read + Seek ,
50
60
{
51
- unimplemented ! ( "\\ Ebml\\ Segment\\ Tags\\ Targets" )
61
+ let mut target_type_value = None ;
62
+ let mut target_type = None ;
63
+ let mut track_uid = Vec :: new ( ) ;
64
+ let mut edition_uid = Vec :: new ( ) ;
65
+ let mut chapter_uid = Vec :: new ( ) ;
66
+ let mut attachment_uid = Vec :: new ( ) ;
67
+
68
+ while let Some ( child) = children_reader. next ( ) ? {
69
+ match child {
70
+ ElementReaderYield :: Child ( ( child, size) ) => match child. ident {
71
+ ElementIdent :: TargetTypeValue => {
72
+ target_type_value = Some ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
73
+ } ,
74
+ ElementIdent :: TargetType => {
75
+ target_type = Some ( children_reader. read_string ( size. value ( ) ) ?) ;
76
+ } ,
77
+ ElementIdent :: TagTrackUID => {
78
+ track_uid. push ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
79
+ } ,
80
+ ElementIdent :: TagEditionUID => {
81
+ edition_uid. push ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
82
+ } ,
83
+ ElementIdent :: TagChapterUID => {
84
+ chapter_uid. push ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
85
+ } ,
86
+ ElementIdent :: TagAttachmentUID => {
87
+ attachment_uid. push ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
88
+ } ,
89
+ _ => unreachable ! (
90
+ "Unhandled child element in \\ Ebml\\ Segment\\ Tags\\ Targets: {child:?}"
91
+ ) ,
92
+ } ,
93
+ ElementReaderYield :: Eof => break ,
94
+ _ => {
95
+ unreachable ! ( "Unhandled child element in \\ Ebml\\ Segment\\ Tags\\ Targets: {child:?}" )
96
+ } ,
97
+ }
98
+ }
99
+
100
+ let target_type_value = match target_type_value {
101
+ // Casting the `u64` to `u8` is safe because the value is checked to be within
102
+ // the range of `TargetType` anyway.
103
+ Some ( value) => TargetType :: try_from ( value as u8 ) ?,
104
+ // The spec defines TargetType 50 (Album) as the default value, as it is the most
105
+ // common grouping level.
106
+ None => TargetType :: Album ,
107
+ } ;
108
+
109
+ Ok ( Target {
110
+ target_type_value,
111
+ target_type,
112
+ track_uid,
113
+ edition_uid,
114
+ chapter_uid,
115
+ attachment_uid,
116
+ } )
52
117
}
53
118
54
119
fn read_simple_tag < R > ( _children_reader : & mut ElementChildIterator < ' _ , R > ) -> Result < ( ) >
0 commit comments