Skip to content

Commit

Permalink
blobby update
Browse files Browse the repository at this point in the history
  • Loading branch information
newpavlov committed Aug 29, 2018
1 parent 852a3d3 commit 8eb9bfe
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 24 deletions.
49 changes: 32 additions & 17 deletions blobby/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,53 @@
extern crate byteorder;

use byteorder::{LE, ByteOrder};
use core::iter::Iterator;
use core::iter::{Iterator, FusedIterator, ExactSizeIterator};

pub struct BlobIterator<'a> {
index: &'a [u8],
data: &'a [u8],
n: usize,
cursor: usize,
pos: usize,
}

impl<'a> BlobIterator<'a> {
pub fn new(data: &'a [u8]) -> Self {
pub fn new(data: &'a [u8]) -> Result<Self, &'static str> {
let (magic, data) = data.split_at(6);
if magic != b"blobby" { Err("invalid data prefix")? }
let (len, data) = data.split_at(2);
let len = LE::read_u16(len) as usize;
let (index, data) = data.split_at(2*len);
let sum = index.chunks(2)
.map(|chunk| LE::read_u16(chunk) as usize)
.fold(0, |acc, x| acc + x);
assert!(sum <= data.len());
Self { index, data, n: 0, cursor: 0 }
let (index, data) = data.split_at(8*len);
for chunk in index.chunks(8) {
let start = LE::read_u32(&chunk[..4]) as usize;
let end = LE::read_u32(&chunk[4..]) as usize;
if start > end { Err("index: start is bigger than end")? }
if end > data.len() {
Err("index: end points outside of data index")?
}
}
Ok(Self { index, data, pos: 0 })
}
}

impl<'a> Iterator for BlobIterator<'a> {
type Item = &'a [u8];

fn next(&mut self) -> Option<&'a [u8]> {
let n = 2*self.n;
if n >= self.index.len() { return None; }
let len = LE::read_u16(&self.index[n..n + 2]) as usize;
let cursor = self.cursor;
self.cursor += len;
self.n += 1;
Some(&self.data[cursor..cursor + len])
if self.pos >= self.index.len()/8 { return None; }
let n = 8*self.pos;
let start = LE::read_u32(&self.index[n..n + 4]) as usize;
let end = LE::read_u32(&self.index[n + 4..n + 8]) as usize;
self.pos += 1;
Some(&self.data[start..end])
}

fn size_hint(&self) -> (usize, Option<usize>) {
let n = self.index.len()/8 - self.pos;
(n, Some(n))
}
}

impl<'a> FusedIterator for BlobIterator<'a> { }

impl<'a> ExactSizeIterator for BlobIterator<'a> {
fn len(&self) -> usize { self.index.len()/8 - self.pos }
}
14 changes: 7 additions & 7 deletions blobby/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
extern crate blobby;

fn check(data: &[u8], result: &[&[u8]]) {
let mut blob = blobby::BlobIterator::new(data);
let mut blob = blobby::BlobIterator::new(data).unwrap();
let mut res = result.iter();
loop {
match (blob.next(), res.next()) {
Expand All @@ -15,26 +15,26 @@ fn check(data: &[u8], result: &[&[u8]]) {

#[test]
fn empty() {
let data = b"\x00\x00";
let data = b"blobby\x00\x00";
check(data, &[]);
}

#[test]
fn single() {
let data = b"\
let data = b"blobby\
\x01\x00\
\x0A\x00\
\x00\x00\x00\x00\x0A\x00\x00\x00\
0123456789\
";
check(data, &[b"0123456789"]);
}

#[test]
fn double() {
let data = b"\
let data = b"blobby\
\x02\x00\
\x0A\x00\
\x03\x00\
\x00\x00\x00\x00\x0A\x00\x00\x00\
\x0A\x00\x00\x00\x0D\x00\x00\x00\
0123456789\
abc\
";
Expand Down

0 comments on commit 8eb9bfe

Please sign in to comment.