o_sfu_rfc/
stream_decoder.rs1use std::{collections::VecDeque, io::Result as IoResult, marker::PhantomData};
5
6pub(crate) const DECODER_CHUNK_SIZE: usize = 4096;
7
8pub type Decoded<Frame, Error> = Option<Result<(Frame, usize), Error>>;
9
10pub trait FrameCodec {
12 type Frame;
13 type Error;
14
15 fn try_decode(unread: &[u8]) -> Decoded<Self::Frame, Self::Error>;
17}
18
19pub struct StreamDecoder<C> {
27 bytes: VecDeque<u8>,
28 codec: PhantomData<C>,
29}
30
31impl<C> Default for StreamDecoder<C> {
32 fn default() -> Self {
33 Self {
34 bytes: VecDeque::new(),
35 codec: PhantomData,
36 }
37 }
38}
39
40impl<C: FrameCodec> StreamDecoder<C> {
41 #[must_use]
42 pub fn new() -> Self {
43 Self::default()
44 }
45
46 pub fn feed_with(&mut self, f: impl FnOnce(&mut [u8]) -> IoResult<usize>) -> IoResult<usize> {
55 let slice_start = self.bytes.len();
56 self.bytes.resize(slice_start + DECODER_CHUNK_SIZE, 0);
57 let slice = self
58 .bytes
59 .make_contiguous()
60 .get_mut(slice_start..)
61 .unwrap_or_default();
62 let result = f(slice);
63 self.bytes
64 .truncate(slice_start + result.as_ref().map_or(0, |&count| count));
65 result
66 }
67}
68
69impl<C: FrameCodec> Iterator for StreamDecoder<C> {
70 type Item = Result<C::Frame, C::Error>;
71
72 fn next(&mut self) -> Option<Self::Item> {
73 let decoded = C::try_decode(self.bytes.make_contiguous())?;
74 Some(decoded.map(|(frame, length)| {
75 self.bytes.drain(..length);
76 frame
77 }))
78 }
79}