mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-12-12 13:42:34 +00:00
EBML: Stub implement Segment parsing
Signed-off-by: Serial <69764315+Serial-ATA@users.noreply.github.com>
This commit is contained in:
parent
4ff820c9da
commit
ca7e3fe237
3 changed files with 81 additions and 17 deletions
|
@ -106,7 +106,7 @@ pub fn ebml_master_elements(input: TokenStream) -> TokenStream {
|
|||
});
|
||||
|
||||
TokenStream::from(quote! {
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||
pub(crate) enum ElementIdent {
|
||||
#( #identifiers_iter ),*
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
mod segment;
|
||||
|
||||
use super::EbmlFile;
|
||||
use crate::ebml::element_reader::{ElementIdent, ElementReader, ElementReaderYield};
|
||||
use crate::ebml::element_reader::{ElementHeader, ElementIdent, ElementReader, ElementReaderYield};
|
||||
use crate::ebml::vint::VInt;
|
||||
use crate::ebml::EbmlProperties;
|
||||
use crate::error::Result;
|
||||
use crate::macros::decode_err;
|
||||
|
@ -15,35 +18,38 @@ where
|
|||
// new ones all scattered throughout the file
|
||||
let mut properties = EbmlProperties::default();
|
||||
|
||||
let mut ebml_tag = None;
|
||||
|
||||
let mut element_reader = ElementReader::new(reader);
|
||||
|
||||
// First we need to go through the elements in the EBML master element
|
||||
read_ebml_header(&mut element_reader, parse_options, &mut properties)?;
|
||||
|
||||
loop {
|
||||
let ident;
|
||||
let data_ty;
|
||||
let size;
|
||||
|
||||
let res = element_reader.next()?;
|
||||
match res {
|
||||
ElementReaderYield::Master(_) => continue,
|
||||
ElementReaderYield::Child((child, size_)) => {
|
||||
ident = child.ident;
|
||||
data_ty = child.data_type;
|
||||
size = size_;
|
||||
ElementReaderYield::Master((ElementIdent::Segment, _)) => {
|
||||
ebml_tag = segment::read_from(&mut element_reader, parse_options, &mut properties)?;
|
||||
break;
|
||||
},
|
||||
ElementReaderYield::Unknown(element) => {
|
||||
log::debug!("Encountered unknown EBML element: {}", element.id.0);
|
||||
element_reader.skip(element.size.value())?;
|
||||
// CRC-32 (0xBF) and Void (0xEC) elements can occur at the top level.
|
||||
// This is valid, and we can just skip them.
|
||||
ElementReaderYield::Unknown(ElementHeader {
|
||||
id: VInt(id @ (0xBF | 0xEC)),
|
||||
size,
|
||||
}) => {
|
||||
log::debug!("Skipping global element: {:X}", id);
|
||||
element_reader.skip(size.value())?;
|
||||
continue;
|
||||
},
|
||||
ElementReaderYield::Eof => break,
|
||||
_ => {
|
||||
decode_err!(@BAIL Ebml, "File does not contain a segment element")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Ok(EbmlFile {
|
||||
ebml_tag: None,
|
||||
ebml_tag,
|
||||
properties,
|
||||
})
|
||||
}
|
||||
|
@ -78,7 +84,7 @@ where
|
|||
},
|
||||
ElementReaderYield::Unknown(element) => {
|
||||
log::debug!(
|
||||
"Encountered unknown EBML element in header: {}",
|
||||
"Encountered unknown EBML element in header: {:X}",
|
||||
element.id.0
|
||||
);
|
||||
element_reader.skip(element.size.value())?;
|
||||
|
|
58
src/ebml/read/segment.rs
Normal file
58
src/ebml/read/segment.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use crate::ebml::element_reader::{ElementIdent, ElementReader, ElementReaderYield};
|
||||
use crate::ebml::properties::EbmlProperties;
|
||||
use crate::ebml::tag::EbmlTag;
|
||||
use crate::error::Result;
|
||||
use crate::macros::decode_err;
|
||||
use crate::probe::ParseOptions;
|
||||
|
||||
use std::io::{Read, Seek};
|
||||
|
||||
pub(super) fn read_from<R>(
|
||||
element_reader: &mut ElementReader<R>,
|
||||
_parse_options: ParseOptions,
|
||||
_properties: &mut EbmlProperties,
|
||||
) -> Result<Option<EbmlTag>>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
element_reader.lock();
|
||||
|
||||
let mut tags = None;
|
||||
|
||||
loop {
|
||||
let res = element_reader.next()?;
|
||||
match res {
|
||||
ElementReaderYield::Master((id, size)) => match id {
|
||||
ElementIdent::Info => todo!("Support segment.Info"),
|
||||
ElementIdent::Cluster => todo!("Support segment.Cluster"),
|
||||
ElementIdent::Tracks => todo!("Support segment.Tracks"),
|
||||
ElementIdent::Tags => todo!("Support segment.Tags"),
|
||||
ElementIdent::Attachments => todo!("Support segment.Attachments"),
|
||||
ElementIdent::Chapters => todo!("Support segment.Chapters"),
|
||||
_ => {
|
||||
// We do not end up using information from all of the segment
|
||||
// elements, so we can just skip any useless ones.
|
||||
|
||||
log::debug!("Skipping EBML master element: {:?}", id);
|
||||
element_reader.skip(size)?;
|
||||
element_reader.goto_previous_master()?;
|
||||
continue;
|
||||
},
|
||||
},
|
||||
ElementReaderYield::Unknown(element) => {
|
||||
log::debug!("Skipping unknown EBML element: {:X}", element.id.0);
|
||||
element_reader.skip(element.size.value())?;
|
||||
continue;
|
||||
},
|
||||
ElementReaderYield::Eof => {
|
||||
element_reader.unlock();
|
||||
break;
|
||||
},
|
||||
_ => {
|
||||
decode_err!(@BAIL Ebml, "Segment element should only contain master elements")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Ok(tags)
|
||||
}
|
Loading…
Reference in a new issue