pub fn frame_for_stream(body: &[u8], out: &mut Vec<u8>) {
let mut len = body.len() as u64;
loop {
let mut byte = (len & 0x7f) as u8;
len >>= 7;
if len != 0 {
byte |= 0x80;
}
out.push(byte);
if len == 0 {
break;
}
}
out.extend_from_slice(body);
}
#[derive(Default)]
pub struct StreamDeframer {
buf: Vec<u8>,
start: usize,
}
impl StreamDeframer {
pub fn new() -> Self {
Self::default()
}
pub fn push(&mut self, bytes: &[u8]) {
self.buf.extend_from_slice(bytes);
}
pub fn is_empty(&self) -> bool {
self.start >= self.buf.len()
}
pub fn pending(&self) -> usize {
self.buf.len() - self.start
}
pub fn drain_frames(&mut self, mut f: impl FnMut(&[u8])) -> usize {
let mut count = 0;
loop {
let Some((len, header)) = read_uvarint(&self.buf[self.start..]) else {
break; };
let body_start = self.start + header;
let Some(body_end) = body_start.checked_add(len as usize) else {
break;
};
if body_end > self.buf.len() {
break; }
f(&self.buf[body_start..body_end]);
self.start = body_end;
count += 1;
}
if self.start > 0 {
self.buf.drain(0..self.start);
self.start = 0;
}
count
}
}
fn read_uvarint(buf: &[u8]) -> Option<(u64, usize)> {
let mut value = 0u64;
let mut shift = 0u32;
for (i, &b) in buf.iter().enumerate() {
value |= u64::from(b & 0x7f) << shift;
if b & 0x80 == 0 {
return Some((value, i + 1));
}
shift += 7;
if shift >= 64 {
return None; }
}
None
}
#[cfg(test)]
mod tests {
use super::*;
fn frame_all(bodies: &[&[u8]]) -> Vec<u8> {
let mut out = Vec::new();
for b in bodies {
frame_for_stream(b, &mut out);
}
out
}
fn collect(deframer: &mut StreamDeframer) -> Vec<Vec<u8>> {
let mut got = Vec::new();
deframer.drain_frames(|body| got.push(body.to_vec()));
got
}
#[test]
fn whole_stream_at_once() {
let stream = frame_all(&[b"hello", b"", b"world!!", &[0u8, 255, 7]]);
let mut d = StreamDeframer::new();
d.push(&stream);
let got = collect(&mut d);
assert_eq!(got, vec![b"hello".to_vec(), b"".to_vec(), b"world!!".to_vec(), vec![0, 255, 7]]);
assert!(d.is_empty(), "fully consumed at a frame boundary");
}
#[test]
fn byte_at_a_time_arrival() {
let bodies: Vec<Vec<u8>> = (0..20).map(|i| vec![i as u8; (i % 5) + 1]).collect();
let refs: Vec<&[u8]> = bodies.iter().map(|b| b.as_slice()).collect();
let stream = frame_all(&refs);
let mut d = StreamDeframer::new();
let mut got = Vec::new();
for &byte in &stream {
d.push(&[byte]);
d.drain_frames(|body| got.push(body.to_vec()));
}
assert_eq!(got, bodies, "every frame reassembled exactly, in order");
assert!(d.is_empty());
}
#[test]
fn frame_split_across_chunks_mid_body_and_mid_length() {
let big = vec![0xABu8; 5000]; let stream = frame_all(&[b"a", big.as_slice(), b"z"]);
let mut d = StreamDeframer::new();
let cut1 = 2 + 1; d.push(&stream[..cut1]);
assert_eq!(collect(&mut d), vec![b"a".to_vec()], "only the complete first frame");
let cut2 = cut1 + 2500;
d.push(&stream[cut1..cut2]);
assert_eq!(collect(&mut d), Vec::<Vec<u8>>::new(), "big body incomplete → nothing yet");
assert!(d.pending() > 0, "the partial big frame is buffered");
d.push(&stream[cut2..]);
assert_eq!(collect(&mut d), vec![big.clone(), b"z".to_vec()], "big + trailing frame complete");
assert!(d.is_empty());
}
#[test]
fn empty_and_no_complete_frame() {
let mut d = StreamDeframer::new();
assert_eq!(collect(&mut d), Vec::<Vec<u8>>::new(), "no bytes → nothing");
d.push(&[0x80]); assert_eq!(collect(&mut d), Vec::<Vec<u8>>::new(), "incomplete length → wait");
assert_eq!(d.pending(), 1);
d.push(&[0x01, b'X']); assert_eq!(collect(&mut d), Vec::<Vec<u8>>::new(), "length completes but body not arrived");
}
#[test]
fn end_to_end_zero_copy_stream_read() {
use crate::concurrency::marshal::{message_to_wire, view_message};
use crate::interpreter::RuntimeValue;
let m1 = message_to_wire("p", &RuntimeValue::Int(11)).unwrap();
let m2 = message_to_wire("p", &RuntimeValue::Int(22)).unwrap();
let m3 = message_to_wire("p", &RuntimeValue::Int(33)).unwrap();
let stream = frame_all(&[&m1, &m2, &m3]);
let mut d = StreamDeframer::new();
let mut ints = Vec::new();
for chunk in stream.chunks(7) {
d.push(chunk);
d.drain_frames(|frame| {
let v = view_message(frame).expect("frame opens as a view in place");
ints.push(v.as_int().expect("reads the int with no full decode"));
});
}
assert_eq!(ints, vec![11, 22, 33], "every streamed message read zero-copy, in order");
}
}