chapter-tgz 0.1.0

Specially crafted .tar.gz with embedded chapter boundary information
Documentation
pub(crate) const fn prefix(bfinal: bool) -> [u8; 9] {
    [
        0b00000100 | bfinal as u8,
        0b11000000,
        0b00010001,
        0b00000001,
        0b00000000,
        0b00000000,
        0b00000000,
        0b00000000,
        0b00100000,
    ]
}

pub(crate) fn decode_from_end(bytes: &[u8]) -> Option<(usize, u64)> {
    let prefix = prefix(true);
    let mut start = bytes.len().checked_sub(13)?;
    while !bytes[start..].starts_with(&prefix) {
        start = start.checked_sub(1)?;
    }
    let payload = decode_rest(&bytes[start + prefix.len()..])?;
    Some((start, payload))
}

pub(crate) fn decode_from_start(bytes: &[u8]) -> Option<u64> {
    let prefix = prefix(false);
    if bytes.starts_with(&prefix) {
        decode_rest(&bytes[prefix.len()..])
    } else {
        None
    }
}

fn decode_rest(bytes: &[u8]) -> Option<u64> {
    let mut bitpos = 0;
    let mut take = |n: usize| -> u8 {
        let byte = (bytes.get(bitpos / 8).unwrap_or(&0) >> (bitpos % 8))
            | bytes
                .get(bitpos / 8 + 1)
                .unwrap_or(&0)
                .unbounded_shl((8 - bitpos % 8) as u32);
        bitpos += n;
        byte & 0b11111111u8.unbounded_shr((8 - n) as u32)
    };

    let mut payload = 0;
    let mut zeros = 0;
    for i in 0..22 {
        if i > 0 && take(1) != 0 {
            break;
        }
        let n = take(3);
        payload |= u64::from(n) << (i * 3);
        zeros += 3 + n as usize;
    }

    if (payload < 0x8000_0000_0000_0000 || take(1) == 1)
        && take(1) == 1
        && match zeros {
            4..=97 => {
                take(7) == 0b1111111
                    && take(2) == 0b11
                    && take(7) == (256 - (zeros + 138) - 11) as u8
            }
            98..=107 => {
                take(7) == (256 - (zeros + 20) - 11) as u8
                    && take(1) == 0
                    && take(3) == 0b111
                    && take(1) == 0
                    && take(3) == 0b111
            }
            108..=117 => {
                take(7) == (256 - (zeros + 10) - 11) as u8 && take(1) == 0 && take(3) == 0b111
            }
            118..=214 => take(7) == (256 - zeros - 11) as u8,
            0..=3 | 215.. => false,
        }
        && take(2) == 1
        && take(2) == 1
        && take(1) == 0
    {
        Some(payload)
    } else {
        None
    }
}