pub(crate) const INS_BASE: [u32; 24] = [
0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, 34, 50, 66, 98, 130, 194, 322, 578, 1090, 2114, 6210,
22594,
];
pub(crate) const INS_EXTRA: [u32; 24] = [
0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 12, 14, 24,
];
pub(crate) const COPY_BASE: [u32; 24] = [
2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 18, 22, 30, 38, 54, 70, 102, 134, 198, 326, 582, 1094, 2118,
];
pub(crate) const COPY_EXTRA: [u32; 24] = [
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 24,
];
pub(crate) fn insert_to_code(len: u32) -> (u32, u32, u32) {
for c in (0..24).rev() {
let base = INS_BASE[c];
if len >= base {
let extra = len - base;
debug_assert!(extra < (1u32 << INS_EXTRA[c]) || INS_EXTRA[c] >= 32);
return (c as u32, INS_EXTRA[c], extra);
}
}
unreachable!("INS_BASE[0]=0, every u32 falls into some code")
}
pub(crate) fn copy_to_code(len: u32) -> (u32, u32, u32) {
debug_assert!(len >= 2, "copy length must be at least 2");
for c in (0..24).rev() {
let base = COPY_BASE[c];
if len >= base {
let extra = len - base;
debug_assert!(extra < (1u32 << COPY_EXTRA[c]) || COPY_EXTRA[c] >= 32);
return (c as u32, COPY_EXTRA[c], extra);
}
}
unreachable!("COPY_BASE[0]=2, every len>=2 falls into some code")
}
pub(crate) fn ic_command_sym(ins_code: u32, copy_code: u32, use_last_dist: bool) -> u32 {
let ins_grp = if ins_code < 8 {
0
} else if ins_code < 16 {
1
} else {
2
};
let copy_grp = if copy_code < 8 {
0
} else if copy_code < 16 {
1
} else {
2
};
let cell: u32 = match (ins_grp, copy_grp, use_last_dist) {
(0, 0, true) => 0,
(0, 1, true) => 1,
(0, 0, false) => 2,
(0, 1, false) => 3,
(1, 0, false) => 4,
(1, 1, false) => 5,
(0, 2, false) => 6,
(2, 0, false) => 7,
(1, 2, false) => 8,
(2, 1, false) => 9,
(2, 2, false) => 10,
_ => panic!("use_last_dist=true only valid for ins<8 && copy<16"),
};
let ins_base: u32 = match ins_grp {
0 => 0,
1 => 8,
2 => 16,
_ => unreachable!(),
};
let copy_base: u32 = match copy_grp {
0 => 0,
1 => 8,
2 => 16,
_ => unreachable!(),
};
let cell_local = ((ins_code - ins_base) << 3) | (copy_code - copy_base);
cell * 64 + cell_local
}
pub(crate) fn distance_to_normal_code(dist: u32) -> Option<(u32, u32, u32)> {
if dist == 0 {
return None;
}
for v in 0u32..48 {
let ndistbits = 1 + (v >> 1);
let offset = ((2u32 + (v & 1)) << ndistbits) - 4;
let lo = offset + 1;
let hi = offset + (1u32 << ndistbits);
if dist >= lo && dist <= hi {
let dextra = dist - lo;
return Some((16 + v, ndistbits, dextra));
}
}
None
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn insert_code_roundtrip() {
for len in [
0u32, 1, 5, 6, 14, 22, 100, 322, 1090, 22594, 22595, 22600, 100_000,
] {
let (c, eb, ex) = insert_to_code(len);
let reconstructed = INS_BASE[c as usize] + ex;
assert_eq!(reconstructed, len, "len {} → code {} extra {}", len, c, ex);
if eb < 32 {
assert!(ex < (1u32 << eb), "extra {} too big for {} bits", ex, eb);
}
}
}
#[test]
fn copy_code_roundtrip() {
for len in [
2u32, 3, 9, 10, 14, 22, 100, 326, 1094, 2118, 2119, 10_000, 100_000,
] {
let (c, eb, ex) = copy_to_code(len);
let reconstructed = COPY_BASE[c as usize] + ex;
assert_eq!(reconstructed, len, "len {} → code {} extra {}", len, c, ex);
if eb < 32 {
assert!(ex < (1u32 << eb), "extra {} too big for {} bits", ex, eb);
}
}
}
#[test]
fn distance_code_roundtrip() {
for d in [
1u32, 2, 3, 4, 5, 12, 13, 28, 29, 100, 1000, 65520, 1_000_000, 16_777_000,
] {
let (dcode, ndistbits, dextra) = distance_to_normal_code(d).unwrap();
let v = dcode - 16;
let nb = 1 + (v >> 1);
assert_eq!(nb, ndistbits);
let offset = ((2u32 + (v & 1)) << nb) - 4;
let recovered = offset + dextra + 1;
assert_eq!(recovered, d, "dist {} → code {} extra {}", d, dcode, dextra);
assert!(dextra < (1u32 << nb));
}
}
#[test]
fn ic_command_sym_known_values() {
assert_eq!(ic_command_sym(0, 0, true), 0);
assert_eq!(ic_command_sym(8, 0, false), 256);
assert_eq!(ic_command_sym(23, 0, false), 504);
}
}