EBML stands for Extensible Binary Meta-Language and is somewhat of a binary version of XML. It's used for container formats like WebM or MKV.
IMPORTANT: The iterator contained in this crate is spec-agnostic and requires a specification implementing the
EbmlSpecification
andEbmlTag
traits to read files. Typically, you would only use this crate to implement a custom specification - most often you would prefer a crate providing an existing specification, like webm-iterable.
[dependencies]
ebml-iterable = "0.6.2"
The TagIterator
struct implements Rust's standard Iterator trait.
This struct can be created with the new
function on any source that implements the standard Read trait. The iterator outputs TSpec
objects based on the defined specification and the tag data.
Note: The
with_capacity
method can be used to construct aTagIterator
with a specified default buffer size. This is only useful as a microoptimization to memory management if you know the maximum tag size of the file you're reading.
The data in the tag can then be modified as desired (encryption, compression, etc.) and reencoded using the TagWriter
struct. This struct can be created with the new
function on any source that implements the standard Write trait. Once created, this struct can encode EBML using the write
method on any objects that implement EbmlSpecification
and EbmlTag
regardless of whether they came from a TagIterator
. This will emit binary EBML to the underlying Write
destination.
Most tag types contain their data directly, but there is a category of tag in EBML called Master
which contains other tags. This crate contains an enumeration of three different classifications of master tags:
Start
is a marker for the beginning of a "master" tag.End
is a marker for the end of a "master" tag.Full(children)
is a complete tag that includes all child tags of theMaster
tag. This is only emitted by theTagIterator
for tag types passed in viatags_to_buffer
.
pub enum TagDataType {
Master,
UnsignedInt,
Integer,
Utf8,
Binary,
Float,
}
TagDataType is an enum containing the possible data types stored within a tag. The relationship between the tag variant and the type of data contained in the tag directly corresponds is defined by whichever specification is in use. Because EBML is binary, the correct specification is required to parse tag content.
- Master: A complete master tag containing any number of child tags.
- UnsignedInt: An unsigned integer.
- Integer: A signed integer.
- Utf8: A Unicode text string. Note that the EBML spec includes a separate element type for ASCII. Given that ASCII is a subset of Utf8, this library currently parses and encodes both types using the same Utf8 logic.
- Binary: Binary data, otherwise uninterpreted.
- Float: IEEE-754 floating point number.
Note: This library made a concious decision to not parse "Date" elements from EBML due to lack of built-in support for dates in Rust. Specification implementations should treat Date elements as Binary so that consumers have the option of parsing the unaltered data using their library of choice, if needed.
Any specification based on EBML can use this library to parse or write binary data. Writing needs nothing special (if you use the write_raw()
method), but parsing requires a struct implementing the EbmlSpecification
and EbmlTag
traits. These traits currently have a large number of methods to implement and need consistent implementations to avoid errors, so any implementation attempt is recommended to use the "derive-spec"
feature flag in this crate and using the provided macro. Custom specification implementations can refer to webm-iterable as an example.
There is currently only one optional feature in this crate, but that may change over time as needs arise.
- derive-spec -
When enabled, this provides a macro to simplify implementations of the
EbmlSpecification
andEbmlTag
traits. This introduces dependencies onsyn
,quote
, andproc-macro2
, so expect compile times to increase a little.
Parsing and writing complete files should both work. Streaming (using tags of unknown size) should now also be supported, as of version 0.4.0. If something is broken, please create an issue.
Any additional feature requests can also be submitted as an issue.