#[derive(Clone, Default)]
enum State {
#[default]
Empty,
Top6,
Bottom2Top4,
Top2Bottom4,
}
impl State {
#[inline]
fn advance(&self) -> Self {
match self {
Self::Empty => Self::Top6,
Self::Top6 => Self::Bottom2Top4,
Self::Bottom2Top4 => Self::Top2Bottom4,
Self::Top2Bottom4 => Self::Empty,
}
}
}
#[derive(Clone, Default)]
pub(crate) struct SixBitDecoder {
state: State,
partial: u8,
}
impl SixBitDecoder {
pub(crate) fn new() -> Self {
Self {
state: Default::default(),
partial: 0,
}
}
pub(crate) fn next(&mut self, byte: u8) -> Option<u8> {
let byte = byte & 0x3F;
let out: u8;
self.state = self.state.advance();
match self.state {
State::Top6 => {
self.partial = byte << 2;
return None;
}
State::Bottom2Top4 => {
out = self.partial | (byte >> 4);
self.partial = (byte & 0x0F) << 4;
}
State::Top2Bottom4 => {
out = self.partial | (byte >> 2);
self.partial = (byte & 0x03) << 6;
}
State::Empty => {
out = self.partial | byte;
}
}
Some(out)
}
}
#[cfg(test)]
mod test {
use super::SixBitDecoder;
#[test]
fn decoder() {
let mut decoder = SixBitDecoder::new();
assert_eq!(decoder.next(0xFF), None);
assert_eq!(decoder.next(0xFF), Some(0xFFu8));
assert_eq!(decoder.next(0xFF), Some(0xFFu8));
assert_eq!(decoder.next(0xFF), Some(0xFFu8));
assert_eq!(decoder.next(0xFF), None);
let mut decoder = SixBitDecoder::new();
assert_eq!(decoder.next(0b11_000000), None);
assert_eq!(decoder.next(0b11_000000), Some(0));
let mut decoder = SixBitDecoder::new();
assert_eq!(decoder.next(0b11_101010), None);
assert_eq!(decoder.next(0b11_100101), Some(0b10101010));
assert_eq!(decoder.next(0b11_010100), Some(0b01010101));
assert_eq!(decoder.next(0b11_000001), Some(0b00000001));
assert_eq!(decoder.next(0b11_101010), None);
let mut decoder = SixBitDecoder::new();
assert_eq!(decoder.next(0x03), None);
assert_eq!(decoder.next(0x36), Some(0xf));
assert_eq!(decoder.next(0x09), Some(0x62));
assert_eq!(decoder.next(0x29), Some(0x69));
assert_eq!(decoder.next(0x1b), None);
assert_eq!(decoder.next(0x26), Some(0x6e));
}
}