Created
August 8, 2018 18:46
-
-
Save pirogoeth/4818d14b5772194a930aba4869b7435a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::io; | |
use std::io::{ Write }; | |
use super::TARBOX_MAGIC; | |
use super::attributes; | |
use super::attributes::AttributeContainer; | |
#[derive(Clone, Debug)] | |
pub struct Encoder<A> where A: attributes::AttributeContainer { | |
inner: Vec<u8>, | |
content_size: usize, | |
attributes: A, | |
} | |
impl<A> Encoder<A> where A: attributes::AttributeContainer { | |
/// Returns a new Encoder including a new, empty `AttributesV1` instance. | |
fn new(attrs: A) -> Encoder<A> { | |
Encoder { | |
inner: Vec::new(), | |
content_size: 0, | |
attributes: attrs, | |
} | |
} | |
/// Writes the tarbox header and then the wrapped content. | |
/// The header will look like the following: | |
/// | |
/// +--------------+--------+-------+-----+ | |
/// | TARBOX MAGIC | VERS | ATTRS | NUL | | |
/// +--------------+--------+-------+-----+ | |
/// | [u8; 2] | u8 | ?[u8] | u8 | | |
/// +--------------+--------+-------+-----+ | |
fn unwrap(self) -> Vec<u8> { | |
let mut final_buf = Vec::new(); | |
final_buf.extend_from_slice(&TARBOX_MAGIC); | |
// Push header version | |
let attrs_version = self.attributes.version(); | |
final_buf.push(attrs_version); | |
// Push attributes including version header | |
final_buf.extend(self.attributes.to_bytes().unwrap().iter()); | |
// Push the end of header byte | |
final_buf.push(0); | |
final_buf.extend(self.inner.into_iter()); | |
return final_buf; | |
} | |
} | |
impl<A> Write for Encoder<A> where A: attributes::AttributeContainer { | |
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
let bytes_len = buf.len(); | |
self.content_size += bytes_len; | |
self.inner.extend(buf); | |
Ok(bytes_len) | |
} | |
fn flush(&mut self) -> io::Result<()> { | |
Ok(()) | |
} | |
} | |
#[cfg(test)] | |
mod tests { | |
use std::io::Write; | |
use super::{ | |
attributes, | |
attributes::AttributeContainer, | |
Encoder, | |
}; | |
#[test] | |
fn test_encoder() { | |
let attrs = attributes::v1::AttributesV1::empty(); | |
let mut enc = Encoder::new(attrs); | |
let inner: [u8; 2] = [0xca, 0xfe]; | |
assert_eq!(2, enc.write(&inner).unwrap()); | |
let version = enc.attributes.version(); | |
let data = enc.unwrap(); | |
assert_eq!([0x7a, 0xb0, version, 0x0, 0x0, 0xca, 0xfe], data.as_slice()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment