Skip to main content

FetchObjectReader

Struct FetchObjectReader 

Source
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

Source

pub fn new() -> Self

Build a reader for the objects following a fetch stream’s header.

Source

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.

Source

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::Normal on 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::Normal alongside 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

Source§

fn clone(&self) -> FetchObjectReader

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for FetchObjectReader

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for FetchObjectReader

Source§

fn default() -> FetchObjectReader

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.