blobby-0.1.1/Cargo.toml.orig010064400017500001750000000006361335273402400141020ustar0000000000000000[package] name = "blobby" version = "0.1.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" description = "Iterator over simple binary blob storage" documentation = "https://docs.rs/blobby" repository = "https://github.com/RustCrypto/blobby" categories = ["no-std"] [dependencies] byteorder = { version = "1", default-features = false } [badges] travis-ci = { repository = "RustCrypto/utils" } blobby-0.1.1/Cargo.toml0000644000000016330000000000000103440ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g. crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "blobby" version = "0.1.1" authors = ["RustCrypto Developers"] description = "Iterator over simple binary blob storage" documentation = "https://docs.rs/blobby" categories = ["no-std"] license = "MIT OR Apache-2.0" repository = "https://github.com/RustCrypto/blobby" [dependencies.byteorder] version = "1" default-features = false [badges.travis-ci] repository = "RustCrypto/utils" blobby-0.1.1/src/lib.rs010064400017500001750000000120631335273547700131300ustar0000000000000000//! This crate provides several iterators over simply binary blob storage. //! //! # Storage format //! Data in the storage format starts with magical string "blobby', next is one //! byte which denotes how many bytes are used for blob length prefixes. For //! example "blobby1" means that 1 byte is used for length, and "blobby2", //! "blobby4", "blobby8" mean 2, 4 and 8 bytes respectively (this number will //! be denoted as `n`). //! //! After header goes a sequence of records. Each record starts with prefix of //! `n` bytes in which record length (excluding prefix) is stored using little //! endian format. //! //! # Examples //! First line represents input binary string and second line shows blobs stored //! in it. //! ```text //! "blobby1\x05hello\x01 \x00\x05world" //! "hello", " ", "", "world" //! ``` //! Example for `n=2`, note that length is given in little endian format: //! ```text //! "blobby2\x03\x00foo\x00\x00\x03\x00bar" //! "foo", "", "bar" //! ``` #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] #![no_std] extern crate byteorder; use byteorder::{LE, ByteOrder}; use core::iter::Iterator; /// Iterator over binary blobs pub struct BlobIterator<'a> { data: &'a [u8], size: IndexSize, } impl<'a> BlobIterator<'a> { /// Create a new `BlobIterator` for given `data`. pub fn new(data: &'a [u8]) -> Result { if data.len() < 7 { Err("data is too small")? } let (header, data) = data.split_at(7); let size = match header { b"blobby1" => IndexSize::N8, b"blobby2" => IndexSize::N16, b"blobby4" => IndexSize::N32, b"blobby8" => IndexSize::N64, _ => Err("invalid data header")?, }; Ok(BlobIterator { data, size }) } } impl<'a> Iterator for BlobIterator<'a> { type Item = &'a [u8]; fn next(&mut self) -> Option<&'a [u8]> { if self.data.len() == 0 { return None; } let (val, leftover) = self.size.read(self.data); self.data = leftover; Some(val) } } /// Iterator over binary blob pairs pub struct Blob2Iterator<'a> { inner: BlobIterator<'a>, } impl<'a> Blob2Iterator<'a> { /// Create a new `Blob2Iterator` for given `data`. pub fn new(data: &'a [u8]) -> Result { Ok(Self { inner: BlobIterator::new(data)? }) } } impl<'a> Iterator for Blob2Iterator<'a> { type Item = [&'a [u8]; 2]; fn next(&mut self) -> Option { let mut res = Self::Item::default(); for (i, v) in res.iter_mut().enumerate() { *v = match self.inner.next() { Some(val) => val, None if i == 0 => return None, None => panic!("failed to get 2 blobs, not enough elements."), }; } Some(res) } } /// Iterator over binary blob triples pub struct Blob3Iterator<'a> { inner: BlobIterator<'a>, } impl<'a> Blob3Iterator<'a> { /// Create a new `Blob3Iterator` for given `data`. pub fn new(data: &'a [u8]) -> Result { Ok(Self { inner: BlobIterator::new(data)? }) } } impl<'a> Iterator for Blob3Iterator<'a> { type Item = [&'a [u8]; 3]; fn next(&mut self) -> Option { let mut res = Self::Item::default(); for (i, v) in res.iter_mut().enumerate() { *v = match self.inner.next() { Some(val) => val, None if i == 0 => return None, None => panic!("failed to get 3 blobs, not enough elements."), }; } Some(res) } } /// Iterator over binary blob quadruples pub struct Blob4Iterator<'a> { inner: BlobIterator<'a>, } impl<'a> Blob4Iterator<'a> { /// Create a new `Blob4Iterator` for given `data`. pub fn new(data: &'a [u8]) -> Result { Ok(Self { inner: BlobIterator::new(data)? }) } } impl<'a> Iterator for Blob4Iterator<'a> { type Item = [&'a [u8]; 4]; fn next(&mut self) -> Option { let mut res = Self::Item::default(); for (i, v) in res.iter_mut().enumerate() { *v = match self.inner.next() { Some(val) => val, None if i == 0 => return None, None => panic!("failed to get 4 blobs, not enough elements."), }; } Some(res) } } #[derive(Copy, Clone)] enum IndexSize { N8, N16, N32, N64, } macro_rules! branch_read { ($data:ident, $n:expr, $method:ident) => {{ let (size, data) = $data.split_at($n); let n = LE::$method(size) as usize; data.split_at(n) }} } impl IndexSize { fn read<'a>(self, data: &'a [u8]) -> (&'a [u8], &'a [u8]) { match self { IndexSize::N8 => { let n = data[0] as usize; data[1..].split_at(n) }, IndexSize::N16 => branch_read!(data, 2, read_u16), IndexSize::N32 => branch_read!(data, 4, read_u32), IndexSize::N64 => branch_read!(data, 8, read_u64), } } } blobby-0.1.1/tests/mod.rs010064400017500001750000000047621335267643600135220ustar0000000000000000#![no_std] extern crate blobby; fn check(data: &[u8], result: &[&[u8]]) { let mut blob = blobby::BlobIterator::new(data).unwrap(); let mut res = result.iter(); loop { match (blob.next(), res.next()) { (Some(v1), Some(v2)) => assert_eq!(&v1, v2), (None, None) => break, _ => panic!("items number mismatch"), } } } #[test] fn test_single0() { let data = b"blobby1"; check(data, &[]); } #[test] fn test_single1() { let data = b"blobby1\x01a"; check(data, &[b"a"]); } #[test] fn test_single2() { let data = b"blobby1\x03abc\x00\x01a"; check(data, &[b"abc", b"", b"a"]); } #[test] fn test_single3() { let data = b"blobby2\x03\x00abc\x00\x00\x01\x00a"; check(data, &[b"abc", b"", b"a"]); } #[test] fn test_single4() { let data = b"blobby4\x03\x00\x00\x00abc\x00\x00\x00\x00\x01\x00\x00\x00a"; check(data, &[b"abc", b"", b"a"]); } #[test] fn test_single5() { let data = b"blobby8\ \x03\x00\x00\x00\x00\x00\x00\x00abc\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x01\x00\x00\x00\x00\x00\x00\x00a"; check(data, &[b"abc", b"", b"a"]); } #[test] fn test_double() { let data = b"blobby1\x03abc\x00\x01a\x02cd"; let result: &[[&[u8]; 2]] = &[[b"abc", b""], [b"a", b"cd"]]; let mut blob = blobby::Blob2Iterator::new(data).unwrap(); let mut res = result.iter(); loop { match (blob.next(), res.next()) { (Some(v1), Some(v2)) => assert_eq!(&v1, v2), (None, None) => break, _ => panic!("items number mismatch"), } } } #[test] fn test_triple() { let data = b"blobby1\x03abc\x00\x01a\x02cd\x03def\x00"; let result: &[[&[u8]; 3]] = &[[b"abc", b"", b"a"], [b"cd", b"def", b""]]; let mut blob = blobby::Blob3Iterator::new(data).unwrap(); let mut res = result.iter(); loop { match (blob.next(), res.next()) { (Some(v1), Some(v2)) => assert_eq!(&v1, v2), (None, None) => break, _ => panic!("items number mismatch"), } } } #[test] fn test_quadruple() { let data = b"blobby1\x03abc\x00\x01a\x02cd"; let result: &[[&[u8]; 4]] = &[[b"abc", b"", b"a", b"cd"]]; let mut blob = blobby::Blob4Iterator::new(data).unwrap(); let mut res = result.iter(); loop { match (blob.next(), res.next()) { (Some(v1), Some(v2)) => assert_eq!(&v1, v2), (None, None) => break, _ => panic!("items number mismatch"), } } } blobby-0.1.1/.cargo_vcs_info.json0000644000000001120000000000000123350ustar00{ "git": { "sha1": "7df0c688b31e0194c4d3e7a416eb4b7bf7b77980" } }