mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-25 12:00:35 +00:00
codec: fix length_delimited
docs examples (#6638)
This commit is contained in:
parent
ed4ddf443d
commit
06582776a5
@ -75,55 +75,23 @@
|
||||
//!
|
||||
//! ## Example 1
|
||||
//!
|
||||
//! The following will parse a `u16` length field at offset 0, including the
|
||||
//! frame head in the yielded `BytesMut`.
|
||||
//!
|
||||
//! ```
|
||||
//! # use tokio::io::AsyncRead;
|
||||
//! # use tokio_util::codec::LengthDelimitedCodec;
|
||||
//! # fn bind_read<T: AsyncRead>(io: T) {
|
||||
//! LengthDelimitedCodec::builder()
|
||||
//! .length_field_offset(0) // default value
|
||||
//! .length_field_type::<u16>()
|
||||
//! .length_adjustment(0) // default value
|
||||
//! .num_skip(0) // Do not strip frame header
|
||||
//! .new_read(io);
|
||||
//! # }
|
||||
//! # pub fn main() {}
|
||||
//! ```
|
||||
//!
|
||||
//! The following frame will be decoded as such:
|
||||
//!
|
||||
//! ```text
|
||||
//! INPUT DECODED
|
||||
//! +-- len ---+--- Payload ---+ +-- len ---+--- Payload ---+
|
||||
//! | \x00\x0B | Hello world | --> | \x00\x0B | Hello world |
|
||||
//! +----------+---------------+ +----------+---------------+
|
||||
//! ```
|
||||
//!
|
||||
//! The value of the length field is 11 (`\x0B`) which represents the length
|
||||
//! of the payload, `hello world`. By default, [`FramedRead`] assumes that
|
||||
//! the length field represents the number of bytes that **follows** the
|
||||
//! length field. Thus, the entire frame has a length of 13: 2 bytes for the
|
||||
//! frame head + 11 bytes for the payload.
|
||||
//!
|
||||
//! ## Example 2
|
||||
//!
|
||||
//! The following will parse a `u16` length field at offset 0, omitting the
|
||||
//! frame head in the yielded `BytesMut`.
|
||||
//!
|
||||
//! ```
|
||||
//! # use tokio::io::AsyncRead;
|
||||
//! # use tokio_stream::StreamExt;
|
||||
//! # use tokio_util::codec::LengthDelimitedCodec;
|
||||
//! # fn bind_read<T: AsyncRead>(io: T) {
|
||||
//! LengthDelimitedCodec::builder()
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() {
|
||||
//! # let io: &[u8] = b"\x00\x0BHello world";
|
||||
//! let mut reader = LengthDelimitedCodec::builder()
|
||||
//! .length_field_offset(0) // default value
|
||||
//! .length_field_type::<u16>()
|
||||
//! .length_adjustment(0) // default value
|
||||
//! // `num_skip` is not needed, the default is to skip
|
||||
//! .new_read(io);
|
||||
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
|
||||
//! # assert_eq!(res, b"Hello world");
|
||||
//! # }
|
||||
//! # pub fn main() {}
|
||||
//! ```
|
||||
//!
|
||||
//! The following frame will be decoded as such:
|
||||
@ -135,27 +103,32 @@
|
||||
//! +----------+---------------+ +---------------+
|
||||
//! ```
|
||||
//!
|
||||
//! This is similar to the first example, the only difference is that the
|
||||
//! frame head is **not** included in the yielded `BytesMut` value.
|
||||
//! The value of the length field is 11 (`\x0B`) which represents the length
|
||||
//! of the payload, `hello world`. By default, [`FramedRead`] assumes that
|
||||
//! the length field represents the number of bytes that **follows** the
|
||||
//! length field. Thus, the entire frame has a length of 13: 2 bytes for the
|
||||
//! frame head + 11 bytes for the payload.
|
||||
//!
|
||||
//! ## Example 3
|
||||
//! ## Example 2
|
||||
//!
|
||||
//! The following will parse a `u16` length field at offset 0, including the
|
||||
//! frame head in the yielded `BytesMut`. In this case, the length field
|
||||
//! **includes** the frame head length.
|
||||
//! frame head in the yielded `BytesMut`.
|
||||
//!
|
||||
//! ```
|
||||
//! # use tokio::io::AsyncRead;
|
||||
//! # use tokio_stream::StreamExt;
|
||||
//! # use tokio_util::codec::LengthDelimitedCodec;
|
||||
//! # fn bind_read<T: AsyncRead>(io: T) {
|
||||
//! LengthDelimitedCodec::builder()
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() {
|
||||
//! # let io: &[u8] = b"\x00\x0BHello world";
|
||||
//! let mut reader = LengthDelimitedCodec::builder()
|
||||
//! .length_field_offset(0) // default value
|
||||
//! .length_field_type::<u16>()
|
||||
//! .length_adjustment(-2) // size of head
|
||||
//! .num_skip(0)
|
||||
//! .length_adjustment(2) // Add head size to length
|
||||
//! .num_skip(0) // Do NOT skip the head
|
||||
//! .new_read(io);
|
||||
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
|
||||
//! # assert_eq!(res, b"\x00\x0BHello world");
|
||||
//! # }
|
||||
//! # pub fn main() {}
|
||||
//! ```
|
||||
//!
|
||||
//! The following frame will be decoded as such:
|
||||
@ -163,10 +136,46 @@
|
||||
//! ```text
|
||||
//! INPUT DECODED
|
||||
//! +-- len ---+--- Payload ---+ +-- len ---+--- Payload ---+
|
||||
//! | \x00\x0D | Hello world | --> | \x00\x0D | Hello world |
|
||||
//! | \x00\x0B | Hello world | --> | \x00\x0B | Hello world |
|
||||
//! +----------+---------------+ +----------+---------------+
|
||||
//! ```
|
||||
//!
|
||||
//! This is similar to the first example, the only difference is that the
|
||||
//! frame head is **included** in the yielded `BytesMut` value. To achieve
|
||||
//! this, we need to add the header size to the length with `length_adjustment`,
|
||||
//! and set `num_skip` to `0` to prevent skipping the head.
|
||||
//!
|
||||
//! ## Example 3
|
||||
//!
|
||||
//! The following will parse a `u16` length field at offset 0, omitting the
|
||||
//! frame head in the yielded `BytesMut`. In this case, the length field
|
||||
//! **includes** the frame head length.
|
||||
//!
|
||||
//! ```
|
||||
//! # use tokio_stream::StreamExt;
|
||||
//! # use tokio_util::codec::LengthDelimitedCodec;
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() {
|
||||
//! # let io: &[u8] = b"\x00\x0DHello world";
|
||||
//! let mut reader = LengthDelimitedCodec::builder()
|
||||
//! .length_field_offset(0) // default value
|
||||
//! .length_field_type::<u16>()
|
||||
//! .length_adjustment(-2) // size of head
|
||||
//! .new_read(io);
|
||||
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
|
||||
//! # assert_eq!(res, b"Hello world");
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! The following frame will be decoded as such:
|
||||
//!
|
||||
//! ```text
|
||||
//! INPUT DECODED
|
||||
//! +-- len ---+--- Payload ---+ +--- Payload ---+
|
||||
//! | \x00\x0D | Hello world | --> | Hello world |
|
||||
//! +----------+---------------+ +---------------+
|
||||
//! ```
|
||||
//!
|
||||
//! In most cases, the length field represents the length of the payload
|
||||
//! only, as shown in the previous examples. However, in some protocols the
|
||||
//! length field represents the length of the whole frame, including the
|
||||
@ -179,17 +188,20 @@
|
||||
//! frame head, including the frame head in the yielded `BytesMut`.
|
||||
//!
|
||||
//! ```
|
||||
//! # use tokio::io::AsyncRead;
|
||||
//! # use tokio_stream::StreamExt;
|
||||
//! # use tokio_util::codec::LengthDelimitedCodec;
|
||||
//! # fn bind_read<T: AsyncRead>(io: T) {
|
||||
//! LengthDelimitedCodec::builder()
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() {
|
||||
//! # let io: &[u8] = b"\x00\x00\x0B\xCA\xFEHello world";
|
||||
//! let mut reader = LengthDelimitedCodec::builder()
|
||||
//! .length_field_offset(0) // default value
|
||||
//! .length_field_length(3)
|
||||
//! .length_adjustment(2) // remaining head
|
||||
//! .length_adjustment(3 + 2) // len field and remaining head
|
||||
//! .num_skip(0)
|
||||
//! .new_read(io);
|
||||
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
|
||||
//! # assert_eq!(res, b"\x00\x00\x0B\xCA\xFEHello world");
|
||||
//! # }
|
||||
//! # pub fn main() {}
|
||||
//! ```
|
||||
//!
|
||||
//! The following frame will be decoded as such:
|
||||
@ -223,17 +235,20 @@
|
||||
//! included.
|
||||
//!
|
||||
//! ```
|
||||
//! # use tokio::io::AsyncRead;
|
||||
//! # use tokio_stream::StreamExt;
|
||||
//! # use tokio_util::codec::LengthDelimitedCodec;
|
||||
//! # fn bind_read<T: AsyncRead>(io: T) {
|
||||
//! LengthDelimitedCodec::builder()
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() {
|
||||
//! # let io: &[u8] = b"\xCA\x00\x0B\xFEHello world";
|
||||
//! let mut reader = LengthDelimitedCodec::builder()
|
||||
//! .length_field_offset(1) // length of hdr1
|
||||
//! .length_field_type::<u16>()
|
||||
//! .length_adjustment(1) // length of hdr2
|
||||
//! .num_skip(3) // length of hdr1 + LEN
|
||||
//! .new_read(io);
|
||||
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
|
||||
//! # assert_eq!(res, b"\xFEHello world");
|
||||
//! # }
|
||||
//! # pub fn main() {}
|
||||
//! ```
|
||||
//!
|
||||
//! The following frame will be decoded as such:
|
||||
@ -269,15 +284,19 @@
|
||||
//! length.
|
||||
//!
|
||||
//! ```
|
||||
//! # use tokio::io::AsyncRead;
|
||||
//! # use tokio_stream::StreamExt;
|
||||
//! # use tokio_util::codec::LengthDelimitedCodec;
|
||||
//! # fn bind_read<T: AsyncRead>(io: T) {
|
||||
//! LengthDelimitedCodec::builder()
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() {
|
||||
//! # let io: &[u8] = b"\xCA\x00\x0F\xFEHello world";
|
||||
//! let mut reader = LengthDelimitedCodec::builder()
|
||||
//! .length_field_offset(1) // length of hdr1
|
||||
//! .length_field_type::<u16>()
|
||||
//! .length_adjustment(-3) // length of hdr1 + LEN, negative
|
||||
//! .num_skip(3)
|
||||
//! .new_read(io);
|
||||
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
|
||||
//! # assert_eq!(res, b"\xFEHello world");
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
@ -308,17 +327,20 @@
|
||||
//! frame head, excluding the 4th byte from the yielded `BytesMut`.
|
||||
//!
|
||||
//! ```
|
||||
//! # use tokio::io::AsyncRead;
|
||||
//! # use tokio_stream::StreamExt;
|
||||
//! # use tokio_util::codec::LengthDelimitedCodec;
|
||||
//! # fn bind_read<T: AsyncRead>(io: T) {
|
||||
//! LengthDelimitedCodec::builder()
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() {
|
||||
//! # let io: &[u8] = b"\x00\x00\x0B\xFFHello world";
|
||||
//! let mut reader = LengthDelimitedCodec::builder()
|
||||
//! .length_field_offset(0) // default value
|
||||
//! .length_field_length(3)
|
||||
//! .length_adjustment(0) // default value
|
||||
//! .num_skip(4) // skip the first 4 bytes
|
||||
//! .new_read(io);
|
||||
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
|
||||
//! # assert_eq!(res, b"Hello world");
|
||||
//! # }
|
||||
//! # pub fn main() {}
|
||||
//! ```
|
||||
//!
|
||||
//! The following frame will be decoded as such:
|
||||
|
Loading…
x
Reference in New Issue
Block a user