Skip to content

Instantly share code, notes, and snippets.

@Kroisse
Last active August 29, 2015 13:58
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 Kroisse/10347956 to your computer and use it in GitHub Desktop.
Save Kroisse/10347956 to your computer and use it in GitHub Desktop.
use std::{iter, slice};
use std::io::{IoResult, Writer};
pub struct BlockWriter {
blk_size: uint,
blks: Vec<Vec<u8>>,
}
struct Blocks<'a>(slice::Items<'a, Vec<u8>>);
impl<'a> iter::Iterator<&'a [u8]> for Blocks<'a> {
fn next(&mut self) -> Option<&'a [u8]> {
let Blocks(ref mut inner) = *self;
inner.next().map(|blk| blk.as_slice())
}
fn size_hint(&self) -> (uint, Option<uint>) {
let Blocks(ref inner) = *self;
inner.size_hint()
}
}
impl BlockWriter {
pub fn with_block_size(n: uint) -> BlockWriter {
BlockWriter {
blk_size: n,
blks: vec!(),
}
}
pub fn blocks<'a>(&'a self) -> Blocks<'a>{
Blocks(self.blks.iter())
}
}
impl Writer for BlockWriter {
fn write(&mut self, mut buf: &[u8]) -> IoResult<()> {
while !buf.is_empty() {
match self.blks.last().filtered(|blk| blk.capacity() > 0) {
Some(_) => {}
None => {
self.blks.push(Vec::with_capacity(self.blk_size));
}
}
let blk = self.blks.mut_last().unwrap();
let capacity = blk.capacity();
let (chunk, remained) = if buf.len() <= capacity {
(buf, &[])
} else {
(buf.slice_to(capacity), buf.slice_from(capacity))
};
blk.push_all(chunk);
buf = remained;
}
Ok(())
}
}
impl Container for BlockWriter {
fn len(&self) -> uint {
self.blks.iter().fold(0, |sum, blk| sum + blk.len())
}
fn is_empty(&self) -> bool {
self.blks.is_empty() || self.blks.get(0).is_empty()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment