refactor SimpleBlock struct to be independent of Element enum

This commit is contained in:
Tangent 128 2017-09-04 01:41:48 -04:00
parent fd8b820eef
commit 93883e2683
3 changed files with 39 additions and 37 deletions

View file

@ -5,6 +5,7 @@ use std::fs::File;
use std::io::Read; use std::io::Read;
use std::path::Path; use std::path::Path;
use lab_ebml::Schema; use lab_ebml::Schema;
use lab_ebml::webm::SimpleBlock;
use lab_ebml::webm::Webm; use lab_ebml::webm::Webm;
use lab_ebml::webm::WebmElement::*; use lab_ebml::webm::WebmElement::*;
@ -22,7 +23,7 @@ pub fn main() {
match element { match element {
// suppress printing byte arrays // suppress printing byte arrays
Tracks(slice) => println!("Tracks[{}]", slice.len()), Tracks(slice) => println!("Tracks[{}]", slice.len()),
SimpleBlock{timecode, ..} => println!("SimpleBlock@{}", timecode), SimpleBlock(SimpleBlock {timecode, ..}) => println!("SimpleBlock@{}", timecode),
other => println!("{:?}", other) other => println!("{:?}", other)
} }
} }

View file

@ -14,12 +14,12 @@ pub fn main() {
encode_webm_element(WebmElement::Cluster, &mut cursor).unwrap(); encode_webm_element(WebmElement::Cluster, &mut cursor).unwrap();
encode_webm_element(WebmElement::Timecode(0), &mut cursor).unwrap(); encode_webm_element(WebmElement::Timecode(0), &mut cursor).unwrap();
encode_webm_element(WebmElement::SimpleBlock { encode_webm_element(WebmElement::SimpleBlock(SimpleBlock {
track: 3, track: 3,
flags: 0x0, flags: 0x0,
timecode: 123, timecode: 123,
data: "Hello, World".as_bytes() data: "Hello, World".as_bytes()
}, &mut cursor).unwrap(); }), &mut cursor).unwrap();
encode_webm_element(WebmElement::Cluster, &mut cursor).unwrap(); encode_webm_element(WebmElement::Cluster, &mut cursor).unwrap();
encode_webm_element(WebmElement::Timecode(1000), &mut cursor).unwrap(); encode_webm_element(WebmElement::Timecode(1000), &mut cursor).unwrap();

View file

@ -12,6 +12,14 @@ const TIMECODE_ID: u64 = 0x67;
const SIMPLE_BLOCK_ID: u64 = 0x23; const SIMPLE_BLOCK_ID: u64 = 0x23;
pub struct Webm; pub struct Webm;
#[derive(Debug, PartialEq)]
pub struct SimpleBlock<'b> {
pub track: u64,
pub timecode: i16,
pub flags: u8,
pub data: &'b[u8]
}
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum WebmElement<'b> { pub enum WebmElement<'b> {
EbmlHead, EbmlHead,
@ -23,12 +31,7 @@ pub enum WebmElement<'b> {
Tracks(&'b[u8]), Tracks(&'b[u8]),
Cluster, Cluster,
Timecode(u64), Timecode(u64),
SimpleBlock { SimpleBlock(SimpleBlock<'b>),
track: u64,
timecode: i16,
flags: u8,
data: &'b[u8]
},
Unknown(u64) Unknown(u64)
} }
@ -69,42 +72,40 @@ fn decode_simple_block(bytes: &[u8]) -> Result<WebmElement, Error> {
} }
let timecode = BigEndian::read_i16(&bytes[track_field_len..]); let timecode = BigEndian::read_i16(&bytes[track_field_len..]);
let flags = bytes[track_field_len + 2]; let flags = bytes[track_field_len + 2];
return Ok(WebmElement::SimpleBlock { return Ok(WebmElement::SimpleBlock(SimpleBlock {
track: track, track: track,
timecode: timecode, timecode: timecode,
flags: flags, flags: flags,
data: &bytes[header_len..], data: &bytes[header_len..],
}) }))
} else { } else {
return Err(Error::CorruptPayload); return Err(Error::CorruptPayload);
} }
} }
pub fn encode_simple_block<T: Write>(element: WebmElement, output: &mut T) -> IoResult<()> { pub fn encode_simple_block<T: Write>(block: SimpleBlock, output: &mut T) -> IoResult<()> {
if let WebmElement::SimpleBlock{ let SimpleBlock {
track, track,
timecode, timecode,
flags, flags,
data data
} = element { } = block;
// limiting number of tracks for now
if track > 31 {
return Err(IoError::new(ErrorKind::InvalidInput, WriteError::OutOfRange));
}
let header_len = 1 + 2 + 1;
encode_tag_header(SIMPLE_BLOCK_ID, Varint::Value((header_len + data.len()) as u64), output)?;
encode_varint(Varint::Value(track), output)?; // limiting number of tracks for now
if track > 31 {
let mut buffer = Cursor::new([0; 3]); return Err(IoError::new(ErrorKind::InvalidInput, WriteError::OutOfRange));
buffer.put_i16::<BigEndian>(timecode);
buffer.put_u8(flags);
output.write_all(&buffer.get_ref()[..])?;
output.write_all(data)
} else {
Err(IoError::new(ErrorKind::InvalidInput, WriteError::OutOfRange))
} }
let header_len = 1 + 2 + 1;
encode_tag_header(SIMPLE_BLOCK_ID, Varint::Value((header_len + data.len()) as u64), output)?;
encode_varint(Varint::Value(track), output)?;
let mut buffer = Cursor::new([0; 3]);
buffer.put_i16::<BigEndian>(timecode);
buffer.put_u8(flags);
output.write_all(&buffer.get_ref()[..])?;
output.write_all(data)
} }
pub fn encode_webm_element<T: Write + Seek>(element: WebmElement, output: &mut T) -> IoResult<()> { pub fn encode_webm_element<T: Write + Seek>(element: WebmElement, output: &mut T) -> IoResult<()> {
@ -118,7 +119,7 @@ pub fn encode_webm_element<T: Write + Seek>(element: WebmElement, output: &mut T
WebmElement::Tracks(data) => encode_bytes(TRACKS_ID, data, output), WebmElement::Tracks(data) => encode_bytes(TRACKS_ID, data, output),
WebmElement::Cluster => encode_tag_header(CLUSTER_ID, Varint::Unknown, output), WebmElement::Cluster => encode_tag_header(CLUSTER_ID, Varint::Unknown, output),
WebmElement::Timecode(time) => encode_integer(TIMECODE_ID, time, output), WebmElement::Timecode(time) => encode_integer(TIMECODE_ID, time, output),
WebmElement::SimpleBlock {..} => encode_simple_block(element, output), WebmElement::SimpleBlock(block) => encode_simple_block(block, output),
_ => Err(IoError::new(ErrorKind::InvalidInput, WriteError::OutOfRange)) _ => Err(IoError::new(ErrorKind::InvalidInput, WriteError::OutOfRange))
} }
} }
@ -142,24 +143,24 @@ mod tests {
assert_eq!(iter.next(), Some(WebmElement::Cluster)); assert_eq!(iter.next(), Some(WebmElement::Cluster));
assert_eq!(iter.next(), Some(WebmElement::Timecode(0))); assert_eq!(iter.next(), Some(WebmElement::Timecode(0)));
assert_eq!(iter.next(), Some(WebmElement::SimpleBlock { assert_eq!(iter.next(), Some(WebmElement::SimpleBlock(SimpleBlock {
track: 1, track: 1,
timecode: 0, timecode: 0,
flags: 0b10000000, flags: 0b10000000,
data: &TEST_FILE[443..3683] data: &TEST_FILE[443..3683]
})); })));
assert_eq!(iter.next(), Some(WebmElement::SimpleBlock { assert_eq!(iter.next(), Some(WebmElement::SimpleBlock(SimpleBlock {
track: 1, track: 1,
timecode: 33, timecode: 33,
flags: 0b00000000, flags: 0b00000000,
data: &TEST_FILE[3690..4735] data: &TEST_FILE[3690..4735]
})); })));
assert_eq!(iter.next(), Some(WebmElement::SimpleBlock { assert_eq!(iter.next(), Some(WebmElement::SimpleBlock(SimpleBlock {
track: 1, track: 1,
timecode: 67, timecode: 67,
flags: 0b00000000, flags: 0b00000000,
data: &TEST_FILE[4741..4801] data: &TEST_FILE[4741..4801]
})); })));
for _ in 3..30 { for _ in 3..30 {
// skip remaining contents for brevity // skip remaining contents for brevity
iter.next(); iter.next();