///|
pub fn count_single_split_cases(input : Bytes) -> Int {
input.length() + 1
}
///|
pub fn count_three_way_cases(
first_cuts : Array[Int],
second_cuts : Array[Int],
) -> Int {
first_cuts.length() * second_cuts.length()
}
///|
pub fn feed_single_split(
input : Bytes,
split : Int,
policy : DecodePolicy,
) -> DecodeProgress {
let decoder = Decoder::new(policy)
let first = Bytes::from_array(input.to_array()[0:split])
let second = Bytes::from_array(input.to_array()[split:])
match decoder.feed(first) {
Done(frame) => Done(frame)
Failed(error) => Failed(error)
NeedMore => decoder.feed(second)
}
}
///|
pub fn feed_three_way(
input : Bytes,
first_cut : Int,
second_cut : Int,
policy : DecodePolicy,
) -> DecodeProgress {
let decoder = Decoder::new(policy)
match decoder.feed(Bytes::from_array(input.to_array()[0:first_cut])) {
Done(frame) => Done(frame)
Failed(error) => Failed(error)
NeedMore =>
match
decoder.feed(Bytes::from_array(input.to_array()[first_cut:second_cut])) {
Done(frame) => Done(frame)
Failed(error) => Failed(error)
NeedMore =>
decoder.feed(Bytes::from_array(input.to_array()[second_cut:]))
}
}
}
///|
pub fn assert_all_single_splits(input : Bytes, policy : DecodePolicy) -> Int {
for split = 0; split <= input.length(); split = split + 1 {
match feed_single_split(input, split, policy) {
Done(_) => ()
NeedMore =>
abort("single split unexpectedly needed more data at \{split}")
Failed(error) =>
abort("single split failed at \{split}: \{error.context}")
}
}
input.length() + 1
}
///|
pub fn assert_selected_three_way_splits(
input : Bytes,
cuts : Array[Int],
policy : DecodePolicy,
) -> Int {
let mut count = 0
for first in cuts {
for second in cuts {
if first <= second && second <= input.length() {
match feed_three_way(input, first, second, policy) {
Done(_) => ()
NeedMore => abort("three-way split unexpectedly needed more data")
Failed(error) => abort("three-way split failed: \{error.context}")
}
count = count + 1
}
}
}
count
}
///|
pub fn assert_all_prefix_truncations(
header : Bytes,
policy : DecodePolicy,
) -> Int {
for length = 0; length < header.length(); length = length + 1 {
let decoder = Decoder::new(policy)
match decoder.feed(Bytes::from_array(header.to_array()[0:length])) {
NeedMore => ()
Failed(error) =>
if error.kind != NeedMoreData &&
error.kind != TruncatedAddress &&
error.kind != TruncatedTlv {
abort("unexpected truncation error")
}
Done(_) => abort("truncated header decoded as complete")
}
}
header.length()
}