///|
/// Stateful decoder accepting arbitrarily fragmented byte chunks.
pub struct Decoder {
buffer : Array[Byte]
max_frame_size : Int
max_buffer_size : Int
}
///|
pub fn Decoder::new(
max_frame_size? : Int = 1048576,
max_buffer_size? : Int = max_frame_size + 5,
) -> Decoder {
Decoder::{ buffer: [], max_frame_size, max_buffer_size, }
}
///|
/// Number of bytes retained while waiting for a complete frame.
pub fn Decoder::buffered(self : Decoder) -> Int {
self.buffer.length()
}
///|
/// Discard partial data so a caller can recover at a known boundary.
pub fn Decoder::reset(self : Decoder) -> Unit {
self.buffer.clear()
}
///|
/// Feed any chunk size and return every complete frame now available.
pub fn Decoder::feed(
self : Decoder,
chunk : Bytes,
) -> Result[Array[Bytes], FrameError] {
let requested = self.buffer.length() + chunk.length()
if requested > self.max_buffer_size {
return Err(BufferLimitExceeded(requested, self.max_buffer_size))
}
for byte in chunk {
self.buffer.push(byte)
}
let frames : Array[Bytes] = []
for _step = 0; self.buffer.length() > 0; _step = _step + 1 {
let snapshot = Bytes::from_array(self.buffer)
match decode_frame(snapshot, max_frame_size=self.max_frame_size) {
Ok((payload, consumed)) => {
frames.push(payload)
self.buffer.clear()
for byte in snapshot[consumed:] {
self.buffer.push(byte)
}
}
Err(NeedMore) => return Ok(frames)
Err(error) => return Err(error)
}
}
Ok(frames)
}
///|
/// Signal end-of-input. A partial header or payload is an explicit error.
pub fn Decoder::finish(self : Decoder) -> Result[Unit, FrameError] {
if self.buffer.length() == 0 {
Ok(())
} else {
Err(NeedMore)
}
}