pub struct Iterate7BitChunks<'a> {
bytes: &'a [u8],
offset: usize,
remains: u64,
remains_bits: usize,
}
impl<'a> Iterate7BitChunks<'a> {
pub fn new(bytes: &'a [u8]) -> Self {
Self {
bytes,
offset: 0,
remains: 0,
remains_bits: 0,
}
}
}
impl Iterator for Iterate7BitChunks<'_> {
type Item = u8;
fn next(&mut self) -> Option<u8> {
if self.remains_bits > 7 {
let x = (self.remains >> (self.remains_bits - 7)) as u8 & 0x7f;
self.remains_bits -= 7;
Some((x << 1) | 1)
} else if self.offset < self.bytes.len() {
self.remains <<= 8;
self.remains |= self.bytes[self.offset] as u64;
self.offset += 1;
self.remains_bits += 8;
self.next()
} else if self.remains_bits > 0 {
assert!(self.remains_bits <= 7);
let mut x: u8 = self.remains as u8;
x <<= 8 - self.remains_bits;
self.remains_bits = 0;
Some(x)
} else {
None
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty() {
let mut iter = Iterate7BitChunks::new(&[]);
assert_eq!(None, iter.next());
}
#[test]
fn one_byte() {
let mut iter = Iterate7BitChunks::new(&[0]);
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[1]);
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b10000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[2]);
assert_eq!(Some(0b00000011), iter.next());
assert_eq!(Some(0b00000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[3]);
assert_eq!(Some(0b00000011), iter.next());
assert_eq!(Some(0b10000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[4]);
assert_eq!(Some(0b00000101), iter.next());
assert_eq!(Some(0b00000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[254]);
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b00000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[255]);
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b10000000), iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn two_bytes() {
let mut iter = Iterate7BitChunks::new(&[0, 0]);
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[255, 255]);
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11000000), iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn three_bytes() {
let mut iter = Iterate7BitChunks::new(&[0, 0, 0]);
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[255, 255, 255]);
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11100000), iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn four_bytes() {
let mut iter = Iterate7BitChunks::new(&[0, 0, 0, 0]);
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[255, 255, 255, 255]);
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11110000), iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn five_bytes() {
let mut iter = Iterate7BitChunks::new(&[0, 0, 0, 0, 0]);
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[255, 255, 255, 255, 255]);
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111000), iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn six_bytes() {
let mut iter = Iterate7BitChunks::new(&[0, 0, 0, 0, 0, 0]);
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[255, 255, 255, 255, 255, 255]);
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111100), iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn seven_bytes() {
let mut iter = Iterate7BitChunks::new(&[0, 0, 0, 0, 0, 0, 0]);
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[255, 255, 255, 255, 255, 255, 255]);
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111110), iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn eight_bytes() {
let mut iter = Iterate7BitChunks::new(&[0, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[255, 255, 255, 255, 255, 255, 255, 255]);
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b10000000), iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn nine_bytes() {
let mut iter = Iterate7BitChunks::new(&[0, 0, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000001), iter.next());
assert_eq!(Some(0b00000000), iter.next());
assert_eq!(None, iter.next());
let mut iter = Iterate7BitChunks::new(&[255, 255, 255, 255, 255, 255, 255, 255, 255]);
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11111111), iter.next());
assert_eq!(Some(0b11000000), iter.next());
assert_eq!(None, iter.next());
}
}