Skip to content

Commit

Permalink
Added in an option to specify ebml size byte length; bump to version …
Browse files Browse the repository at this point in the history
…0.6.0; realized I also had some updates to the async side... probably need to test those more since they were just sitting here uncommitted for awhile
  • Loading branch information
austinleroy committed Oct 20, 2023
1 parent a64c34a commit 2861d15
Show file tree
Hide file tree
Showing 9 changed files with 331 additions and 81 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ebml-iterable"
version = "0.5.0"
version = "0.6.0"
authors = ["Austin Blake <austinl3roy@gmail.com>"]
edition = "2018"
description = "This crate provides an iterator over EBML encoded data. The items provided by the iterator are Tags as defined in EBML. The iterator is spec-agnostic and requires a specification implementing specific 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`."
Expand All @@ -16,7 +16,7 @@ repository = "https://github.com/austinleroy/ebml-iterable"
[dependencies]
ebml-iterable-specification = { version = "=0.4.0", path = "specification" }
ebml-iterable-specification-derive = { version = "=0.4.0", path = "specification-derive", optional = true }
futures = "0.3.21"
futures = { version = "0.3.28", optional = true }

[features]
derive-spec = ["ebml-iterable-specification-derive"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ binary version of XML. It's used for container formats like [WebM][webm] or
```Cargo.toml
[dependencies]
ebml-iterable = "0.5.0"
ebml-iterable = "0.6.0"
```

# Usage
Expand Down
7 changes: 4 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,17 @@

mod errors;
mod tag_iterator;
mod tag_iterator_async;
mod tag_writer;
pub mod tools;
pub mod specs;
mod tag_iterator_util;
mod spec_util;

#[cfg(feature = "futures")]
pub mod nonblocking;

pub use self::tag_iterator::TagIterator;
pub use self::tag_iterator_async::TagIteratorAsync;
pub use self::tag_writer::TagWriter;
pub use self::tag_writer::{TagWriter, WriteOptions};

pub mod iterator {
pub use super::tag_iterator_util::AllowableErrors;
Expand Down
53 changes: 53 additions & 0 deletions src/nonblocking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use std::io::Cursor;
use ebml_iterable_specification::{EbmlSpecification, EbmlTag};
use futures::{AsyncRead, AsyncReadExt, Stream};
use crate::error::TagIteratorError;
use crate::TagIterator;

///
/// This can be transformed into a [`Stream`] using [`into_stream`][TagIteratorAsync::into_stream], or consumed directly by calling [`.next().await`] in a loop.
///
/// The struct can be created with the [`new()`][TagIteratorAsync::new] function on any source that implements the [`futures::AsyncRead`] trait.
///
pub struct TagIteratorAsync<R: AsyncRead + Unpin, TSpec>
where
TSpec: EbmlSpecification<TSpec> + EbmlTag<TSpec> + Clone
{
source: R,
buffer: Box<[u8]>,
iterator: TagIterator<Cursor<Vec<u8>>, TSpec>
}

impl<R: AsyncRead + Unpin, TSpec> TagIteratorAsync<R, TSpec>
where
TSpec: EbmlSpecification<TSpec> + EbmlTag<TSpec> + Clone
{

pub fn new(source: R, tags_to_buffer: &[TSpec]) -> Self {
let buffer = vec![0u8; 1024 * 64];
Self {
source,
buffer: buffer.into_boxed_slice(),
iterator: TagIterator::new(Cursor::new(Vec::new()), tags_to_buffer)
}
}

pub async fn next(&mut self) -> Option<Result<TSpec, TagIteratorError>> {
match self.source.read(&mut self.buffer).await {
Ok(len) => {
self.iterator.get_mut().get_mut().append(&mut self.buffer[..len].to_vec());
self.iterator.next()
},
Err(e) => {
Some(Err(TagIteratorError::ReadError { source: e }))
}
}
}

pub fn into_stream(self) -> impl Stream<Item=Result<TSpec, TagIteratorError>> {
futures::stream::unfold(self, |mut read| async {
let next = read.next().await;
next.map(move |it| (it, read))
})
}
}
2 changes: 1 addition & 1 deletion src/spec_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub fn is_ended_by<T: EbmlSpecification<T> + EbmlTag<T> + Clone>(current_id: u64
}

#[inline(always)]
pub fn validate_tag_path<T: EbmlSpecification<T> + EbmlTag<T> + Clone>(tag_id: u64, doc_path: impl Iterator<Item = (u64, EBMLSize)>) -> bool {
pub fn validate_tag_path<T: EbmlSpecification<T> + EbmlTag<T> + Clone>(tag_id: u64, doc_path: impl Iterator<Item = (u64, EBMLSize, usize)>) -> bool {
let path = <T>::get_path_by_id(tag_id);
let mut path_marker = 0;
let mut global_counter = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/tag_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ impl<R: Read, TSpec> TagIterator<R, TSpec>

#[inline(always)]
fn validate_tag_path(&self, tag_id: u64) -> bool {
validate_tag_path::<TSpec>(tag_id, self.tag_stack.iter().map(|p| (p.tag.get_id(), p.size)))
validate_tag_path::<TSpec>(tag_id, self.tag_stack.iter().map(|p| (p.tag.get_id(), p.size, 0)))
}

#[inline(always)]
Expand Down
Loading

0 comments on commit 2861d15

Please sign in to comment.