Skip to content

Commit d710bcd

Browse files
committed
EBML: Start parsing \Ebml\Segment\Tags\Tag\SimpleTag
1 parent d2b0a93 commit d710bcd

File tree

2 files changed

+132
-32
lines changed

2 files changed

+132
-32
lines changed

lofty/src/ebml/element_reader.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ struct MasterElementContext {
250250
const MAX_DEPTH: u8 = 16;
251251
const ROOT_DEPTH: u8 = 1;
252252

253+
#[derive(Debug)]
253254
struct ElementReaderContext {
254255
depth: u8,
255256
masters: Vec<MasterElementContext>,
@@ -439,7 +440,7 @@ where
439440
}
440441

441442
fn goto_previous_master(&mut self) -> Result<()> {
442-
if self.ctx.depth == 0 || self.ctx.lock_depths.last() == Some(&self.ctx.depth) {
443+
if self.ctx.depth == ROOT_DEPTH || self.ctx.lock_depths.last() == Some(&self.ctx.depth) {
443444
decode_err!(@BAIL Ebml, "Cannot go to previous master element, already at root")
444445
}
445446

@@ -500,6 +501,8 @@ where
500501
}
501502

502503
pub(crate) fn lock(&mut self) {
504+
log::trace!("New lock at depth: {}", self.ctx.depth);
505+
503506
self.ctx.locked = true;
504507
self.ctx.lock_len = self.current_master_length();
505508
self.ctx.lock_depths.push(self.ctx.depth);

lofty/src/ebml/read/segment_tags.rs

Lines changed: 128 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::config::ParseOptions;
22
use crate::ebml::element_reader::{ElementChildIterator, ElementIdent, ElementReaderYield};
3-
use crate::ebml::{EbmlTag, TargetType};
3+
use crate::ebml::{EbmlTag, Language, SimpleTag, TagValue, TargetType};
44
use crate::error::Result;
55

66
use crate::macros::decode_err;
@@ -19,6 +19,7 @@ where
1919
ElementReaderYield::Master((ElementIdent::Tag, _size)) => {
2020
read_tag(&mut children_reader.children(), tag)?
2121
},
22+
ElementReaderYield::Eof => break,
2223
_ => unimplemented!("Unhandled child element in \\Ebml\\Segment\\Tags: {child:?}"),
2324
}
2425
}
@@ -31,14 +32,25 @@ where
3132
R: Read + Seek,
3233
{
3334
while let Some(child) = children_reader.next()? {
34-
match child {
35-
ElementReaderYield::Master((ElementIdent::Targets, _size)) => {
35+
let ElementReaderYield::Master((master, _size)) = child else {
36+
match child {
37+
ElementReaderYield::Eof => break,
38+
_ => {
39+
unreachable!("Unhandled child element in \\Ebml\\Segment\\Tags\\Tag: {child:?}")
40+
},
41+
}
42+
};
43+
44+
match master {
45+
ElementIdent::Targets => {
3646
let _ = read_targets(&mut children_reader.children())?;
3747
},
38-
ElementReaderYield::Master((ElementIdent::SimpleTag, _size)) => {
39-
read_simple_tag(&mut children_reader.children())?
48+
ElementIdent::SimpleTag => {
49+
let _ = read_simple_tag(&mut children_reader.children())?;
50+
},
51+
_ => {
52+
unimplemented!("Unhandled child element in \\Ebml\\Segment\\Tags\\Tag: {master:?}");
4053
},
41-
_ => unimplemented!("Unhandled child element in \\Ebml\\Segment\\Tags: {child:?}"),
4254
}
4355
}
4456

@@ -66,33 +78,38 @@ where
6678
let mut attachment_uid = Vec::new();
6779

6880
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-
},
81+
let ElementReaderYield::Child((child, size)) = child else {
82+
match child {
83+
ElementReaderYield::Eof => break,
8984
_ => unreachable!(
90-
"Unhandled child element in \\Ebml\\Segment\\Tags\\Targets: {child:?}"
85+
"Unhandled child element in \\Ebml\\Segment\\Tags\\Tag\\Targets: {child:?}"
9186
),
87+
}
88+
};
89+
90+
match child.ident {
91+
ElementIdent::TargetTypeValue => {
92+
target_type_value = Some(children_reader.read_unsigned_int(size.value())?);
93+
},
94+
ElementIdent::TargetType => {
95+
target_type = Some(children_reader.read_string(size.value())?);
96+
},
97+
ElementIdent::TagTrackUID => {
98+
track_uid.push(children_reader.read_unsigned_int(size.value())?);
99+
},
100+
ElementIdent::TagEditionUID => {
101+
edition_uid.push(children_reader.read_unsigned_int(size.value())?);
102+
},
103+
ElementIdent::TagChapterUID => {
104+
chapter_uid.push(children_reader.read_unsigned_int(size.value())?);
105+
},
106+
ElementIdent::TagAttachmentUID => {
107+
attachment_uid.push(children_reader.read_unsigned_int(size.value())?);
92108
},
93-
ElementReaderYield::Eof => break,
94109
_ => {
95-
unreachable!("Unhandled child element in \\Ebml\\Segment\\Tags\\Targets: {child:?}")
110+
unreachable!(
111+
"Unhandled child element in \\Ebml\\Segment\\Tags\\Tag\\Targets: {child:?}"
112+
)
96113
},
97114
}
98115
}
@@ -116,9 +133,89 @@ where
116133
})
117134
}
118135

119-
fn read_simple_tag<R>(_children_reader: &mut ElementChildIterator<'_, R>) -> Result<()>
136+
fn read_simple_tag<R>(children_reader: &mut ElementChildIterator<'_, R>) -> Result<SimpleTag>
120137
where
121138
R: Read + Seek,
122139
{
123-
unimplemented!("\\Ebml\\Segment\\Tags\\SimpleTag")
140+
let mut name = None;
141+
let mut language = None;
142+
let mut default = false;
143+
let mut value = None;
144+
145+
while let Some(child) = children_reader.next()? {
146+
let ElementReaderYield::Child((child, size)) = child else {
147+
match child {
148+
ElementReaderYield::Eof => break,
149+
_ => unreachable!(
150+
"Unhandled child element in \\Ebml\\Segment\\Tags\\Tag\\SimpleTag: {child:?}"
151+
),
152+
}
153+
};
154+
155+
match child.ident {
156+
ElementIdent::TagName => {
157+
name = Some(children_reader.read_string(size.value())?);
158+
},
159+
ElementIdent::TagLanguage => {
160+
if language.is_some() {
161+
log::warn!("Duplicate language found in SimpleTag, ignoring");
162+
children_reader.skip(size.value())?;
163+
continue;
164+
}
165+
166+
language = Some(Language::Iso639_2(
167+
children_reader.read_string(size.value())?,
168+
));
169+
},
170+
ElementIdent::TagLanguageBCP47 => {
171+
if language.is_some() {
172+
log::warn!("Duplicate language found in SimpleTag, ignoring");
173+
children_reader.skip(size.value())?;
174+
continue;
175+
}
176+
177+
language = Some(Language::Bcp47(children_reader.read_string(size.value())?));
178+
},
179+
ElementIdent::TagDefault => {
180+
default = children_reader.read_flag(size.value())?;
181+
},
182+
ElementIdent::TagString => {
183+
if value.is_some() {
184+
log::warn!("Duplicate value found in SimpleTag, ignoring");
185+
children_reader.skip(size.value())?;
186+
continue;
187+
}
188+
189+
value = Some(TagValue::String(children_reader.read_string(size.value())?));
190+
},
191+
ElementIdent::TagBinary => {
192+
if value.is_some() {
193+
log::warn!("Duplicate value found in SimpleTag, ignoring");
194+
children_reader.skip(size.value())?;
195+
continue;
196+
}
197+
198+
value = Some(TagValue::Binary(children_reader.read_binary(size.value())?));
199+
},
200+
_ => {
201+
unreachable!(
202+
"Unhandled child element in \\Ebml\\Segment\\Tags\\Tag\\SimpleTag: {child:?}"
203+
);
204+
},
205+
}
206+
}
207+
208+
let Some(name) = name else {
209+
decode_err!(
210+
@BAIL Ebml,
211+
"SimpleTag is missing the required TagName element"
212+
);
213+
};
214+
215+
Ok(SimpleTag {
216+
name,
217+
language,
218+
default,
219+
value,
220+
})
124221
}

0 commit comments

Comments
 (0)