pub struct LengthFieldBasedDecoder { buffer: Box<[u8]>, cur_index: usize, } impl LengthFieldBasedDecoder { const INITIAL_CAPACITY: usize = 8192; pub fn new() -> Self { Self { buffer: vec![0u8; Self::INITIAL_CAPACITY].into_boxed_slice(), cur_index: 0, } } pub fn input(&mut self, data: &[u8]) { self.ensure_capacity(data.len()); self.buffer[self.cur_index..self.cur_index + data.len()].copy_from_slice(data); self.cur_index += data.len(); } pub fn pop_with(&mut self, decode: impl FnOnce(&[u8]) -> Option) -> Option { if self.cur_index >= 3 { let frame_length = read_length_field(&self.buffer); let segment_size = 3 + frame_length; if self.cur_index >= segment_size { let retval = decode(&self.buffer[3..segment_size]); self.buffer.copy_within(segment_size..self.cur_index, 0); self.cur_index -= segment_size; return retval; } } None } #[inline] fn ensure_capacity(&mut self, add_len: usize) { if self.buffer.len() < self.cur_index + add_len { let mut new_buf = vec![0u8; self.cur_index + add_len]; new_buf[..self.cur_index].copy_from_slice(&self.buffer[..self.cur_index]); self.buffer = new_buf.into_boxed_slice(); } } } #[inline] fn read_length_field(buf: &[u8]) -> usize { buf[0] as usize | (buf[1] as usize) << 8 | (buf[2] as usize) << 16 }