pub struct FramedRecvStream {
inner: RecvStream,
buf: BytesMut,
draft: DraftVersion,
subgroup_io: Option<SubgroupObjectReader>,
fetch_io: Option<FetchObjectReader>,
tracking: Option<(TrackObjects, u64)>,
}Expand description
A framed reader for a recv stream. Handles MoQT varint-length decoding.
Fields§
§inner: RecvStream§buf: BytesMut§draft: DraftVersion§subgroup_io: Option<SubgroupObjectReader>Stateful subgroup object reader (tracks delta-decode state and extension-presence flag).
fetch_io: Option<FetchObjectReader>Stateful fetch object reader, holding the Object each following Object
may inherit its Group ID, Subgroup ID, Object ID and Priority from.
Seeded by FramedRecvStream::read_fetch_header.
tracking: Option<(TrackObjects, u64)>The record this stream’s objects are measured against, and the Group ID its header named.
One group for the whole stream: a subgroup header names it once and no
object header repeats it. None on a stream that was never given one -
a stream for an alias no live binding names, and every stream built
outside Connection::accept_subgroup_stream - and such a stream reads
exactly as it did before this existed.
Implementations§
Source§impl FramedRecvStream
impl FramedRecvStream
Sourcepub fn new(inner: RecvStream, draft: DraftVersion) -> Self
pub fn new(inner: RecvStream, draft: DraftVersion) -> Self
Create a new framed receive stream for the given draft version.
Sourcefn measure_objects_against(&mut self, objects: TrackObjects, group: u64)
fn measure_objects_against(&mut self, objects: TrackObjects, group: u64)
Measure this stream’s objects against objects, all of them in group.
Called by Connection::accept_subgroup_stream once the header has
been read, which is the only point at which both the track and the group
are known.
Sourcefn note_subgroup_object(
&self,
object: u64,
status: Option<u64>,
) -> Result<(), ConnectionError>
fn note_subgroup_object( &self, object: u64, status: Option<u64>, ) -> Result<(), ConnectionError>
Judge one object this stream carried against where its track ended.
The object’s Group ID is the stream’s and its Object ID is its own, already resolved from the delta the wire carries; what they are measured against is the end an end-of-track object settled on any stream.
Sourceasync fn fill(&mut self) -> Result<bool, ConnectionError>
async fn fill(&mut self) -> Result<bool, ConnectionError>
Read more data from the stream into the internal buffer.
Sourceasync fn ensure(&mut self, n: usize) -> Result<(), ConnectionError>
async fn ensure(&mut self, n: usize) -> Result<(), ConnectionError>
Ensure at least n bytes are available in the buffer.
Sourcepub async fn read_control(
&mut self,
capture_raw: bool,
) -> Result<(AnyControlMessage, Option<Vec<u8>>), ConnectionError>
pub async fn read_control( &mut self, capture_raw: bool, ) -> Result<(AnyControlMessage, Option<Vec<u8>>), ConnectionError>
Read a control message from the stream.
When capture_raw is true, the returned tuple includes a clone of the
framed wire bytes (for observer emission). When false, the second
element is None and the payload clone is skipped.
Sourcepub async fn read_subgroup_header(
&mut self,
) -> Result<AnySubgroupHeader, ConnectionError>
pub async fn read_subgroup_header( &mut self, ) -> Result<AnySubgroupHeader, ConnectionError>
Read a subgroup stream header. Also initializes the internal delta-decoding state.
Sourcepub async fn read_fetch_header(
&mut self,
) -> Result<AnyFetchHeader, ConnectionError>
pub async fn read_fetch_header( &mut self, ) -> Result<AnyFetchHeader, ConnectionError>
Read a fetch response header, and seed the object reader that follows it.
The seeding is what makes FramedRecvStream::read_fetch_object usable:
a draft-15 fetch object may leave out fields and take the prior Object’s,
so the objects of one stream have to be read through one reader and the
header is where that reader begins.
Sourcepub async fn read_subgroup_object(
&mut self,
) -> Result<SubgroupObject, ConnectionError>
pub async fn read_subgroup_object( &mut self, ) -> Result<SubgroupObject, ConnectionError>
Read the next draft-15 subgroup object from this stream. Uses
the stateful reader seeded by
FramedRecvStream::read_subgroup_header to decode the
delta-encoded object ID and (when the stream type says so) the
extension block. Returns an error if called before a subgroup
header was read.
Errors with ConnectionError::ExtensionsOnNonNormalStatus on an
Object that carries extension headers on a status other than Normal,
which draft-15 Section 10.2.1.2 answers with a session close. The Object
is consumed from the stream before the check, so the reader stays in
step with the wire and a caller that reports the violation and reads on
sees the following Object rather than a re-parse of this one.
Sourcepub async fn read_fetch_stream_header(
&mut self,
) -> Result<FetchHeader, ConnectionError>
pub async fn read_fetch_stream_header( &mut self, ) -> Result<FetchHeader, ConnectionError>
Read the next draft-15 fetch header from this stream.
The typed twin of read_fetch_header, and it
has to do the same two things that one does.
It seeds the object reader, because the two consume the same bytes: a
version that left fetch_io unset would put the stream in a state no
caller can leave, with the next
read_fetch_object returning its
fetch header not read yet refusal about a header this method has just
read, and the bytes it would need already spent.
It fills before decoding, and treats a varint that ran out of buffer as
a short read rather than a malformed header. FetchHeader::decode
reports that as CodecError::VarInt(VarIntError::UnexpectedEnd) where
AnyFetchHeader reports a bare CodecError::UnexpectedEnd, so a loop
matching only the latter never reaches its own fill — and since the
buffer starts empty, that is every first call on a fresh stream.
Sourcepub async fn read_fetch_object(
&mut self,
) -> Result<(FetchObjectHeader, Vec<u8>), ConnectionError>
pub async fn read_fetch_object( &mut self, ) -> Result<(FetchObjectHeader, Vec<u8>), ConnectionError>
Read the next draft-15 fetch object’s header and payload.
The mirror of FramedSendStream::write_fetch_object, and it needs the
same state that one needs: draft-15 lets an Object leave out its Group
ID, Subgroup ID, Object ID and Priority and take the prior Object’s, so
the reader carries the prior Object and this method is refused before
FramedRecvStream::read_fetch_header has seeded it.
The header that comes back is resolved — every field is a value rather than an inheritance — which is what makes draft-15 and draft-18 different from the three drafts either side of them.
The payload comes back with the header because payload_length says how
many bytes follow it, and a reader that takes the wrong number of them
desynchronises every later object on the stream.
§Errors
ConnectionError::DataStreamState when no fetch header has been read,
ConnectionError::UnexpectedEnd when the stream ends inside the header
or inside the payload it declared, and ConnectionError::Codec on
every rule Section 10.4.4 states about the flags and about an Object that
inherits from one that does not exist.
Sourceasync fn read_object_payload(
&mut self,
length: &VarInt,
) -> Result<Vec<u8>, ConnectionError>
async fn read_object_payload( &mut self, length: &VarInt, ) -> Result<Vec<u8>, ConnectionError>
Take the length payload bytes that follow a fetch object’s header.
Separate from the header read because the header is decoded from a probe cursor that may have to be retried after a fill, and the payload is a flat byte count that never is.
Sourcepub fn draft(&self) -> DraftVersion
pub fn draft(&self) -> DraftVersion
Returns the draft version this stream is framed for.