pub struct MoqTraceReader<R: Read> {
inner: PeekReader<R>,
header: TraceHeader,
version: u32,
faulted: bool,
}Expand description
Streaming reader for .moqtrace files.
Validates the preamble and parses the first segment’s header on
construction. Use read_event, or the iterator it
backs, for code that does not care about segment boundaries — it advances
through them silently. Use read_next to see them.
Fields§
§inner: PeekReader<R>§header: TraceHeader§version: u32§faulted: boolSet when a segment header could not be built, and the stream is therefore parked on the events of a segment there is no header for.
Nothing may be decoded from that position under
header, which still describes the segment
before it: those events belong to a segment this reader could not read,
and handing them back under the previous segment’s header presents that
segment as read under a header the file never gave it. Because "n"
and "t" are segment-local and global order is (segment.sequence, n), it also misorders every event so recovered, silently.
The next read resynchronizes to the next segment instead. See
read_next.
Implementations§
Source§impl<R: Read> MoqTraceReader<R>
impl<R: Read> MoqTraceReader<R>
Sourcepub fn new(reader: R) -> Result<Self, MoqTraceError>
pub fn new(reader: R) -> Result<Self, MoqTraceError>
Open a reader, validating the preamble and parsing the first segment’s header.
Sourcepub fn header(&self) -> &TraceHeader
pub fn header(&self) -> &TraceHeader
The current segment’s header.
After a segment header this reader could not build — reported once by
read_next — this still names the last segment that
was read, until the next read reaches the segment after the fault.
No event is handed back under it in the meantime, which is the property
that matters: the header a caller holds always belongs to the events it
has been given.
Sourcepub fn read_next(&mut self) -> Result<Option<ReadItem>, MoqTraceError>
pub fn read_next(&mut self) -> Result<Option<ReadItem>, MoqTraceError>
Read the next item: an event in the current segment, or the header of a segment that starts here.
Returns Ok(None) at a clean end of file. A stream that stops
part-way through an item yields MoqTraceError::Truncated instead,
which names the offset the incomplete item began at; everything
returned before it stands.
§A segment header this reader cannot build
The error is returned once, and the segment it names is skipped whole:
the next call resynchronizes to the segment after it, exactly as
resync_to_next_segment would, and
reports it as a ReadItem::Segment like any other.
Reading on from where the bad preamble left off is the one thing that
must not happen. The preamble is consumed before the header is built,
so the stream is parked on the next segment’s events with no header
for them; decoding them leaves the previous segment’s header standing,
and SPEC.md is explicit that a reader “MUST report it and MUST NOT
present the segment as read”. Handing back its events under the
previous header presents it as read and gets the header wrong, and
since "n" and "t" are segment-local while global order is
(segment.sequence, n), every event so recovered is also misordered —
with nothing in the returned values to say so. A caller that keeps only
the Oks of the iterator sees no fault at all.
Skipping rather than refusing to go on matches the JavaScript reader’s
recover path over the same file, and leaves both idioms honest: a
collect::<Result<Vec<_>, _>>() still stops at the error, and a caller
that filters errors out gets the segments it can trust and none of the
events from the one it cannot.
Sourcepub fn read_event(&mut self) -> Result<Option<TraceEvent>, MoqTraceError>
pub fn read_event(&mut self) -> Result<Option<TraceEvent>, MoqTraceError>
Read the next event, advancing through segment boundaries silently.
header tracks the segment the event came from.
Returns Ok(None) only at a clean end of file.
Sourcepub fn resync_to_next_segment(
&mut self,
) -> Result<Option<TraceHeader>, MoqTraceError>
pub fn resync_to_next_segment( &mut self, ) -> Result<Option<TraceHeader>, MoqTraceError>
Scan forward to the next segment and resume there, returning its
header — or Ok(None) if the stream ends before one is found.
This is the recovery path a segmented trace exists to offer: after a
Truncated or a decode error, the current
segment is unreadable from that point on, but the segments after it
are intact and independently parseable. Everything skipped is
discarded — the bytes between the failure and the next segment are the
corrupt region.
A header this reader cannot build is one of those failures rather than a way out of one: if the segment found here has one, the error is returned and the segment after it is where the next read picks up.
Sourcepub fn into_event_iter(self) -> MoqTraceEventIterator<R> ⓘ
pub fn into_event_iter(self) -> MoqTraceEventIterator<R> ⓘ
Iterate over events, advancing through segment boundaries silently.
Sourcepub fn into_item_iter(self) -> MoqTraceItemIterator<R> ⓘ
pub fn into_item_iter(self) -> MoqTraceItemIterator<R> ⓘ
Iterate over items — events and segment boundaries both.
Trait Implementations§
Source§impl<R: Read> IntoIterator for MoqTraceReader<R>
Yields events, advancing through segment boundaries silently.
impl<R: Read> IntoIterator for MoqTraceReader<R>
Yields events, advancing through segment boundaries silently.