/// Dissolve the frame decoder, returning any excess data. pub(crate) fn dissolve(self) -> Vec<u8> { self.data
}
/// The required number of bytes for the decoder to decode a full frame. /// /// Note: An efficient implementation may always provide more than the required amount of bytes, /// if already available. pub(crate) fn required_length(&self) -> usize {
LENGTH.saturating_sub(self.data.len())
}
/// Add chunks to the decoder's stream of data. pub(crate) fn add_chunks(&mutself, chunks: &[&[u8]]) { for chunk in chunks { self.data.extend_from_slice(chunk);
}
}
/// Get the next frame from the decoder, passing through a transformation step (e.g. to avoid /// copying) if available. pub(crate) fn next_and_then<TFrame, F: FnOnce(&[u8; LENGTH]) -> TFrame>(
&mutself,
map_fn: F,
) -> Option<TFrame> { ifself.data.len() < LENGTH { return None;
}
Some(map_fn( self.data
.drain(..LENGTH)
.as_slice()
.try_into()
.expect("self.data must contain LENGTH bytes"),
))
}
} impl<const LENGTH: usize> fmt::Debug for FixedLengthFrameDecoder<LENGTH> { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct(Self::NAME)
.field("data", &format_args!("length={}", self.data.len()))
.field("required_length()", &self.required_length())
.finish()
}
}
/// An arbitrary fixed-size frame delimiter, decoding itself to yield the length of a frame. pub(crate) trait FrameDelimiter<const LENGTH: usize> { const LENGTH: usize;
/// Decode the frame delimiter and return the length of the frame fn decode(data: [u8; LENGTH]) -> usize;
}
/// [`u16`] little endian length delimiter. pub(crate) struct U16LittleEndianDelimiter;
/// [`u32`] little endian length delimiter. pub(crate) struct U32LittleEndianDelimiter;
/// Contains a stream of data and hands out individual variable length frames, one by one. #[derive(Name)] pub(crate) struct VariableLengthFrameDecoder< const DELIMETER_LENGTH: usize,
TDelimiter: FrameDelimiter<DELIMETER_LENGTH>,
> {
delimiter: PhantomData<TDelimiter>,
state: VariableLengthFrameDecoderState,
data: Vec<u8>,
} impl<const DELIMETER_LENGTH: usize, TDelimiter: FrameDelimiter<DELIMETER_LENGTH>>
VariableLengthFrameDecoder<DELIMETER_LENGTH, TDelimiter>
{ const LENGTH: usize = DELIMETER_LENGTH;
/// Create a frame decoder using a [`FrameDelimiter`] to decode the length of frames with `data` /// being the initial data. pub(crate) fn new(data: Vec<u8>) -> Self { Self {
delimiter: PhantomData,
state: VariableLengthFrameDecoderState::PartialDelimiter,
data,
}
}
/// The required number of bytes for the decoder to advance its internal state. /// /// Note: An efficient implementation may always provide more than the required amount of bytes, /// if already available. pub(crate) fn required_length(&self) -> usize { match &self.state {
VariableLengthFrameDecoderState::PartialDelimiter => Self::LENGTH.saturating_sub(self.data.len()),
VariableLengthFrameDecoderState::PartialFrame { length } => {
length.saturating_sub(self.data.len())
},
}
}
/// Add chunks to the decoder's stream of data and return the amount of data that is currently /// buffered. pub(crate) fn add_chunks(&mutself, chunks: &[&[u8]]) -> usize { for chunk in chunks { self.data.extend_from_slice(chunk);
} self.data.len()
}
/// Dissolve the frame decoder, returning any excess data. #[expect(dead_code, reason = "Will use later")] pub(crate) fn dissolve(self) -> Vec<u8> { self.data
}
/// Get the next frame from the decoder, passing through a transformation step (e.g. to avoid /// copying) if available. pub(crate) fn next_frame_and_then<TResult, F: FnOnce(&[u8]) -> TResult>(
&mutself,
map_fn: F,
) -> Option<TResult> where
[(); DELIMETER_LENGTH]:,
{ iflet VariableLengthFrameDecoderState::PartialDelimiter = &self.state { // Check if we have sufficient bytes to decode the limiter or wait for more let delimiter = self.data.get(..DELIMETER_LENGTH)?;
// Decode the delimiter to retrieve the length let delimiter: [u8; DELIMETER_LENGTH] = delimiter
.try_into()
.expect("[0..DELIMETER_LENGTH] must be DELIMETER_LENGTH bytes"); let length = TDelimiter::decode(delimiter);
// Drain the delimiter and move into the next state let _ = self.data.drain(..DELIMETER_LENGTH); self.state = VariableLengthFrameDecoderState::PartialFrame { length };
}
iflet VariableLengthFrameDecoderState::PartialFrame { length } = &self.state { ifself.data.len() < *length { // We have less data than what our frame needs. Wait for more. return None;
}
// The chunk contains more than or exactly what our frame needs. Drain the frame data // and move into the next state with the remaining data. let frame = map_fn(self.data.drain(..*length).as_slice()); self.state = VariableLengthFrameDecoderState::PartialDelimiter; return Some(frame);
}
unreachable!("All decoder states should have been handled at this point");
}
} impl<const DELIMETER_LENGTH: usize, TDelimiter: FrameDelimiter<DELIMETER_LENGTH>> fmt::Debug for VariableLengthFrameDecoder<DELIMETER_LENGTH, TDelimiter>
{ fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct(Self::NAME)
.field("state", &self.state)
.field("data", &format_args!("length={}", self.data.len()))
.finish()
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.37 Sekunden
(vorverarbeitet am 2026-06-22)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.