// Static dictionary references (RFC 7932 section 8) and literal context
// modes (section 7.1).
///|
const NUM_TRANSFORMS : Int32 = 121
///|
/// The longest transformed word: a 24-byte word plus 13 added bytes.
const MAX_TRANSFORMED_WORD : Int32 = 37
///|
/// Writes word `index` of length `length` under transform `transform` into
/// `out`, and returns how many bytes it wrote.
fn transform_word(
out : FixedArray[Byte],
length : Int32,
index : Int32,
transform : Int32,
) -> Int32 {
let kind = transform_types[transform].to_int()
let mut start = dictionary_offsets[length] + index * length
let mut word_length = length
if kind >= 1 && kind <= 9 {
word_length = (length - kind).max(0)
} else if kind >= 12 {
let skip = kind - 11
start += skip
word_length = (length - skip).max(0)
}
// A prefix and a suffix take at most 13 bytes together, so the word, at
// most 24, fits in `out`'s MAX_TRANSFORMED_WORD bytes, as
// `@transform.transform_into` requires (the test "transform_word: the
// longest word under the longest transform fills the buffer" checks the
// tables).
@transform.transform_into(
out,
transform_prefixes[transform][:],
dictionary[start:start + word_length],
kind,
transform_suffixes[transform][:],
)
}
///|
/// The literal context ID of `mode` for the last two bytes `p1` and `p2`.
fn literal_context(mode : Int32, p1 : Int32, p2 : Int32) -> Int32 {
match mode {
0 => p1 & 0x3f
1 => p1 >> 2
2 => lut0[p1].to_int() | lut1[p2].to_int()
_ => (lut2[p1].to_int() << 3) | lut2[p2].to_int()
}
}