// Huffman encoding is a compression technique that replaces common strings with shorter codes.
// Ugh I wish we didn't have to implement this, but the other endpoint is allowed to use it.
// Taken from https://github.com/hyperium/h3/blob/master/h3/src/qpack/prefix_string/decode.rs
// License: MIT
#[derive(Debug, Default, PartialEq, Clone)]
pub struct BitWindow {
pub byte: u32,
pub bit: u32,
pub count: u32,
}
impl BitWindow {
pub fn new() -> Self {
Self::default()
}
pub fn forwards(&mut self, step: u32) {
self.bit += self.count;
self.byte += self.bit / 8;
self.bit %= 8;
self.count = step;
}
pub fn opposite_bit_window(&self) -> BitWindow {
BitWindow {
byte: self.byte,
bit: self.bit,
count: 8 - (self.bit % 8),
}
}
}
use thiserror::Error;
#[derive(Error, Debug, PartialEq, Clone)]
pub enum Error {
#[error("missing bits: {0:?}")]
MissingBits(BitWindow),
#[error("unhandled: {0:?} {1:?}")]
Unhandled(BitWindow, usize),
}
#[derive(Clone, Debug)]
enum DecodeValue {
Partial(&'static HuffmanDecoder),
Sym(u8),
}
#[derive(Clone, Debug)]
struct HuffmanDecoder {
lookup: u32,
table: &'static [DecodeValue],
}
impl HuffmanDecoder {
fn check_eof(&self, bit_pos: &mut BitWindow, input: &[u8]) -> Result