pub struct AnyFetchObjectWriter { /* private fields */ }Expand description
Re-emitter for the frames of a fetch data stream, for any enabled draft.
The inverse of AnyFetchObjectReader, and it exists for one caller: a
relay reading one fetch stream and writing another from the same frames,
having removed some of them. Removing a frame changes what the frames
behind it are encoded against, and on drafts 15-19 nearly every field of
a fetch object is defined against the frame before it — draft-17
Section 10.4.4.1, Table 7: “Object ID is the prior Object’s ID plus one” —
so a survivor following a removed run cannot keep its original bytes.
§How it is driven
One writer belongs to one stream, and reemit_object
is called for every frame the caller forwards, in wire order, whether or
not anything has been removed yet. That call is what moves the writer, so a
forwarded frame it never saw leaves it a frame behind and re-encodes the
next survivor against the wrong predecessor. A frame the caller elides is
the one it is not called for — that is the whole of eliding.
§What it costs
Nothing on drafts 07-14, and on drafts 15-19 one header re-derivation per frame, which allocates only when the answer differs from the bytes that arrived. A stream with nothing removed from it therefore forwards every frame’s own bytes and copies no payload.
§Drafts 18 and 19 need the Group Order
Their Group ID is a difference whose sign the fetch’s Group Order decides,
exactly as for AnyFetchObjectReader, and it is settled on the control
plane rather than on the data stream. new takes it for that
reason: the wrong order re-encodes without error onto groups walking the
wrong way.
Implementations§
Source§impl AnyFetchObjectWriter
impl AnyFetchObjectWriter
Sourcepub fn new(
header: &AnyFetchHeader,
group_order: AnyFetchGroupOrder,
) -> Result<Self, CodecError>
pub fn new( header: &AnyFetchHeader, group_order: AnyFetchGroupOrder, ) -> Result<Self, CodecError>
Create a writer for a stream with the given header, whose groups are
written in group_order.
See the type’s own documentation for what the order is for and why it cannot be read off the stream. On drafts 07-17 the argument is ignored.
Returns CodecError::UnsupportedDraft for drafts not compiled in.
Sourcepub fn draft(&self) -> DraftVersion
pub fn draft(&self) -> DraftVersion
The draft this writer encodes.
Sourcepub fn reemit_object(
&mut self,
frame: &AnyFetchFrame,
raw: &[u8],
out: &mut impl BufMut,
) -> Result<FetchReemit, CodecError>
pub fn reemit_object( &mut self, frame: &AnyFetchFrame, raw: &[u8], out: &mut impl BufMut, ) -> Result<FetchReemit, CodecError>
Re-emit one forwarded fetch frame, re-encoding its framing against the frames actually forwarded before it, and advance.
frame came from AnyFetchObjectReader::read_object_frame on the
stream being read; raw is that frame’s wire bytes. The return value
says which bytes to forward, and the two answers are not symmetric:
FetchReemit::Unchanged writes nothing and means raw is still
correct, while FetchReemit::Reframed has written the whole frame to
out and raw must not also be forwarded.
§raw need not be a complete frame
Any prefix is legal provided the whole framing is present — the
framing being meta.wire_len - meta.payload_length bytes, which is a
number the frame already carries. Everything behind it is copied
byte-for-byte, however many bytes there are, and no length validation is
performed. That is what lets a caller fix up the first chunk of a frame
too large to buffer, where only the first chunk carries the framing at
all.
§Errors
CodecError::UnsupportedDraft when frame was read off another
draft’s stream.
CodecError::InvalidField when raw is shorter than the framing the
frame declares, and when the frame has no encoding against the
predecessor now in front of it — a Group ID that moves against the
Group Order, an Object ID that does not advance, and the arithmetic
overflows. The writer is left where it was in that case, so a caller
that gives up on one frame and carries on is not also one frame out.
Trait Implementations§
Source§impl Clone for AnyFetchObjectWriter
impl Clone for AnyFetchObjectWriter
Source§fn clone(&self) -> AnyFetchObjectWriter
fn clone(&self) -> AnyFetchObjectWriter
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more