pub struct Checksummed<F, C> { /* private fields */ }Expand description
A framer decorator that appends and verifies a checksum trailer.
§Example
use wire_codec::checksum::Crc32;
use wire_codec::framing::{Checksummed, Endian, Framer, LengthPrefixed, LengthWidth};
use wire_codec::{Error, WriteBuf};
let inner = LengthPrefixed::bounded(LengthWidth::U16, Endian::Big);
let framer = Checksummed::new(inner, Crc32, Endian::Little);
let mut out = [0u8; 32];
let mut buf = WriteBuf::new(&mut out);
framer.write_frame(b"ping", &mut buf).unwrap();
let n = buf.position();
assert_eq!(n, 2 + 4 + 4); // prefix + payload + CRC-32
let frame = framer.next_frame(&out[..n]).unwrap().unwrap();
assert_eq!(frame.payload(), b"ping");
assert_eq!(frame.consumed(), n);
out[3] ^= 0x01; // flip one payload bit in transit
assert_eq!(framer.next_frame(&out[..n]), Err(Error::ChecksumMismatch));Implementations§
Source§impl<F: Framer, C: Checksum> Checksummed<F, C>
impl<F: Framer, C: Checksum> Checksummed<F, C>
Sourcepub const fn new(inner: F, checksum: C, endian: Endian) -> Self
pub const fn new(inner: F, checksum: C, endian: Endian) -> Self
Wrap inner, appending checksum in endian byte order. The
checksum covers the whole inner frame (ChecksumScope::Frame).
Sourcepub const fn with_scope(self, scope: ChecksumScope) -> Self
pub const fn with_scope(self, scope: ChecksumScope) -> Self
Choose which bytes the checksum covers.
Sourcepub const fn scope(&self) -> ChecksumScope
pub const fn scope(&self) -> ChecksumScope
Which bytes the checksum covers.
Trait Implementations§
impl<F: Copy, C: Copy> Copy for Checksummed<F, C>
impl<F: Eq, C: Eq> Eq for Checksummed<F, C>
Source§impl<F: Framer, C: Checksum> Framer for Checksummed<F, C>
impl<F: Framer, C: Checksum> Framer for Checksummed<F, C>
Source§fn next_frame<'a>(&self, input: &'a [u8]) -> Result<Option<Frame<'a>>>
fn next_frame<'a>(&self, input: &'a [u8]) -> Result<Option<Frame<'a>>>
Extract an inner frame and verify the trailer that follows it.
§Errors
Error::ChecksumMismatchif the trailer does not match.- Any error from the inner framer.
Source§fn write_frame(&self, payload: &[u8], out: &mut WriteBuf<'_>) -> Result<()>
fn write_frame(&self, payload: &[u8], out: &mut WriteBuf<'_>) -> Result<()>
Write the inner frame followed by the checksum trailer.
§Errors
Error::BufferFullifoutcannot hold the frame and trailer. When the inner framer reportsFramer::max_frame_len(every built-in framer does, exactly), that bound plus the trailer is checked before anything is written.- Any error from the inner framer.
Because the room is checked first, a short buffer is reported as
Error::BufferFull even when the inner framer would also reject
the payload (with Error::FrameTooLarge or
Error::DelimiterInPayload, say); given enough room, the inner
framer’s error is returned instead.
The cursor is unchanged on error. With a built-in inner framer nothing is written either. With a custom inner framer that reports no size bound, a trailer that does not fit can leave the inner frame’s bytes behind the (restored) cursor.
Source§fn next_frame_from<'a>(
&self,
input: &'a [u8],
scanned: &mut usize,
) -> Result<Option<Frame<'a>>>
fn next_frame_from<'a>( &self, input: &'a [u8], scanned: &mut usize, ) -> Result<Option<Frame<'a>>>
Resumable variant: forwards the progress hint to the inner framer.
§Errors
Same contract as Framer::next_frame for this type.
Source§fn max_frame_len(&self, payload_len: usize) -> Option<usize>
fn max_frame_len(&self, payload_len: usize) -> Option<usize>
Framer::write_frame writes for
a payload of payload_len bytes. Read more