///|
pub struct Decoder {
priv buffer : Array[Byte]
priv mut limit : Int
priv mut expected : Int
priv mut poisoned : Bool
} derive(Debug)
///|
pub fn Decoder::new(max_size? : Int = 131072) -> Decoder raise FrameError {
if max_size < 8 || max_size > 16777216 {
raise Invalid("invalid frame limit")
}
{ buffer: [], limit: max_size, expected: 7, poisoned: false, }
}
///|
fn Decoder::set_limit(self : Decoder, limit : Int) -> Unit raise FrameError {
if limit < 4096 ||
limit > 16777216 ||
self.buffer.length() > limit ||
self.expected > limit {
raise Invalid("invalid negotiated frame limit")
}
self.limit = limit
}
///|
fn Decoder::consume(
self : Decoder,
input : Bytes,
) -> Array[Frame] raise FrameError {
let frames = []
for byte in input {
self.buffer.push(byte)
if self.buffer.length() == 7 {
let b = self.buffer
let n = b[3].to_int64() * 16777216L +
b[4].to_int64() * 65536L +
b[5].to_int64() * 256L +
b[6].to_int64()
if n > (self.limit - 8).to_int64() {
raise Invalid("declared frame exceeds limit")
}
self.expected = n.to_int() + 8
}
if self.buffer.length() == self.expected && self.expected >= 8 {
if byte != 206 {
raise Invalid("invalid frame terminator")
}
let b = self.buffer
let payload = []
for i in 7..<(b.length() - 1) {
payload.push(b[i])
}
let frame : Frame = {
kind: b[0].to_int(),
channel: b[1].to_int() * 256 + b[2].to_int(),
payload: Bytes::from_array(payload),
}
validate(frame, self.limit)
frames.push(frame)
self.buffer.clear()
self.expected = 7
}
}
frames
}
///|
/// A malformed stream poisons the decoder. Frames from the failing feed call are discarded.
pub fn Decoder::feed(
self : Decoder,
input : Bytes,
) -> Array[Frame] raise FrameError {
if self.poisoned {
raise Invalid("decoder is poisoned")
}
errdefer {
self.poisoned = true
}
self.consume(input)
}
///|
pub fn Decoder::finish(self : Decoder) -> Unit raise FrameError {
if self.poisoned || !self.buffer.is_empty() {
raise Invalid("incomplete or invalid stream")
}
}