Skip to main content

reemit_subgroup_object

Function reemit_subgroup_object 

Source
pub fn reemit_subgroup_object(
    draft: DraftVersion,
    prev_forwarded: Option<u64>,
    object_id: u64,
    raw: &[u8],
    out: &mut impl BufMut,
) -> Result<Reemit, CodecError>
Expand description

Re-emit a subgroup object whose wire bytes are already known, adjusting only this draft’s encoding of its identity.

This is the whole of what removing an object from a subgroup stream costs. Drafts 07-13 encode absolute Object IDs, so every survivor’s bytes are already correct and this copies raw unchanged after checking that IDs still increase. Drafts 14-19 encode id - prev - 1, so the leading varint is recomputed against prev_forwarded; when its minimal encoding is byte-identical to the one in raw the bytes are still copied unchanged. Everything after the ID field — extension block, length, status, payload — is always copied verbatim.

After one object is re-emitted following an elided run, the writer’s cursor re-converges with the reader’s, so every later object’s original bytes remain correct. An elide therefore costs at most one fix-up, not a re-encode of the stream’s tail.

prev_forwarded is the absolute Object ID of the last object actually forwarded on this stream, or None when none has been.

§raw need not be a complete object

Any prefix is legal provided the whole leading Object ID field is present. Everything after that field is copied byte-for-byte, however many bytes there are, and no length validation is performed — this function never reads the extension block, never reads the payload length field and never compares it to raw.len(). It cannot: on drafts 07-13 it does not decode past the ID at all, and on 14-19 it decodes exactly one varint.

This is what lets a caller fix up the first chunk of an oversized object — an object too large to buffer is forwarded in chunks, and only the first one carries the ID field. A caller that cannot guarantee the ID field is whole in the chunk it passes gets CodecError::InvalidField rather than a silent truncation.

Do not add a completeness check. A raw.len() >= wire_len assertion would look defensive, would pass every test that feeds it whole objects, and would refuse the prefix this function exists to accept.

§Errors

CodecError::InvalidField when object_id is not strictly greater than prev_forwarded, when the recomputed delta exceeds the varint range, or when raw does not begin with a decodable varint — which includes a raw too short to hold the whole leading varint.

§Examples

use moqtap_codec::dispatch::{reemit_subgroup_object, Reemit};
use moqtap_codec::version::DraftVersion;

// A draft-19 object that was encoded as the successor of ID 4 —
// leading delta 0 — re-emitted after ID 3 was the last one forwarded.
let raw = [0x00, 0x02, 0xca, 0xfe];
let mut out = Vec::new();
let what = reemit_subgroup_object(DraftVersion::Draft19, Some(3), 5, &raw, &mut out).unwrap();
assert_eq!(what, Reemit::Reencoded { id_bytes_before: 1, id_bytes_after: 1 });
assert_eq!(out, [0x01, 0x02, 0xca, 0xfe]);