Skip to main content

LengthPrefixed

Struct LengthPrefixed 

Source
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

Source

pub const DEFAULT_MAX_PAYLOAD: u64

Payload limit applied by LengthPrefixed::bounded: 8 MiB.

Matches the default of tokio_util::codec::LengthDelimitedCodec.

Source

pub 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

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));
Source

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);
Source

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 { .. })
));
Source

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);
Source

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);
Source

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-counting U8 prefix). write_frame reports that effective bound as the limit of Error::FrameTooLarge.
  • A positive adjustment does not raise the limit: payloads longer than LengthWidth::max_payload are 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");
Source

pub const fn width(&self) -> LengthWidth

Configured prefix width.

Source

pub const fn endian(&self) -> Endian

Configured endianness.

Source

pub const fn max_payload(&self) -> u64

Configured maximum payload size in bytes.

Source

pub const fn length_adjustment(&self) -> i64

Configured length adjustment (see LengthPrefixed::with_length_adjustment).

Trait Implementations§

Source§

impl Clone for LengthPrefixed

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for LengthPrefixed

Source§

impl Debug for LengthPrefixed

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for LengthPrefixed

Source§

impl Framer for LengthPrefixed

Source§

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
Source§

fn write_frame(&self, payload: &[u8], out: &mut WriteBuf<'_>) -> Result<()>

Write the prefix and the payload.

§Errors

Nothing is written on error.

Source§

fn max_frame_len(&self, payload_len: usize) -> Option<usize>

Upper bound on the number of bytes Framer::write_frame writes for a payload of payload_len bytes. Read more
Source§

fn next_frame_from<'a>( &self, input: &'a [u8], scanned: &mut usize, ) -> Result<Option<Frame<'a>>>

Resumable variant of Framer::next_frame for streaming input. Read more
Source§

impl Hash for LengthPrefixed

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for LengthPrefixed

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for LengthPrefixed

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.