Skip to content

Instantly share code, notes, and snippets.

@pirogoeth
Created August 8, 2018 18:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pirogoeth/4818d14b5772194a930aba4869b7435a to your computer and use it in GitHub Desktop.
Save pirogoeth/4818d14b5772194a930aba4869b7435a to your computer and use it in GitHub Desktop.
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