pub struct LengthPrefixed { /* private fields */ }Expand description
Length-prefixed framer.
§Example
use wire_codec::WriteBuf;
use wire_codec::framing::{Endian, Framer, LengthPrefixed, LengthWidth};
let framer = LengthPrefixed::unbounded(LengthWidth::U16, Endian::Big);
let mut out = [0u8; 16];
let mut buf = WriteBuf::new(&mut out);
framer.write_frame(b"hello", &mut buf).unwrap();
let written = buf.position();
assert_eq!(&out[..written], &[0x00, 0x05, b'h', b'e', b'l', b'l', b'o']);
let frame = framer.next_frame(&out[..written]).unwrap().unwrap();
assert_eq!(frame.payload(), b"hello");
assert_eq!(frame.consumed(), 7);Implementations§
Source§impl LengthPrefixed
impl LengthPrefixed
Sourcepub const DEFAULT_MAX_PAYLOAD: u64
pub const DEFAULT_MAX_PAYLOAD: u64
Payload limit applied by LengthPrefixed::bounded: 8 MiB.
Matches the default of tokio_util::codec::LengthDelimitedCodec.
Sourcepub const fn new(width: LengthWidth, endian: Endian) -> Self
👎Deprecated since 1.2.0: unbounded: the payload limit is the prefix maximum (4 GiB for U32). Use LengthPrefixed::bounded or LengthPrefixed::bounded_to for peer input, or LengthPrefixed::unbounded to keep this behaviour
pub const fn new(width: LengthWidth, endian: Endian) -> Self
unbounded: the payload limit is the prefix maximum (4 GiB for U32). Use LengthPrefixed::bounded or LengthPrefixed::bounded_to for peer input, or LengthPrefixed::unbounded to keep this behaviour
Build an unbounded framer using the given prefix width and endianness.
Warning: the payload limit is the largest value the prefix can
encode: 4 GiB for LengthWidth::U32, and for LengthWidth::U64
everything addressable. A peer that sends a large prefix and then
trickles bytes makes a streaming reader (tokio_util::codec::Framed,
StreamDecoder) buffer toward that
size. Use LengthPrefixed::bounded (8 MiB) or
LengthPrefixed::bounded_to for input from untrusted peers, and
LengthPrefixed::unbounded where the full range is really wanted.
new becomes bounded in 2.0.
§Example
use wire_codec::framing::{Endian, LengthPrefixed, LengthWidth};
let framer = LengthPrefixed::new(LengthWidth::U32, Endian::Big);
assert_eq!(framer.max_payload(), u64::from(u32::MAX));Sourcepub const fn unbounded(width: LengthWidth, endian: Endian) -> Self
pub const fn unbounded(width: LengthWidth, endian: Endian) -> Self
Build a framer whose payload limit is the largest value the prefix
can encode: the behaviour of new before 1.2.0, under a name that
says so.
Only for input whose size is already bounded by other means (a
trusted local file, a transport that caps frames itself). For peer
input use LengthPrefixed::bounded or
LengthPrefixed::bounded_to.
§Example
use wire_codec::framing::{Endian, LengthPrefixed, LengthWidth};
let framer = LengthPrefixed::unbounded(LengthWidth::U16, Endian::Big);
assert_eq!(framer.max_payload(), 65_535);Sourcepub const fn bounded_to(width: LengthWidth, endian: Endian, max: u64) -> Self
pub const fn bounded_to(width: LengthWidth, endian: Endian, max: u64) -> Self
Build a framer capped at max payload bytes (or the width’s own
maximum, if smaller). Equivalent to
LengthPrefixed::unbounded(width, endian).with_max_payload(max).
§Example
use wire_codec::framing::{Endian, Framer, LengthPrefixed, LengthWidth};
use wire_codec::Error;
let framer = LengthPrefixed::bounded_to(LengthWidth::U32, Endian::Big, 1024);
assert_eq!(framer.max_payload(), 1024);
assert!(matches!(
framer.next_frame(&[0, 0, 0x10, 0]),
Err(Error::FrameTooLarge { .. })
));Sourcepub const fn bounded(width: LengthWidth, endian: Endian) -> Self
pub const fn bounded(width: LengthWidth, endian: Endian) -> Self
Build a framer capped at LengthPrefixed::DEFAULT_MAX_PAYLOAD
payload bytes (or the width’s own maximum, if smaller).
This is the recommended constructor for input from untrusted peers.
§Example
use wire_codec::framing::{Endian, LengthPrefixed, LengthWidth};
let framer = LengthPrefixed::bounded(LengthWidth::U32, Endian::Big);
assert_eq!(framer.max_payload(), LengthPrefixed::DEFAULT_MAX_PAYLOAD);
// A u16 prefix cannot describe more than 65 535 bytes anyway.
let small = LengthPrefixed::bounded(LengthWidth::U16, Endian::Big);
assert_eq!(small.max_payload(), 65_535);Sourcepub const fn with_max_payload(self, max: u64) -> Self
pub const fn with_max_payload(self, max: u64) -> Self
Override the payload size limit enforced when reading and writing frames.
The limit is clamped to LengthWidth::max_payload of the configured
width.
§Example
use wire_codec::framing::{Endian, LengthPrefixed, LengthWidth};
let framer = LengthPrefixed::unbounded(LengthWidth::U8, Endian::Big).with_max_payload(1_000);
assert_eq!(framer.max_payload(), 255);Sourcepub const fn with_length_adjustment(self, adjustment: i64) -> Self
pub const fn with_length_adjustment(self, adjustment: i64) -> Self
Set the length adjustment: the payload length is the prefix value
plus adjustment.
The default is 0 (the prefix counts exactly the payload bytes). When
the prefix counts its own bytes as well, use -(header_size); when it
counts a fixed trailer that the caller handles separately, use the
trailer size. This mirrors length_adjustment in
tokio_util::codec::LengthDelimitedCodec.
On decode, a prefix that adjusts to a negative length yields
Error::InvalidLengthPrefix. On encode, a payload whose adjusted
prefix value would be negative also yields
Error::InvalidLengthPrefix, and one whose prefix value would not
fit in the width yields Error::FrameTooLarge.
The payload limit (LengthPrefixed::max_payload) is counted in
payload bytes and is capped at the width’s largest prefix value,
independently of the adjustment. Two consequences:
- A negative adjustment lowers the largest payload that can be
written to
width maximum + adjustment(254 bytes for a self-countingU8prefix).write_framereports that effective bound as thelimitofError::FrameTooLarge. - A positive adjustment does not raise the limit: payloads longer
than
LengthWidth::max_payloadare rejected even though the adjusted prefix could describe them.
§Example
use wire_codec::WriteBuf;
use wire_codec::framing::{Endian, Framer, LengthPrefixed, LengthWidth};
// The 2-byte length field counts itself.
let framer = LengthPrefixed::unbounded(LengthWidth::U16, Endian::Big).with_length_adjustment(-2);
let mut out = [0u8; 8];
let mut buf = WriteBuf::new(&mut out);
framer.write_frame(b"abc", &mut buf).unwrap();
assert_eq!(buf.written(), &[0x00, 0x05, b'a', b'b', b'c']);
let frame = framer.next_frame(&out[..5]).unwrap().unwrap();
assert_eq!(frame.payload(), b"abc");Sourcepub const fn width(&self) -> LengthWidth
pub const fn width(&self) -> LengthWidth
Configured prefix width.
Sourcepub const fn max_payload(&self) -> u64
pub const fn max_payload(&self) -> u64
Configured maximum payload size in bytes.
Sourcepub const fn length_adjustment(&self) -> i64
pub const fn length_adjustment(&self) -> i64
Configured length adjustment (see
LengthPrefixed::with_length_adjustment).
Trait Implementations§
Source§impl Clone for LengthPrefixed
impl Clone for LengthPrefixed
impl Copy for LengthPrefixed
Source§impl Debug for LengthPrefixed
impl Debug for LengthPrefixed
impl Eq for LengthPrefixed
Source§impl Framer for LengthPrefixed
impl Framer for LengthPrefixed
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 one frame if the prefix and the full payload are present.
§Errors
Error::FrameTooLargeif the (adjusted) prefix exceeds the configured limit, or the payload cannot be addressed on this target.Error::InvalidLengthPrefixif the length adjustment turns the prefix into a negative length.
Source§fn write_frame(&self, payload: &[u8], out: &mut WriteBuf<'_>) -> Result<()>
fn write_frame(&self, payload: &[u8], out: &mut WriteBuf<'_>) -> Result<()>
Write the prefix and the payload.
§Errors
Error::FrameTooLargeif the payload exceeds the configured limit, or its adjusted length does not fit in the prefix width.Error::InvalidLengthPrefixif the adjusted length is negative.Error::BufferFullifoutcannot hold the whole frame.
Nothing is written on error.
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 moreSource§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>>>
Framer::next_frame for streaming input. Read more