1
1
use crate :: config:: ParseOptions ;
2
2
use crate :: ebml:: element_reader:: { ElementChildIterator , ElementIdent , ElementReaderYield } ;
3
- use crate :: ebml:: { EbmlTag , Language , SimpleTag , TagValue , TargetType } ;
3
+ use crate :: ebml:: { EbmlTag , Language , SimpleTag , Tag , TagValue , Target , TargetType } ;
4
4
use crate :: error:: Result ;
5
5
6
6
use crate :: macros:: decode_err;
17
17
while let Some ( child) = children_reader. next ( ) ? {
18
18
match child {
19
19
ElementReaderYield :: Master ( ( ElementIdent :: Tag , _size) ) => {
20
- read_tag ( & mut children_reader. children ( ) , tag) ?
20
+ let tag_element = read_tag ( & mut children_reader. children ( ) ) ?;
21
+ tag. tags . push ( tag_element) ;
21
22
} ,
22
23
ElementReaderYield :: Eof => break ,
23
24
_ => unimplemented ! ( "Unhandled child element in \\ Segment\\ Tags: {child:?}" ) ,
@@ -27,10 +28,13 @@ where
27
28
Ok ( ( ) )
28
29
}
29
30
30
- fn read_tag < R > ( children_reader : & mut ElementChildIterator < ' _ , R > , _tag : & mut EbmlTag ) -> Result < ( ) >
31
+ fn read_tag < R > ( children_reader : & mut ElementChildIterator < ' _ , R > ) -> Result < Tag >
31
32
where
32
33
R : Read + Seek ,
33
34
{
35
+ let mut target = None ;
36
+ let mut simple_tags = Vec :: new ( ) ;
37
+
34
38
while let Some ( child) = children_reader. next ( ) ? {
35
39
let ElementReaderYield :: Master ( ( master, _size) ) = child else {
36
40
match child {
@@ -43,39 +47,39 @@ where
43
47
44
48
match master {
45
49
ElementIdent :: Targets => {
46
- let _ = read_targets ( & mut children_reader. children ( ) ) ?;
50
+ if target. is_some ( ) {
51
+ decode_err ! (
52
+ @BAIL Ebml ,
53
+ "Duplicate Targets element found in \\ Segment\\ Tags\\ Tag"
54
+ ) ;
55
+ }
56
+
57
+ target = Some ( read_targets ( & mut children_reader. children ( ) ) ?) ;
47
58
} ,
48
59
ElementIdent :: SimpleTag => {
49
- let _ = read_simple_tag ( & mut children_reader. children ( ) ) ?;
60
+ simple_tags . push ( read_simple_tag ( & mut children_reader. children ( ) ) ?) ;
50
61
} ,
51
62
_ => {
52
63
unimplemented ! ( "Unhandled child element in \\ Segment\\ Tags\\ Tag: {master:?}" ) ;
53
64
} ,
54
65
}
55
66
}
56
67
57
- Ok ( ( ) )
58
- }
68
+ let Some ( target) = target else {
69
+ decode_err ! ( @BAIL Ebml , "\\ Segment\\ Tags\\ Tag is missing the required `Targets` element" ) ;
70
+ } ;
59
71
60
- struct Target {
61
- target_type_value : TargetType ,
62
- target_type : Option < String > ,
63
- track_uid : Vec < u64 > ,
64
- edition_uid : Vec < u64 > ,
65
- chapter_uid : Vec < u64 > ,
66
- attachment_uid : Vec < u64 > ,
72
+ Ok ( Tag {
73
+ target,
74
+ simple_tags,
75
+ } )
67
76
}
68
77
69
78
fn read_targets < R > ( children_reader : & mut ElementChildIterator < ' _ , R > ) -> Result < Target >
70
79
where
71
80
R : Read + Seek ,
72
81
{
73
- let mut target_type_value = None ;
74
- let mut target_type = None ;
75
- let mut track_uid = Vec :: new ( ) ;
76
- let mut edition_uid = Vec :: new ( ) ;
77
- let mut chapter_uid = Vec :: new ( ) ;
78
- let mut attachment_uid = Vec :: new ( ) ;
82
+ let mut target = Target :: default ( ) ;
79
83
80
84
while let Some ( child) = children_reader. next ( ) ? {
81
85
let ElementReaderYield :: Child ( ( child, size) ) = child else {
@@ -89,46 +93,43 @@ where
89
93
90
94
match child. ident {
91
95
ElementIdent :: TargetTypeValue => {
92
- target_type_value = Some ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
96
+ let value = children_reader. read_unsigned_int ( size. value ( ) ) ?;
97
+
98
+ // Casting the `u64` to `u8` is safe because the value is checked to be within
99
+ // the range of `TargetType` anyway.
100
+ let target_type = TargetType :: try_from ( value as u8 ) ?;
101
+ target. target_type = target_type;
93
102
} ,
94
103
ElementIdent :: TargetType => {
95
- target_type = Some ( children_reader. read_string ( size. value ( ) ) ?) ;
104
+ target . name = Some ( children_reader. read_string ( size. value ( ) ) ?) ;
96
105
} ,
97
106
ElementIdent :: TagTrackUID => {
98
- track_uid. push ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
107
+ let mut track_uids = target. track_uids . unwrap_or_default ( ) ;
108
+ track_uids. push ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
109
+ target. track_uids = Some ( track_uids) ;
99
110
} ,
100
111
ElementIdent :: TagEditionUID => {
101
- edition_uid. push ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
112
+ let mut edition_uids = target. edition_uids . unwrap_or_default ( ) ;
113
+ edition_uids. push ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
114
+ target. edition_uids = Some ( edition_uids) ;
102
115
} ,
103
116
ElementIdent :: TagChapterUID => {
104
- chapter_uid. push ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
117
+ let mut chapter_uids = target. chapter_uids . unwrap_or_default ( ) ;
118
+ chapter_uids. push ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
119
+ target. chapter_uids = Some ( chapter_uids) ;
105
120
} ,
106
121
ElementIdent :: TagAttachmentUID => {
107
- attachment_uid. push ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
122
+ let mut attachment_uids = target. attachment_uids . unwrap_or_default ( ) ;
123
+ attachment_uids. push ( children_reader. read_unsigned_int ( size. value ( ) ) ?) ;
124
+ target. attachment_uids = Some ( attachment_uids) ;
108
125
} ,
109
126
_ => {
110
127
unreachable ! ( "Unhandled child element in \\ Segment\\ Tags\\ Tag\\ Targets: {child:?}" )
111
128
} ,
112
129
}
113
130
}
114
131
115
- let target_type_value = match target_type_value {
116
- // Casting the `u64` to `u8` is safe because the value is checked to be within
117
- // the range of `TargetType` anyway.
118
- Some ( value) => TargetType :: try_from ( value as u8 ) ?,
119
- // The spec defines TargetType 50 (Album) as the default value, as it is the most
120
- // common grouping level.
121
- None => TargetType :: Album ,
122
- } ;
123
-
124
- Ok ( Target {
125
- target_type_value,
126
- target_type,
127
- track_uid,
128
- edition_uid,
129
- chapter_uid,
130
- attachment_uid,
131
- } )
132
+ Ok ( target)
132
133
}
133
134
134
135
fn read_simple_tag < R > ( children_reader : & mut ElementChildIterator < ' _ , R > ) -> Result < SimpleTag >
0 commit comments