use bytes::BufMut;
#[derive(Debug, PartialEq)]
pub enum Error {
EncodedLengthOverflow,
}
pub(super) fn encoded_len(value: &[u8]) -> Result<usize, Error> {
let mut encoded_len = 0usize;
let mut pending_bits = 0usize;
for chunk in value.chunks(64) {
let bit_count = pending_bits
+ chunk
.iter()
.map(|code| usize::from(ENCODE_CODE_LENGTHS[usize::from(*code)]))
.sum::<usize>();
encoded_len = encoded_len
.checked_add(bit_count / 8)
.ok_or(Error::EncodedLengthOverflow)?;
pending_bits = bit_count % 8;
}
if pending_bits != 0 {
encoded_len = encoded_len
.checked_add(1)
.ok_or(Error::EncodedLengthOverflow)?;
}
Ok(encoded_len)
}
pub(super) fn encode_into<B: BufMut>(value: &[u8], buf: &mut B) {
let mut pending = 0u64;
let mut pending_bits = 0usize;
for code in value {
let index = usize::from(*code);
let bit_count = usize::from(ENCODE_CODE_LENGTHS[index]);
pending = (pending << bit_count) | u64::from(ENCODE_CODES[index]);
pending_bits += bit_count;
if pending_bits >= 32 {
let trailing_bits = pending_bits - 32;
buf.put_u32((pending >> trailing_bits) as u32);
pending = if trailing_bits == 0 {
0
} else {
pending & ((1u64 << trailing_bits) - 1)
};
pending_bits = trailing_bits;
}
}
if pending_bits != 0 {
let padding = (8 - (pending_bits % 8)) % 8;
pending = (pending << padding) | ((1u64 << padding) - 1);
pending_bits += padding;
while pending_bits != 0 {
pending_bits -= 8;
buf.put_u8((pending >> pending_bits) as u8);
}
}
}
macro_rules! define_encode_tables {
[ $( ( $len:expr => [ $( $byte:expr ),* ] ), )* ] => {
pub(super) const ENCODE_CODES: [u32; 256] = [ $(
pack_code($len, &[ $( $byte as u8 ),* ]),
)* ];
pub(super) const ENCODE_CODE_LENGTHS: [u8; 256] = [ $( $len, )* ];
}
}
const fn pack_code(bit_count: usize, parts: &[u8]) -> u32 {
let mut bits = 0u32;
let mut remaining = bit_count;
let mut index = 0;
while index < parts.len() {
let part_bits = if remaining < 8 { remaining } else { 8 };
let mask = if part_bits == 8 {
u8::MAX
} else {
(1u8 << part_bits) - 1
};
bits = (bits << part_bits) | (parts[index] & mask) as u32;
remaining -= part_bits;
index += 1;
}
bits
}
define_encode_tables![
( 13 => [0b1111_1111, 0b0001_1000]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0101_1000]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_0010]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_0011]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_0100]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_0101]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_0110]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_0111]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_1000]),
( 24 => [0b1111_1111, 0b1111_1111, 0b1110_1010]),
( 30 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0011_1100]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_1001]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_1010]),
( 30 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0011_1101]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_1011]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_1100]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_1101]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_1110]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_1111]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_0000]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_0001]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_0010]),
( 30 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0011_1110]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_0011]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_0100]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_0101]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_0110]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_0111]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_1000]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_1001]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_1010]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_1011]),
( 6 => [0b0001_0100]),
( 10 => [0b1111_1110, 0b0000_0000]), ( 10 => [0b1111_1110, 0b0000_0001]), ( 12 => [0b1111_1111, 0b0000_1010]), ( 13 => [0b1111_1111, 0b0001_1001]), ( 6 => [0b0001_0101]), ( 8 => [0b1111_1000]), ( 11 => [0b1111_1111, 0b0000_0010]), ( 10 => [0b1111_1110, 0b0000_0010]), ( 10 => [0b1111_1110, 0b0000_0011]), ( 8 => [0b1111_1001]), ( 11 => [0b1111_1111, 0b0000_0011]), ( 8 => [0b1111_1010]), ( 6 => [0b0001_0110]), ( 6 => [0b0001_0111]), ( 6 => [0b0001_1000]), ( 5 => [0b0000_0000]), ( 5 => [0b0000_0001]), ( 5 => [0b0000_0010]), ( 6 => [0b0001_1001]), ( 6 => [0b0001_1010]), ( 6 => [0b0001_1011]), ( 6 => [0b0001_1100]), ( 6 => [0b0001_1101]), ( 6 => [0b0001_1110]), ( 6 => [0b0001_1111]), ( 7 => [0b0101_1100]), ( 8 => [0b1111_1011]),
( 15 => [0b1111_1111, 0b0111_1100]), ( 6 => [0b0010_0000]), ( 12 => [0b1111_1111, 0b0000_1011]), ( 10 => [0b1111_1111, 0b0000_0000]), ( 13 => [0b1111_1111, 0b0001_1010]), ( 6 => [0b0010_0001]), ( 7 => [0b0101_1101]), ( 7 => [0b0101_1110]), ( 7 => [0b0101_1111]), ( 7 => [0b0110_0000]), ( 7 => [0b0110_0001]), ( 7 => [0b0110_0010]), ( 7 => [0b0110_0011]), ( 7 => [0b0110_0100]), ( 7 => [0b0110_0101]), ( 7 => [0b0110_0110]), ( 7 => [0b0110_0111]), ( 7 => [0b0110_1000]), ( 7 => [0b0110_1001]), ( 7 => [0b0110_1010]), ( 7 => [0b0110_1011]), ( 7 => [0b0110_1100]), ( 7 => [0b0110_1101]), ( 7 => [0b0110_1110]), ( 7 => [0b0110_1111]), ( 7 => [0b0111_0000]), ( 7 => [0b0111_0001]), ( 7 => [0b0111_0010]), ( 8 => [0b1111_1100]), ( 7 => [0b0111_0011]), ( 8 => [0b1111_1101]), ( 13 => [0b1111_1111, 0b0001_1011]), ( 19 => [0b1111_1111, 0b1111_1110, 0b0000_0000]), ( 13 => [0b1111_1111, 0b0001_1100]), ( 14 => [0b1111_1111, 0b0011_1100]), ( 6 => [0b0010_0010]), ( 15 => [0b1111_1111, 0b0111_1101]), ( 5 => [0b0000_0011]), ( 6 => [0b0010_0011]), ( 5 => [0b0000_0100]), ( 6 => [0b0010_0100]), ( 5 => [0b0000_0101]), ( 6 => [0b0010_0101]), ( 6 => [0b0010_0110]), ( 6 => [0b0010_0111]), ( 5 => [0b0000_0110]), ( 7 => [0b0111_0100]), ( 7 => [0b0111_0101]), ( 6 => [0b0010_1000]), ( 6 => [0b0010_1001]), ( 6 => [0b0010_1010]), ( 5 => [0b0000_0111]), ( 6 => [0b0010_1011]), ( 7 => [0b0111_0110]), ( 6 => [0b0010_1100]), ( 5 => [0b0000_1000]), ( 5 => [0b0000_1001]), ( 6 => [0b0010_1101]), ( 7 => [0b0111_0111]), ( 7 => [0b0111_1000]), ( 7 => [0b0111_1001]), ( 7 => [0b0111_1010]), ( 7 => [0b0111_1011]), ( 15 => [0b1111_1111, 0b0111_1110]), ( 11 => [0b1111_1111, 0b0000_0100]), ( 14 => [0b1111_1111, 0b0011_1101]), ( 13 => [0b1111_1111, 0b0001_1101]), ( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_1100]),
( 20 => [0b1111_1111, 0b1111_1110, 0b0000_0110]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_0010]),
( 20 => [0b1111_1111, 0b1111_1110, 0b0000_0111]),
( 20 => [0b1111_1111, 0b1111_1110, 0b0000_1000]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_0011]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_0100]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_0101]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0101_1001]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_0110]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0101_1010]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0101_1011]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0101_1100]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0101_1101]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0101_1110]),
( 24 => [0b1111_1111, 0b1111_1111, 0b1110_1011]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0101_1111]),
( 24 => [0b1111_1111, 0b1111_1111, 0b1110_1100]),
( 24 => [0b1111_1111, 0b1111_1111, 0b1110_1101]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_0111]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_0000]),
( 24 => [0b1111_1111, 0b1111_1111, 0b1110_1110]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_0001]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_0010]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_0011]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_0100]),
( 21 => [0b1111_1111, 0b1111_1110, 0b0001_1100]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_1000]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_0101]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_1001]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_0110]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_0111]),
( 24 => [0b1111_1111, 0b1111_1111, 0b1110_1111]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_1010]),
( 21 => [0b1111_1111, 0b1111_1110, 0b0001_1101]),
( 20 => [0b1111_1111, 0b1111_1110, 0b0000_1001]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_1011]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_1100]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_1000]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_1001]),
( 21 => [0b1111_1111, 0b1111_1110, 0b0001_1110]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_1010]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_1101]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_1110]),
( 24 => [0b1111_1111, 0b1111_1111, 0b1111_0000]),
( 21 => [0b1111_1111, 0b1111_1110, 0b0001_1111]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0001_1111]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_1011]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_1100]),
( 21 => [0b1111_1111, 0b1111_1111, 0b0000_0000]),
( 21 => [0b1111_1111, 0b1111_1111, 0b0000_0001]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0010_0000]),
( 21 => [0b1111_1111, 0b1111_1111, 0b0000_0010]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_1101]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0010_0001]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_1110]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0110_1111]),
( 20 => [0b1111_1111, 0b1111_1110, 0b0000_1010]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0010_0010]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0010_0011]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0010_0100]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0111_0000]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0010_0101]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0010_0110]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0111_0001]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1000, 0b0000_0000]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1000, 0b0000_0001]),
( 20 => [0b1111_1111, 0b1111_1110, 0b0000_1011]),
( 19 => [0b1111_1111, 0b1111_1110, 0b0000_0001]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0010_0111]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0111_0010]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0010_1000]),
( 25 => [0b1111_1111, 0b1111_1111, 0b1111_0110, 0b0000_0000]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1000, 0b0000_0010]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1000, 0b0000_0011]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1001, 0b0000_0000]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1011, 0b0000_0110]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1011, 0b0000_0111]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1001, 0b0000_0001]),
( 24 => [0b1111_1111, 0b1111_1111, 0b1111_0001]),
( 25 => [0b1111_1111, 0b1111_1111, 0b1111_0110, 0b0000_0001]),
( 19 => [0b1111_1111, 0b1111_1110, 0b0000_0010]),
( 21 => [0b1111_1111, 0b1111_1111, 0b0000_0011]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1001, 0b0000_0010]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1100, 0b0000_0000]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1100, 0b0000_0001]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1001, 0b0000_0011]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1100, 0b0000_0010]),
( 24 => [0b1111_1111, 0b1111_1111, 0b1111_0010]),
( 21 => [0b1111_1111, 0b1111_1111, 0b0000_0100]),
( 21 => [0b1111_1111, 0b1111_1111, 0b0000_0101]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1010, 0b0000_0000]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1010, 0b0000_0001]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_1101]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1100, 0b0000_0011]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1100, 0b0000_0100]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1100, 0b0000_0101]),
( 20 => [0b1111_1111, 0b1111_1110, 0b0000_1100]),
( 24 => [0b1111_1111, 0b1111_1111, 0b1111_0011]),
( 20 => [0b1111_1111, 0b1111_1110, 0b0000_1101]),
( 21 => [0b1111_1111, 0b1111_1111, 0b0000_0110]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0010_1001]),
( 21 => [0b1111_1111, 0b1111_1111, 0b0000_0111]),
( 21 => [0b1111_1111, 0b1111_1111, 0b0000_1000]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0111_0011]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0010_1010]),
( 22 => [0b1111_1111, 0b1111_1111, 0b0010_1011]),
( 25 => [0b1111_1111, 0b1111_1111, 0b1111_0111, 0b0000_0000]),
( 25 => [0b1111_1111, 0b1111_1111, 0b1111_0111, 0b0000_0001]),
( 24 => [0b1111_1111, 0b1111_1111, 0b1111_0100]),
( 24 => [0b1111_1111, 0b1111_1111, 0b1111_0101]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1010, 0b0000_0010]),
( 23 => [0b1111_1111, 0b1111_1111, 0b0111_0100]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1010, 0b0000_0011]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1100, 0b0000_0110]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1011, 0b0000_0000]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1011, 0b0000_0001]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1100, 0b0000_0111]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1101, 0b0000_0000]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1101, 0b0000_0001]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1101, 0b0000_0010]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1101, 0b0000_0011]),
( 28 => [0b1111_1111, 0b1111_1111, 0b1111_1111, 0b0000_1110]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1101, 0b0000_0100]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1101, 0b0000_0101]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1101, 0b0000_0110]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1101, 0b0000_0111]),
( 27 => [0b1111_1111, 0b1111_1111, 0b1111_1110, 0b0000_0000]),
( 26 => [0b1111_1111, 0b1111_1111, 0b1111_1011, 0b0000_0010]),
];
#[cfg(test)]
pub trait HpackStringEncode {
fn hpack_encode(&self) -> Result<Vec<u8>, Error>;
}
#[cfg(test)]
impl HpackStringEncode for Vec<u8> {
fn hpack_encode(&self) -> Result<Vec<u8>, Error> {
self.as_slice().hpack_encode()
}
}
#[cfg(test)]
impl HpackStringEncode for [u8] {
fn hpack_encode(&self) -> Result<Vec<u8>, Error> {
let mut encoded = Vec::with_capacity(encoded_len(self)?);
encode_into(self, &mut encoded);
Ok(encoded)
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::identity_op)]
use super::*;
macro_rules! encoding {
[ $( $code:expr => $( $byte:expr ),* ; )* ] => { $( {
let bytes = vec![$( $byte ),*];
let res = vec![ $code ].hpack_encode();
assert_eq!(res, Ok(bytes), "fail to encode {}", $code);
} )* }
}
/**
* https://tools.ietf.org/html/rfc7541
* Appendix B. Huffman Code
*/
#[test]
#[allow(clippy::cognitive_complexity)]
fn test_encode_single_value() {
encoding![
48 => (0b0000_0000 << 3) | /* padding */ 0b0000_0111; // '0'
49 => (0b0000_0001 << 3) | /* padding */ 0b0000_0111; // '1'
50 => (0b0000_0010 << 3) | /* padding */ 0b0000_0111; // '2'
97 => (0b0000_0011 << 3) | /* padding */ 0b0000_0111; // 'a'
99 => (0b0000_0100 << 3) | /* padding */ 0b0000_0111; // 'c'
101 => (0b0000_0101 << 3) | /* padding */ 0b0000_0111; // 'e'
105 => (0b0000_0110 << 3) | /* padding */ 0b0000_0111; // 'i'
111 => (0b0000_0111 << 3) | /* padding */ 0b0000_0111; // 'o'
115 => (0b0000_1000 << 3) | /* padding */ 0b0000_0111; // 's'
116 => (0b0000_1001 << 3) | /* padding */ 0b0000_0111; // 't'
32 => (0b0001_0100 << 2) | /* padding */ 0b0000_0011;
37 => (0b0001_0101 << 2) | /* padding */ 0b0000_0011; // '%'
45 => (0b0001_0110 << 2) | /* padding */ 0b0000_0011; // '-'
46 => (0b0001_0111 << 2) | /* padding */ 0b0000_0011; // '.'
47 => (0b0001_1000 << 2) | /* padding */ 0b0000_0011; // '/'
51 => (0b0001_1001 << 2) | /* padding */ 0b0000_0011; // '3'
52 => (0b0001_1010 << 2) | /* padding */ 0b0000_0011; // '4'
53 => (0b0001_1011 << 2) | /* padding */ 0b0000_0011; // '5'
54 => (0b0001_1100 << 2) | /* padding */ 0b0000_0011; // '6'
55 => (0b0001_1101 << 2) | /* padding */ 0b0000_0011; // '7'
56 => (0b0001_1110 << 2) | /* padding */ 0b0000_0011; // '8'
57 => (0b0001_1111 << 2) | /* padding */ 0b0000_0011; // '9'
61 => (0b0010_0000 << 2) | /* padding */ 0b0000_0011; // '='
65 => (0b0010_0001 << 2) | /* padding */ 0b0000_0011; // 'A'
95 => (0b0010_0010 << 2) | /* padding */ 0b0000_0011; // '_'
98 => (0b0010_0011 << 2) | /* padding */ 0b0000_0011; // 'b'
100 => (0b0010_0100 << 2) | /* padding */ 0b0000_0011; // 'd'
102 => (0b0010_0101 << 2) | /* padding */ 0b0000_0011; // 'f'
103 => (0b0010_0110 << 2) | /* padding */ 0b0000_0011; // 'g'
104 => (0b0010_0111 << 2) | /* padding */ 0b0000_0011; // 'h'
108 => (0b0010_1000 << 2) | /* padding */ 0b0000_0011; // 'l'
109 => (0b0010_1001 << 2) | /* padding */ 0b0000_0011; // 'm'
110 => (0b0010_1010 << 2) | /* padding */ 0b0000_0011; // 'n'
112 => (0b0010_1011 << 2) | /* padding */ 0b0000_0011; // 'p'
114 => (0b0010_1100 << 2) | /* padding */ 0b0000_0011; // 'r'
117 => (0b0010_1101 << 2) | /* padding */ 0b0000_0011; // 'u'
58 => (0b0101_1100 << 1) | /* padding */ 0b0000_0001; // ':'
66 => (0b0101_1101 << 1) | /* padding */ 0b0000_0001; // 'B'
67 => (0b0101_1110 << 1) | /* padding */ 0b0000_0001; // 'C'
68 => (0b0101_1111 << 1) | /* padding */ 0b0000_0001; // 'D'
69 => (0b0110_0000 << 1) | /* padding */ 0b0000_0001; // 'E'
70 => (0b0110_0001 << 1) | /* padding */ 0b0000_0001; // 'F'
71 => (0b0110_0010 << 1) | /* padding */ 0b0000_0001; // 'G'
72 => (0b0110_0011 << 1) | /* padding */ 0b0000_0001; // 'H'
73 => (0b0110_0100 << 1) | /* padding */ 0b0000_0001; // 'I'
74 => (0b0110_0101 << 1) | /* padding */ 0b0000_0001; // 'J'
75 => (0b0110_0110 << 1) | /* padding */ 0b0000_0001; // 'K'
76 => (0b0110_0111 << 1) | /* padding */ 0b0000_0001; // 'L'
77 => (0b0110_1000 << 1) | /* padding */ 0b0000_0001; // 'M'
78 => (0b0110_1001 << 1) | /* padding */ 0b0000_0001; // 'N'
79 => (0b0110_1010 << 1) | /* padding */ 0b0000_0001; // 'O'
80 => (0b0110_1011 << 1) | /* padding */ 0b0000_0001; // 'P'
81 => (0b0110_1100 << 1) | /* padding */ 0b0000_0001; // 'Q'
82 => (0b0110_1101 << 1) | /* padding */ 0b0000_0001; // 'R'
83 => (0b0110_1110 << 1) | /* padding */ 0b0000_0001; // 'S'
84 => (0b0110_1111 << 1) | /* padding */ 0b0000_0001; // 'T'
85 => (0b0111_0000 << 1) | /* padding */ 0b0000_0001; // 'U'
86 => (0b0111_0001 << 1) | /* padding */ 0b0000_0001; // 'V'
87 => (0b0111_0010 << 1) | /* padding */ 0b0000_0001; // 'W'
89 => (0b0111_0011 << 1) | /* padding */ 0b0000_0001; // 'Y'
106 => (0b0111_0100 << 1) | /* padding */ 0b0000_0001; // 'j'
107 => (0b0111_0101 << 1) | /* padding */ 0b0000_0001; // 'k'
113 => (0b0111_0110 << 1) | /* padding */ 0b0000_0001; // 'q'
118 => (0b0111_0111 << 1) | /* padding */ 0b0000_0001; // 'v'
119 => (0b0111_1000 << 1) | /* padding */ 0b0000_0001; // 'w'
120 => (0b0111_1001 << 1) | /* padding */ 0b0000_0001; // 'x'
121 => (0b0111_1010 << 1) | /* padding */ 0b0000_0001; // 'y'
122 => (0b0111_1011 << 1) | /* padding */ 0b0000_0001; // 'z'
38 => 0b1111_1000; // '&'
42 => 0b1111_1001; // '*'
44 => 0b1111_1010; // ','
59 => 0b1111_1011;
88 => 0b1111_1100; // 'X'
90 => 0b1111_1101; // 'Z'
33 => 0b1111_1110, (0b0000_0000 << 6) | /* padding */ 0b0011_1111; // '!'
34 => 0b1111_1110, (0b0000_0001 << 6) | /* padding */ 0b0011_1111; // '"'
40 => 0b1111_1110, (0b0000_0010 << 6) | 0b0011_1111; 41 => 0b1111_1110, (0b0000_0011 << 6) | 0b0011_1111; 63 => 0b1111_1111, (0b0000_0000 << 6) | 0b0011_1111; 39 => 0b1111_1111, (0b0000_0010 << 5) | 0b0001_1111; 43 => 0b1111_1111, (0b0000_0011 << 5) | 0b0001_1111; 124 => 0b1111_1111, (0b0000_0100 << 5) | 0b0001_1111; 35 => 0b1111_1111, (0b0000_1010 << 4) | 0b0000_1111; 62 => 0b1111_1111, (0b0000_1011 << 4) | 0b0000_1111; 0 => 0b1111_1111, (0b0001_1000 << 3) | 0b0000_0111;
36 => 0b1111_1111, (0b0001_1001 << 3) | 0b0000_0111; 64 => 0b1111_1111, (0b0001_1010 << 3) | 0b0000_0111; 91 => 0b1111_1111, (0b0001_1011 << 3) | 0b0000_0111; 93 => 0b1111_1111, (0b0001_1100 << 3) | 0b0000_0111; 126 => 0b1111_1111, (0b0001_1101 << 3) | 0b0000_0111; 94 => 0b1111_1111, (0b0011_1100 << 2) | 0b0000_0011; 125 => 0b1111_1111, (0b0011_1101 << 2) | 0b0000_0011; 60 => 0b1111_1111, (0b0111_1100 << 1) | 0b0000_0001; 96 => 0b1111_1111, (0b0111_1101 << 1) | 0b0000_0001; 123 => 0b1111_1111, (0b0111_1110 << 1) | 0b0000_0001; 92 => 0b1111_1111, 0b1111_1110, (0b0000_0000 << 5) | 0b0001_1111; 195 => 0b1111_1111, 0b1111_1110, (0b0000_0001 << 5) | 0b0001_1111;
208 => 0b1111_1111, 0b1111_1110, (0b0000_0010 << 5) | 0b0001_1111;
128 => 0b1111_1111, 0b1111_1110, (0b0000_0110 << 4) | 0b0000_1111;
130 => 0b1111_1111, 0b1111_1110, (0b0000_0111 << 4) | 0b0000_1111;
131 => 0b1111_1111, 0b1111_1110, (0b0000_1000 << 4) | 0b0000_1111;
162 => 0b1111_1111, 0b1111_1110, (0b0000_1001 << 4) | 0b0000_1111;
184 => 0b1111_1111, 0b1111_1110, (0b0000_1010 << 4) | 0b0000_1111;
194 => 0b1111_1111, 0b1111_1110, (0b0000_1011 << 4) | 0b0000_1111;
224 => 0b1111_1111, 0b1111_1110, (0b0000_1100 << 4) | 0b0000_1111;
226 => 0b1111_1111, 0b1111_1110, (0b0000_1101 << 4) | 0b0000_1111;
153 => 0b1111_1111, 0b1111_1110, (0b0001_1100 << 3) | 0b0000_0111;
161 => 0b1111_1111, 0b1111_1110, (0b0001_1101 << 3) | 0b0000_0111;
167 => 0b1111_1111, 0b1111_1110, (0b0001_1110 << 3) | 0b0000_0111;
172 => 0b1111_1111, 0b1111_1110, (0b0001_1111 << 3) | 0b0000_0111;
176 => 0b1111_1111, 0b1111_1111, (0b0000_0000 << 3) | 0b0000_0111;
177 => 0b1111_1111, 0b1111_1111, (0b0000_0001 << 3) | 0b0000_0111;
179 => 0b1111_1111, 0b1111_1111, (0b0000_0010 << 3) | 0b0000_0111;
209 => 0b1111_1111, 0b1111_1111, (0b0000_0011 << 3) | 0b0000_0111;
216 => 0b1111_1111, 0b1111_1111, (0b0000_0100 << 3) | 0b0000_0111;
217 => 0b1111_1111, 0b1111_1111, (0b0000_0101 << 3) | 0b0000_0111;
227 => 0b1111_1111, 0b1111_1111, (0b0000_0110 << 3) | 0b0000_0111;
229 => 0b1111_1111, 0b1111_1111, (0b0000_0111 << 3) | 0b0000_0111;
230 => 0b1111_1111, 0b1111_1111, (0b0000_1000 << 3) | 0b0000_0111;
129 => 0b1111_1111, 0b1111_1111, (0b0001_0010 << 2) | 0b0000_0011;
132 => 0b1111_1111, 0b1111_1111, (0b0001_0011 << 2) | 0b0000_0011;
133 => 0b1111_1111, 0b1111_1111, (0b0001_0100 << 2) | 0b0000_0011;
134 => 0b1111_1111, 0b1111_1111, (0b0001_0101 << 2) | 0b0000_0011;
136 => 0b1111_1111, 0b1111_1111, (0b0001_0110 << 2) | 0b0000_0011;
146 => 0b1111_1111, 0b1111_1111, (0b0001_0111 << 2) | 0b0000_0011;
154 => 0b1111_1111, 0b1111_1111, (0b0001_1000 << 2) | 0b0000_0011;
156 => 0b1111_1111, 0b1111_1111, (0b0001_1001 << 2) | 0b0000_0011;
160 => 0b1111_1111, 0b1111_1111, (0b0001_1010 << 2) | 0b0000_0011;
163 => 0b1111_1111, 0b1111_1111, (0b0001_1011 << 2) | 0b0000_0011;
164 => 0b1111_1111, 0b1111_1111, (0b0001_1100 << 2) | 0b0000_0011;
169 => 0b1111_1111, 0b1111_1111, (0b0001_1101 << 2) | 0b0000_0011;
170 => 0b1111_1111, 0b1111_1111, (0b0001_1110 << 2) | 0b0000_0011;
173 => 0b1111_1111, 0b1111_1111, (0b0001_1111 << 2) | 0b0000_0011;
178 => 0b1111_1111, 0b1111_1111, (0b0010_0000 << 2) | 0b0000_0011;
181 => 0b1111_1111, 0b1111_1111, (0b0010_0001 << 2) | 0b0000_0011;
185 => 0b1111_1111, 0b1111_1111, (0b0010_0010 << 2) | 0b0000_0011;
186 => 0b1111_1111, 0b1111_1111, (0b0010_0011 << 2) | 0b0000_0011;
187 => 0b1111_1111, 0b1111_1111, (0b0010_0100 << 2) | 0b0000_0011;
189 => 0b1111_1111, 0b1111_1111, (0b0010_0101 << 2) | 0b0000_0011;
190 => 0b1111_1111, 0b1111_1111, (0b0010_0110 << 2) | 0b0000_0011;
196 => 0b1111_1111, 0b1111_1111, (0b0010_0111 << 2) | 0b0000_0011;
198 => 0b1111_1111, 0b1111_1111, (0b0010_1000 << 2) | 0b0000_0011;
228 => 0b1111_1111, 0b1111_1111, (0b0010_1001 << 2) | 0b0000_0011;
232 => 0b1111_1111, 0b1111_1111, (0b0010_1010 << 2) | 0b0000_0011;
233 => 0b1111_1111, 0b1111_1111, (0b0010_1011 << 2) | 0b0000_0011;
1 => 0b1111_1111, 0b1111_1111, (0b0101_1000 << 1) | 0b0000_0001;
135 => 0b1111_1111, 0b1111_1111, (0b0101_1001 << 1) | 0b0000_0001;
137 => 0b1111_1111, 0b1111_1111, (0b0101_1010 << 1) | 0b0000_0001;
138 => 0b1111_1111, 0b1111_1111, (0b0101_1011 << 1) | 0b0000_0001;
139 => 0b1111_1111, 0b1111_1111, (0b0101_1100 << 1) | 0b0000_0001;
140 => 0b1111_1111, 0b1111_1111, (0b0101_1101 << 1) | 0b0000_0001;
141 => 0b1111_1111, 0b1111_1111, (0b0101_1110 << 1) | 0b0000_0001;
143 => 0b1111_1111, 0b1111_1111, (0b0101_1111 << 1) | 0b0000_0001;
147 => 0b1111_1111, 0b1111_1111, (0b0110_0000 << 1) | 0b0000_0001;
149 => 0b1111_1111, 0b1111_1111, (0b0110_0001 << 1) | 0b0000_0001;
150 => 0b1111_1111, 0b1111_1111, (0b0110_0010 << 1) | 0b0000_0001;
151 => 0b1111_1111, 0b1111_1111, (0b0110_0011 << 1) | 0b0000_0001;
152 => 0b1111_1111, 0b1111_1111, (0b0110_0100 << 1) | 0b0000_0001;
155 => 0b1111_1111, 0b1111_1111, (0b0110_0101 << 1) | 0b0000_0001;
157 => 0b1111_1111, 0b1111_1111, (0b0110_0110 << 1) | 0b0000_0001;
158 => 0b1111_1111, 0b1111_1111, (0b0110_0111 << 1) | 0b0000_0001;
165 => 0b1111_1111, 0b1111_1111, (0b0110_1000 << 1) | 0b0000_0001;
166 => 0b1111_1111, 0b1111_1111, (0b0110_1001 << 1) | 0b0000_0001;
168 => 0b1111_1111, 0b1111_1111, (0b0110_1010 << 1) | 0b0000_0001;
174 => 0b1111_1111, 0b1111_1111, (0b0110_1011 << 1) | 0b0000_0001;
175 => 0b1111_1111, 0b1111_1111, (0b0110_1100 << 1) | 0b0000_0001;
180 => 0b1111_1111, 0b1111_1111, (0b0110_1101 << 1) | 0b0000_0001;
182 => 0b1111_1111, 0b1111_1111, (0b0110_1110 << 1) | 0b0000_0001;
183 => 0b1111_1111, 0b1111_1111, (0b0110_1111 << 1) | 0b0000_0001;
188 => 0b1111_1111, 0b1111_1111, (0b0111_0000 << 1) | 0b0000_0001;
191 => 0b1111_1111, 0b1111_1111, (0b0111_0001 << 1) | 0b0000_0001;
197 => 0b1111_1111, 0b1111_1111, (0b0111_0010 << 1) | 0b0000_0001;
231 => 0b1111_1111, 0b1111_1111, (0b0111_0011 << 1) | 0b0000_0001;
239 => 0b1111_1111, 0b1111_1111, (0b0111_0100 << 1) | 0b0000_0001;
9 => 0b1111_1111, 0b1111_1111, 0b1110_1010;
142 => 0b1111_1111, 0b1111_1111, 0b1110_1011;
144 => 0b1111_1111, 0b1111_1111, 0b1110_1100;
145 => 0b1111_1111, 0b1111_1111, 0b1110_1101;
148 => 0b1111_1111, 0b1111_1111, 0b1110_1110;
159 => 0b1111_1111, 0b1111_1111, 0b1110_1111;
171 => 0b1111_1111, 0b1111_1111, 0b1111_0000;
206 => 0b1111_1111, 0b1111_1111, 0b1111_0001;
215 => 0b1111_1111, 0b1111_1111, 0b1111_0010;
225 => 0b1111_1111, 0b1111_1111, 0b1111_0011;
236 => 0b1111_1111, 0b1111_1111, 0b1111_0100;
237 => 0b1111_1111, 0b1111_1111, 0b1111_0101;
199 => 0b1111_1111, 0b1111_1111, 0b1111_0110, (0b0000_0000 << 7) | 0b0111_1111;
207 => 0b1111_1111, 0b1111_1111, 0b1111_0110, (0b0000_0001 << 7) | 0b0111_1111;
234 => 0b1111_1111, 0b1111_1111, 0b1111_0111, (0b0000_0000 << 7) | 0b0111_1111;
235 => 0b1111_1111, 0b1111_1111, 0b1111_0111, (0b0000_0001 << 7) | 0b0111_1111;
192 => 0b1111_1111, 0b1111_1111, 0b1111_1000, (0b0000_0000 << 6) | 0b0011_1111;
193 => 0b1111_1111, 0b1111_1111, 0b1111_1000, (0b0000_0001 << 6) | 0b0011_1111;
200 => 0b1111_1111, 0b1111_1111, 0b1111_1000, (0b0000_0010 << 6) | 0b0011_1111;
201 => 0b1111_1111, 0b1111_1111, 0b1111_1000, (0b0000_0011 << 6) | 0b0011_1111;
202 => 0b1111_1111, 0b1111_1111, 0b1111_1001, (0b0000_0000 << 6) | 0b0011_1111;
205 => 0b1111_1111, 0b1111_1111, 0b1111_1001, (0b0000_0001 << 6) | 0b0011_1111;
210 => 0b1111_1111, 0b1111_1111, 0b1111_1001, (0b0000_0010 << 6) | 0b0011_1111;
213 => 0b1111_1111, 0b1111_1111, 0b1111_1001, (0b0000_0011 << 6) | 0b0011_1111;
218 => 0b1111_1111, 0b1111_1111, 0b1111_1010, (0b0000_0000 << 6) | 0b0011_1111;
219 => 0b1111_1111, 0b1111_1111, 0b1111_1010, (0b0000_0001 << 6) | 0b0011_1111;
238 => 0b1111_1111, 0b1111_1111, 0b1111_1010, (0b0000_0010 << 6) | 0b0011_1111;
240 => 0b1111_1111, 0b1111_1111, 0b1111_1010, (0b0000_0011 << 6) | 0b0011_1111;
242 => 0b1111_1111, 0b1111_1111, 0b1111_1011, (0b0000_0000 << 6) | 0b0011_1111;
243 => 0b1111_1111, 0b1111_1111, 0b1111_1011, (0b0000_0001 << 6) | 0b0011_1111;
255 => 0b1111_1111, 0b1111_1111, 0b1111_1011, (0b0000_0010 << 6) | 0b0011_1111;
203 => 0b1111_1111, 0b1111_1111, 0b1111_1011, (0b0000_0110 << 5) | 0b0001_1111;
204 => 0b1111_1111, 0b1111_1111, 0b1111_1011, (0b0000_0111 << 5) | 0b0001_1111;
211 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b0000_0000 << 5) | 0b0001_1111;
212 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b0000_0001 << 5) | 0b0001_1111;
214 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b0000_0010 << 5) | 0b0001_1111;
221 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b0000_0011 << 5) | 0b0001_1111;
222 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b0000_0100 << 5) | 0b0001_1111;
223 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b0000_0101 << 5) | 0b0001_1111;
241 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b0000_0110 << 5) | 0b0001_1111;
244 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b0000_0111 << 5) | 0b0001_1111;
245 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b0000_0000 << 5) | 0b0001_1111;
246 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b0000_0001 << 5) | 0b0001_1111;
247 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b0000_0010 << 5) | 0b0001_1111;
248 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b0000_0011 << 5) | 0b0001_1111;
250 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b0000_0100 << 5) | 0b0001_1111;
251 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b0000_0101 << 5) | 0b0001_1111;
252 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b0000_0110 << 5) | 0b0001_1111;
253 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b0000_0111 << 5) | 0b0001_1111;
254 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_0000 << 5) | 0b0001_1111;
2 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_0010 << 4) | 0b0000_1111;
3 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_0011 << 4) | 0b0000_1111;
4 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_0100 << 4) | 0b0000_1111;
5 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_0101 << 4) | 0b0000_1111;
6 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_0110 << 4) | 0b0000_1111;
7 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_0111 << 4) | 0b0000_1111;
8 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_1000 << 4) | 0b0000_1111;
11 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_1001 << 4) | 0b0000_1111;
12 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_1010 << 4) | 0b0000_1111;
14 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_1011 << 4) | 0b0000_1111;
15 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_1100 << 4) | 0b0000_1111;
16 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_1101 << 4) | 0b0000_1111;
17 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_1110 << 4) | 0b0000_1111;
18 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0000_1111 << 4) | 0b0000_1111;
19 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_0000 << 4) | 0b0000_1111;
20 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_0001 << 4) | 0b0000_1111;
21 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_0010 << 4) | 0b0000_1111;
23 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_0011 << 4) | 0b0000_1111;
24 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_0100 << 4) | 0b0000_1111;
25 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_0101 << 4) | 0b0000_1111;
26 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_0110 << 4) | 0b0000_1111;
27 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_0111 << 4) | 0b0000_1111;
28 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_1000 << 4) | 0b0000_1111;
29 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_1001 << 4) | 0b0000_1111;
30 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_1010 << 4) | 0b0000_1111;
31 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_1011 << 4) | 0b0000_1111;
127 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_1100 << 4) | 0b0000_1111;
220 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_1101 << 4) | 0b0000_1111;
249 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000_1110 << 4) | 0b0000_1111;
10 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0011_1100 << 2) | 0b0000_0011;
13 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0011_1101 << 2) | 0b0000_0011;
22 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0011_1110 << 2) | 0b0000_0011;
];
}
#[test]
fn test_encode_all_code_joined() {
let bytes = vec![
0b1111_1111,
(0b0001_1000 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1101,
(0b0000_1000 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
0b1110_0010,
0b1111_1111,
0b1111_1111,
0b1111_1110,
(0b0000_0011 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
0b1110_0100,
0b1111_1111,
0b1111_1111,
0b1111_1110,
(0b0000_0101 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
0b1110_0110,
0b1111_1111,
0b1111_1111,
0b1111_1110,
(0b0000_0111 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
0b1110_1000,
0b1111_1111,
0b1111_1111,
0b1110_1010,
0b1111_1111,
0b1111_1111,
0b1111_1111,
(0b0011_1100 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
0b1111_1010,
(0b0000_0001 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1111,
(0b0010_1010 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
0b1111_1111,
(0b0000_1101 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
0b1110_1011,
0b1111_1111,
0b1111_1111,
0b1111_1110,
(0b0000_1100 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
0b1110_1101,
0b1111_1111,
0b1111_1111,
0b1111_1110,
(0b0000_1110 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
0b1110_1111,
0b1111_1111,
0b1111_1111,
0b1111_1111,
(0b0000_0000 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
0b1111_0001,
0b1111_1111,
0b1111_1111,
0b1111_1111,
(0b0000_0010 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
0b1111_1111,
(0b0000_0010 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1111,
(0b0011_0011 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
0b1111_1101,
(0b0000_0000 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1111,
(0b0011_0101 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
0b1111_1101,
(0b0000_0010 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1111,
(0b0011_0111 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
0b1111_1110,
(0b0000_0000 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1111,
(0b0011_1001 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
0b1111_1110,
(0b0000_0010 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1111,
(0b0011_1011 << 2)
+ 0b0000_0001,
(0b0000_0100 << 4)
+ 0b0000_1111,
(0b0011_1000 << 2)
+ 0b0000_0011,
0b1111_1001,
0b1111_1111,
(0b0000_1010 << 4)
+ 0b0000_1111,
0b1111_1100,
(0b0000_0001 << 7)
+ (0b0001_0101 << 1)
+ 0b0000_0001,
(0b0111_1000 << 1)
+ 0b0000_0001,
0b1111_1110,
(0b0000_0010 << 6)
+ 0b0011_1111,
(0b0000_1010 << 4)
+ 0b0000_1111,
(0b0011_1011 << 2)
+ 0b0000_0011,
(0b0011_1001 << 2)
+ 0b0000_0011,
0b1111_1101,
(0b0000_0001 << 7)
+ 0b0111_1101,
(0b0000_0000 << 7)
+ (0b0001_0110 << 1)
+ 0b0000_0000,
(0b0001_0111 << 3)
+ 0b0000_0011,
(0b0000_0000 << 5)
+ 0b0000_0000,
(0b0000_0001 << 3)
+ 0b0000_0000,
(0b0000_0010 << 6)
+ 0b0001_1001,
(0b0001_1010 << 2)
+ 0b0000_0001,
(0b0000_1011 << 4)
+ 0b0000_0111,
(0b0000_0000 << 6)
+ 0b0001_1101,
(0b0001_1110 << 2)
+ 0b0000_0001,
(0b0000_1111 << 4)
+ 0b0000_1011,
(0b0000_0100 << 5)
+ 0b0001_1111,
(0b0000_0011 << 5)
+ 0b0001_1111,
0b1111_1111,
(0b0000_0000 << 6)
+ 0b0010_0000,
0b1111_1111,
(0b0000_1011 << 4)
+ 0b0000_1111,
(0b0011_1100 << 2)
+ 0b0000_0011,
0b1111_1111,
(0b0000_0010 << 5)
+ 0b0001_0000,
(0b0000_0001 << 7)
+ 0b0101_1101,
(0b0101_1110 << 1)
+ 0b0000_0001,
(0b0001_1111 << 2)
+ 0b0000_0011,
(0b0000_0000 << 3)
+ 0b0000_0110,
(0b0000_0001 << 4)
+ 0b0000_1100,
(0b0000_0010 << 5)
+ 0b0001_1000,
(0b0000_0011 << 6)
+ 0b0011_0010,
(0b0000_0000 << 7)
+ 0b0110_0101,
(0b0110_0110 << 1)
+ 0b0000_0001,
(0b0010_0111 << 2)
+ 0b0000_0011,
(0b0000_1000 << 3)
+ 0b0000_0110,
(0b0000_1001 << 4)
+ 0b0000_1101,
(0b0000_0010 << 5)
+ 0b0001_1010,
(0b0000_0011 << 6)
+ 0b0011_0110,
(0b0000_0000 << 7)
+ 0b0110_1101,
(0b0110_1110 << 1)
+ 0b0000_0001,
(0b0010_1111 << 2)
+ 0b0000_0011,
(0b0001_0000 << 3)
+ 0b0000_0111,
(0b0000_0001 << 4)
+ 0b0000_1110,
(0b0000_0010 << 5)
+ 0b0001_1111,
(0b0000_0100 << 5)
+ 0b0001_1100,
(0b0000_0011 << 6)
+ 0b0011_1111,
(0b0000_0001 << 6)
+ 0b0011_1111,
(0b0111_1011 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1100,
(0b0000_0000 << 6)
+ 0b0011_1111,
(0b0111_1100 << 1)
+ 0b0000_0001,
0b1111_1111,
(0b0001_1100 << 3)
+ 0b0000_0100,
(0b0000_0010 << 5)
+ 0b0001_1111,
0b1111_1111,
(0b0000_0001 << 6)
+ (0b0000_0011 << 1)
+ 0b0000_0001,
(0b0000_0011 << 3)
+ 0b0000_0001,
(0b0000_0000 << 6)
+ 0b0010_0100,
(0b0000_0101 << 3)
+ 0b0000_0100,
(0b0000_0101 << 5)
+ 0b0001_0011,
(0b0000_0000 << 7)
+ (0b0010_0111 << 1)
+ 0b0000_0000,
(0b0000_0110 << 4)
+ 0b0000_1110,
(0b0000_0100 << 5)
+ 0b0001_1101,
(0b0000_0001 << 6)
+ 0b0010_1000,
(0b0010_1001 << 2)
+ 0b0000_0010,
(0b0000_1010 << 4)
+ 0b0000_0011,
(0b0000_0001 << 7)
+ (0b0010_1011 << 1)
+ 0b0000_0001,
(0b0011_0110 << 2)
+ 0b0000_0010,
(0b0000_1100 << 4)
+ 0b0000_0100,
(0b0000_0000 << 7)
+ (0b0000_1001 << 2)
+ 0b0000_0010,
(0b0000_1101 << 4)
+ 0b0000_1110,
(0b0000_0111 << 5)
+ 0b0001_1110,
(0b0000_0000 << 6)
+ 0b0011_1100,
(0b0000_0001 << 7)
+ 0b0111_1010,
(0b0111_1011 << 1)
+ 0b0000_0001,
0b1111_1111,
(0b0011_1110 << 2)
+ 0b0000_0011,
0b1111_1110,
(0b0000_0000 << 7)
+ 0b0111_1111,
(0b0111_1101 << 1)
+ 0b0000_0001,
0b1111_1111,
(0b0000_1101 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
0b1111_1100,
0b1111_1111,
0b1111_1110,
(0b0000_0110 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_0100,
(0b0000_0010 << 6)
+ 0b0011_1111,
0b1111_1111,
(0b0010_0111 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1010,
(0b0000_0000 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1101_0011,
0b1111_1111,
0b1111_1111,
(0b0001_0100 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1101,
(0b0000_0101 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1011,
(0b0000_0001 << 5)
+ 0b0001_1111,
0b1111_1111,
0b1110_1011,
(0b0000_0000 << 7)
+ 0b0111_1111,
0b1111_1111,
0b1101_1010,
0b1111_1111,
0b1111_1111,
(0b0101_1011 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
(0b0001_1100 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1110,
(0b0001_1101 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1101,
(0b0000_1110 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1110,
(0b0000_1011 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1011,
(0b0000_0111 << 5)
+ 0b0001_1111,
0b1111_1111,
0b1111_1101,
(0b0000_0100 << 5)
+ 0b0001_1111,
0b1111_1111,
0b1111_1101,
(0b0000_0101 << 5)
+ 0b0001_1111,
0b1111_1111,
0b1110_1011,
(0b0000_0001 << 7)
+ 0b0111_1111,
0b1111_1111,
0b1110_0000,
0b1111_1111,
0b1111_1111,
0b1110_1110,
0b1111_1111,
0b1111_1111,
(0b0110_0001 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
(0b0010_0010 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
(0b0000_0011 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1110,
(0b0000_0100 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1110_1110,
(0b0000_0000 << 7)
+ 0b0111_1111,
0b1111_1111,
(0b0101_1000 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
(0b0010_0101 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1101,
(0b0000_1001 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1100,
(0b0000_0110 << 5)
+ 0b0001_1111,
0b1111_1111,
0b1111_1001,
(0b0000_0011 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1011,
(0b0000_0011 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1101_1010,
0b1111_1111,
0b1111_1110,
(0b0001_1101 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_0100,
(0b0000_0001 << 7)
+ 0b0111_1111,
0b1111_1111,
(0b0101_1011 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1110,
(0b0001_1100 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1110,
(0b0000_1000 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1101,
(0b0000_0001 << 5)
+ 0b0001_1111,
0b1111_1111,
0b1101_1110,
0b1111_1111,
0b1111_1111,
(0b0110_1010 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1110,
(0b0001_1101 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1011,
(0b0000_0110 << 5)
+ 0b0001_1111,
0b1111_1111,
0b1111_1110,
(0b0000_0000 << 5)
+ 0b0001_1111,
0b1111_1111,
0b1101_1111,
0b1111_1111,
0b1111_1111,
(0b0001_1111 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
(0b0000_1011 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1110,
(0b0000_1100 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_0000,
(0b0000_0000 << 7)
+ 0b0111_1111,
0b1111_1111,
(0b0010_0001 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1110,
(0b0000_0000 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_0001,
(0b0000_0000 << 7)
+ 0b0111_1111,
0b1111_1111,
0b1110_1101,
0b1111_1111,
0b1111_1111,
(0b0010_0001 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
(0b0000_1110 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1110,
(0b0000_1111 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1110_1010,
0b1111_1111,
0b1111_1111,
(0b0010_0010 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1110,
(0b0000_0011 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1001,
(0b0000_0000 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1000,
(0b0000_0000 << 7)
+ 0b0111_1111,
0b1111_1111,
(0b0110_0101 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
(0b0000_0110 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1111,
(0b0000_0001 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
(0b0010_0000 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
0b1110_0001,
0b1111_1111,
0b1111_1110,
(0b0000_1011 << 4)
+ 0b0000_1111,
0b1111_1111,
(0b0111_0001 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
(0b0000_0111 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1111,
(0b0000_0010 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1010,
(0b0000_0000 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1101,
(0b0000_0100 << 5)
+ 0b0001_1111,
0b1111_1111,
0b1111_1111,
(0b0000_0010 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1111,
(0b0110_0011 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
0b1111_0010,
(0b0000_0000 << 7)
+ 0b0111_1111,
0b1111_1111,
0b1111_1101,
(0b0000_1110 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
(0b0101_1111 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
0b1111_0010,
(0b0000_0001 << 7)
+ 0b0111_1111,
0b1111_1111,
0b1111_1000,
(0b0000_0001 << 7)
+ 0b0111_1111,
0b1111_1111,
0b1111_1011,
(0b0000_0001 << 6)
+ 0b0011_1111,
0b1111_1111,
(0b0001_0010 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1000,
(0b0000_0011 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1110,
(0b0000_0110 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
(0b0110_0000 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
0b1111_1000,
(0b0000_0001 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1110,
(0b0000_0111 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
(0b0110_0010 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
(0b0111_0010 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1110,
(0b0000_0100 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_0010,
(0b0000_0001 << 7)
+ 0b0111_1111,
0b1111_1111,
0b1111_1101,
(0b0000_0000 << 5)
+ 0b0001_1111,
0b1111_1111,
0b1111_1111,
(0b0000_1001 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1111,
0b1111_1110,
(0b0000_0001 << 7)
+ 0b0111_1111,
0b1111_1111,
0b1111_1110,
(0b0000_0011 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
(0b0110_0100 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
0b1111_1001,
(0b0000_0001 << 6)
+ 0b0011_1111,
0b1111_1111,
(0b0010_1100 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
(0b0011_0011 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1011,
(0b0000_0001 << 6)
+ 0b0011_1111,
0b1111_1111,
(0b0110_0110 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
(0b0000_1001 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1001,
(0b0000_0011 << 6)
+ 0b0011_1111,
0b1111_1111,
(0b0110_1000 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
(0b0011_0011 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1110,
(0b0000_1010 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1010,
(0b0000_0011 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1101,
(0b0000_0110 << 5)
+ 0b0001_1111,
0b1111_1111,
0b1111_1110,
(0b0000_1111 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
(0b0000_0100 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
(0b0000_0101 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
(0b0010_1010 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
(0b0001_0100 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1111,
(0b0110_1011 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
0b1111_1001,
(0b0000_0010 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1110,
(0b0000_1100 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
(0b0010_1101 << 2)
+ 0b0000_0011,
0b1111_1111,
0b1111_1111,
0b1111_0011,
(0b0000_0001 << 7)
+ 0b0111_1111,
0b1111_1111,
0b1111_1110,
(0b0000_1000 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
(0b0110_1001 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
0b1111_1010,
(0b0000_0010 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1111,
(0b0000_1011 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1111,
0b1111_1111,
(0b0000_0000 << 7)
+ 0b0111_1111,
0b1111_1111,
0b1111_1110,
(0b0000_1100 << 4)
+ 0b0000_1111,
0b1111_1111,
0b1111_1111,
(0b0110_1101 << 1)
+ 0b0000_0001,
0b1111_1111,
0b1111_1111,
0b1111_1011,
(0b0000_0010 << 6)
+ 0b0011_1111,
0b1111_1111,
0b1111_1111,
(0b0000_1111 << 3)
+ 0b0000_0111,
0b1111_1111,
0b1111_1111,
0b1111_0000,
0b1111_1111,
0b1111_1111,
0b1111_1011,
(0b0000_0010 << 6)
+ 0b0011_1111,
];
let values: Vec<u8> = (0..=255).collect();
let res = values.hpack_encode();
assert_eq!(res, Ok(bytes));
}
use super::super::HpackStringDecode;
#[test]
fn encoded_length_matches_output_at_chunk_boundaries() {
for len in [0, 1, 63, 64, 65, 127, 128, 129, 256, 1025] {
let value: Vec<u8> = (0..=255).cycle().take(len).collect();
let mut encoded = Vec::new();
super::encode_into(&value, &mut encoded);
let bits: usize = value
.iter()
.map(|byte| usize::from(super::ENCODE_CODE_LENGTHS[usize::from(*byte)]))
.sum();
assert_eq!(super::encoded_len(&value), Ok(bits.div_ceil(8)));
assert_eq!(encoded.len(), bits.div_ceil(8));
}
}
#[test]
fn byte_count_exact_when_bit_count_multiple_of_8() {
let encoded = vec![
0x8c, 0x2d, 0x4b, 0x70, 0xdd, 0xf4, 0x5a, 0xbe, 0xfb, 0x40, 0x05, 0xdb,
];
let mut res = Vec::new();
for byte in encoded.hpack_decode() {
res.push(byte.unwrap());
}
let reencoded = res.hpack_encode();
assert_eq!(reencoded.unwrap().last(), Some(&0xdb));
}
#[test]
fn byte_() {
let encoded = vec![
0x55, 0x92, 0xbe, 0xff, 0x48, 0x36, 0xcb, 0x86, 0x37, 0x3d, 0x68, 0xca, 0xc9, 0x61,
0xce, 0xde, 0xdc, 0xe5, 0xfc,
];
let mut res = Vec::new();
for byte in encoded.hpack_decode() {
res.push(byte.unwrap());
}
let reencoded = res.hpack_encode();
assert_eq!(reencoded.unwrap().last(), Some(&0xfc));
}
}