From 0909a20a8c5597467f94550d20bfb4c104c863ac Mon Sep 17 00:00:00 2001 From: Tangent 128 Date: Tue, 3 Apr 2018 23:23:19 -0400 Subject: [PATCH] generalize WebmEventSource -> EbmlEventSource --- src/chunk.rs | 9 ++--- src/ebml.rs | 6 ++++ src/iterator.rs | 86 +++++++++++++++++++++++++++++++--------------- src/webm.rs | 8 +---- src/webm_stream.rs | 5 ++- 5 files changed, 73 insertions(+), 41 deletions(-) diff --git a/src/chunk.rs b/src/chunk.rs index 449248b..0de1459 100644 --- a/src/chunk.rs +++ b/src/chunk.rs @@ -2,6 +2,7 @@ use futures::{Async, Stream}; use std::io::Cursor; use std::mem; use std::sync::Arc; +use ebml::EbmlEventSource; use webm::*; #[derive(Clone, Debug)] @@ -87,12 +88,12 @@ pub enum ChunkingError { OtherError(E) } -pub struct WebmChunker { +pub struct WebmChunker { source: S, state: ChunkerState } -impl<'a, S: WebmEventSource> Stream for WebmChunker +impl<'a, S: EbmlEventSource> Stream for WebmChunker { type Item = Chunk; type Error = ChunkingError; @@ -209,11 +210,11 @@ impl<'a, S: WebmEventSource> Stream for WebmChunker } } -pub trait WebmStream { +pub trait WebmStream { fn chunk_webm(self) -> WebmChunker; } -impl<'a, T: WebmEventSource> WebmStream for T { +impl<'a, T: EbmlEventSource> WebmStream for T { fn chunk_webm(self) -> WebmChunker { WebmChunker { source: self, diff --git a/src/ebml.rs b/src/ebml.rs index f0797e7..d780b89 100644 --- a/src/ebml.rs +++ b/src/ebml.rs @@ -2,6 +2,7 @@ use bytes::{BigEndian, ByteOrder, BufMut}; use std::error::Error as ErrorTrait; use std::fmt::{Display, Formatter, Result as FmtResult}; use std::io::{Cursor, Error as IoError, ErrorKind, Result as IoResult, Write, Seek, SeekFrom}; +use futures::Async; pub const EBML_HEAD_ID: u64 = 0x0A45DFA3; pub const DOC_TYPE_ID: u64 = 0x0282; @@ -286,6 +287,11 @@ pub trait FromEbml<'a>: Sized { } } +pub trait EbmlEventSource { + type Error; + fn poll_event<'a, T: FromEbml<'a>>(&'a mut self) -> Result>, Self::Error>; +} + #[cfg(test)] mod tests { use bytes::{BytesMut}; diff --git a/src/iterator.rs b/src/iterator.rs index a668835..d8a6850 100644 --- a/src/iterator.rs +++ b/src/iterator.rs @@ -1,47 +1,79 @@ use futures::Async; use ebml::Error as EbmlError; +use ebml::EbmlEventSource; use ebml::FromEbml; -use webm::*; +use webm::WebmElement; -pub struct EbmlCursor { - source: T, - position: usize +pub struct EbmlCursor<'a> { + source: &'a [u8] } -impl EbmlCursor { - pub fn new(source: S) -> Self { +impl<'a> EbmlCursor<'a> { + pub fn new(source: &'a [u8]) -> Self { EbmlCursor { - source, - position: 0 + source } } } -impl<'a> EbmlCursor<&'a [u8]> { - fn decode_element>(&mut self) -> Result, EbmlError> { - match T::decode_element(&self.source.as_ref()[self.position..]) { - Err(err) => Err(err), - Ok(None) => Ok(None), - Ok(Some((element, element_size))) => { - self.position += element_size; - Ok(Some(element)) +impl<'a> Iterator for EbmlCursor<'a> { + type Item = WebmElement<'a>; + + fn next(&mut self) -> Option> { + match WebmElement::check_space(self.source) { + Err(err) => { + None + }, + Ok(None) => { + None + }, + Ok(Some(element_size)) => { + let (element_data, rest) = self.source.split_at(element_size); + self.source = rest; + match WebmElement::decode_element(element_data) { + Err(err) => { + None + }, + Ok(None) => { + // buffer should have enough data + panic!("Buffer was supposed to have enough data to parse element, somehow did not.") + }, + Ok(Some((element, _))) => { + Some(element) + } + } } } } } -impl<'a> Iterator for EbmlCursor<&'a [u8]> { - type Item = WebmElement<'a>; - - fn next(&mut self) -> Option> { - self.decode_element().unwrap_or(None) - } -} - -impl<'b> WebmEventSource for EbmlCursor<&'b [u8]> { +impl<'b> EbmlEventSource for EbmlCursor<'b> { type Error = EbmlError; - fn poll_event<'a>(&'a mut self) -> Result>>, EbmlError> { - self.decode_element().map(Async::Ready) + fn poll_event<'a, T: FromEbml<'a>>(&'a mut self) -> Result>, EbmlError> { + match T::check_space(self.source) { + Err(err) => { + Err(err) + }, + Ok(None) => { + Ok(None) + }, + Ok(Some(element_size)) => { + let (element_data, rest) = self.source.split_at(element_size); + self.source = rest; + match T::decode_element(element_data) { + Err(err) => { + Err(err) + }, + Ok(None) => { + // buffer should have enough data + panic!("Buffer was supposed to have enough data to parse element, somehow did not.") + }, + Ok(Some((element, _))) => { + Ok(Some(element)) + } + } + } + }.map(Async::Ready) } } diff --git a/src/webm.rs b/src/webm.rs index 338723f..50d76cd 100644 --- a/src/webm.rs +++ b/src/webm.rs @@ -1,6 +1,5 @@ use std::io::{Cursor, Error as IoError, ErrorKind, Result as IoResult, Write, Seek}; use bytes::{BigEndian, BufMut, ByteOrder}; -use futures::Async; use ebml::*; use iterator::EbmlCursor; @@ -13,7 +12,7 @@ const CLUSTER_ID: u64 = 0x0F43B675; const TIMECODE_ID: u64 = 0x67; const SIMPLE_BLOCK_ID: u64 = 0x23; -pub fn parse_webm<'a, T: AsRef<[u8]> + ?Sized>(source: &'a T) -> EbmlCursor<&'a [u8]> { +pub fn parse_webm<'a, T: AsRef<[u8]> + ?Sized>(source: &'a T) -> EbmlCursor<'a> { EbmlCursor::new(source.as_ref()) } @@ -127,11 +126,6 @@ pub fn encode_webm_element(element: &WebmElement, output: &mut } } -pub trait WebmEventSource { - type Error; - fn poll_event<'a>(&'a mut self) -> Result>>, Self::Error>; -} - #[cfg(test)] mod tests { use tests::TEST_FILE; diff --git a/src/webm_stream.rs b/src/webm_stream.rs index b9124a1..2bd2177 100644 --- a/src/webm_stream.rs +++ b/src/webm_stream.rs @@ -4,7 +4,6 @@ use futures::Async; use futures::stream::Stream; use ebml::*; -use webm::*; pub enum ParsingError { EbmlError(::ebml::Error), @@ -71,10 +70,10 @@ impl, S: Stream> WebmBuffer { } } -impl, S: Stream> WebmEventSource for WebmBuffer { +impl, S: Stream> EbmlEventSource for WebmBuffer { type Error = ParsingError; - fn poll_event<'a>(&'a mut self) -> Result>>, Self::Error> { + fn poll_event<'a, T: FromEbml<'a>>(&'a mut self) -> Result>, Self::Error> { return WebmBuffer::poll_event(self); } }