///|
/// QPACK primitives (RFC 9204): the 99-entry static table with exact and
/// name-only lookups (Appendix A) and the string literal coding raw and Huffman — the
/// building blocks the field-section encoder is assembled from. The prefixed integer
/// under them all is RFC 7541 §5.1 unchanged, so it comes from `moonvar`.
///
/// moon run src/examples/27-qpack-primitives --target native
#coverage.skip
fn main {
run() catch {
e => println("qpack error: \{e}")
}
}
///|
fn run() -> Unit raise {
println("static table entries = \{@qpack.static_table.length()}")
println("get(17) = \{field(@qpack.entry(17))} (expect :method GET)")
println("find(:method, GET) = \{opt_i(@qpack.find(b":method", b"GET"))}")
println("find_name(:status) = \{opt_i(@qpack.find_name(b":status"))}")
println(
"max_entries(4096)=\{@qpack.max_entries(4096)} entry_size(:method,GET)=\{@qpack.cost(b":method", b"GET")}",
)
let enc = @prefix.encode(1337, prefix=5)
println("int 1337 (5-bit prefix) = \{hex(enc)}")
let (v, n) = @prefix.decode(enc[:], prefix=5)
println("decoded = \{v} in \{n} bytes")
let raw = @qpack.string(b"hello", 7, 0, false)
let huff = @qpack.string(b"hello", 7, 0, true)
println(
"string \"hello\": raw=\{raw.length()} huffman=\{huff.length()} bytes (huffman shorter=\{huff.length() < raw.length()})",
)
match @qpack.read_string(huff[:], 7) {
Some((d, _)) => println("huffman decoded = \{ascii(d)}")
None => println("bad string")
}
}
///|
fn field(o : @header.Header?) -> String {
match o {
Some(h) => h.ascii().0 + " " + h.ascii().1
None => "(none)"
}
}
///|
fn opt_i(o : Int32?) -> String {
match o {
Some(n) => n.to_string()
None => "(none)"
}
}
///|
fn hex(b : Bytes) -> String {
let digits = "0123456789abcdef"
let sb = StringBuilder()
for i = 0; i < b.length(); i = i + 1 {
let x = b[i].to_int()
sb.write_char(digits[x >> 4].unsafe_to_char())
sb.write_char(digits[x & 0xf].unsafe_to_char())
}
sb.to_string()
}
///|
fn ascii(b : Bytes) -> String {
let sb = StringBuilder()
for i = 0; i < b.length(); i = i + 1 {
sb.write_char(b[i].to_int().unsafe_to_char())
}
sb.to_string()
}