pub struct FetchObjectReader { /* private fields */ }Expand description
Stateful reader/writer for the objects on one draft-15 fetch stream.
Holds the fields of the object last read or written, which is what the next object’s Serialization Flags may refer to. One reader belongs to one stream: draft-15 Section 10.4.4 counts “the prior Object” along the stream, so sharing a reader between streams, or restarting one mid-stream, resolves later objects onto the wrong group, subgroup, ID or priority without producing an error anywhere.
A fresh reader has no prior object, which is exactly the state in which the
draft’s protocol violation applies — see
FetchObjectHeader::references_prior_object.
Implementations§
Source§impl FetchObjectReader
impl FetchObjectReader
Sourcepub fn read_object_header(
&mut self,
buf: &mut impl Buf,
) -> Result<FetchObjectHeader, CodecError>
pub fn read_object_header( &mut self, buf: &mut impl Buf, ) -> Result<FetchObjectHeader, CodecError>
Decode the next object’s framing, leaving its payload in buf.
Consumes the Serialization Flags byte, whichever of the Group ID, Subgroup ID, Object ID, Priority and Extensions fields that byte says are present, the Object Payload Length, and the Object Status when that length is zero. The declared payload bytes are left where they are, so a caller can forward them without a copy; skipping them is the caller’s job, and skipping the wrong number of them desynchronises every later object on the stream.
Errors with CodecError::InvalidField when the flags set either bit
draft-15 Section 10.4.4, Table 8 leaves unassigned, when the stream’s
first object inherits from an object that does not exist, when an
inherited value cannot be represented, or when the Object Status is a
code the draft does not assign.
Sourcepub fn write_object_header(
&mut self,
header: &FetchObjectHeader,
buf: &mut impl BufMut,
) -> Result<(), CodecError>
pub fn write_object_header( &mut self, header: &FetchObjectHeader, buf: &mut impl BufMut, ) -> Result<(), CodecError>
Serialize an object’s framing, leaving its payload to the caller.
Writes exactly the fields header.serialization_flags announces, and
stops after the Object Payload Length — or, when that length is zero,
after the Object Status. The caller appends payload_length payload
bytes; the length is already on the wire by then, so appending a
different number of them frames an object no reader can parse.
The flags are taken as the authority on what reaches the wire, which
means a header whose resolved fields disagree with its own flags cannot
be written faithfully. Every such disagreement is refused with
CodecError::InvalidField rather than resolved:
- a field the flags omit whose value is not the one the omission implies — a Group ID that is not the prior object’s, a Subgroup ID that is not what the two-bit encoding resolves to, an Object ID that is not the prior object’s plus one, a Priority that is not the prior object’s. Written anyway, each would arrive as the value the flags imply, and the object the peer sees would be a different object.
- extension bytes with the extensions bit clear, which would be dropped in silence. Draft-15 Section 10.2.1.2 requires relays to forward extensions they do not understand unchanged, so dropping them is not a smaller loss than mis-stating an ID.
- a status other than
ObjectStatus::Normalon an object with a non-zero payload length. Section 10.4.4 puts the status field on the wire only when that length is zero, and Section 10.2.1.1 the conformance side: “Any object with a status code other than zero MUST have an empty payload.” There is no such object to write.ObjectStatus::Normalalongside a payload is not that case and is accepted: it is the status the encoding elides for every object that carries bytes, so stating it asks for exactly the bytes leaving it out asks for.
Not refused: extension bytes on an object whose resolved status is not
ObjectStatus::Normal, which Section 10.2.1.2 forbids. As on a
subgroup stream this is the only writer a fetch object has, and the
frame encodes and reads back exactly, so refusing it would cost the
ability to reproduce a capture rather than prevent anything.
Also refused: flags setting either bit Table 8 leaves unassigned, and a first object on the stream that inherits from an object that does not exist.
Every check runs before a byte is written, so a refused header leaves
buf untouched rather than half an object the next write would run
into, and leaves the reader’s prior-object state as it was.
Trait Implementations§
Source§impl Clone for FetchObjectReader
impl Clone for FetchObjectReader
Source§fn clone(&self) -> FetchObjectReader
fn clone(&self) -> FetchObjectReader
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more