1 //! Frame a stream of bytes based on a length prefix
2 //!
3 //! Many protocols delimit their frames by prefacing frame data with a
4 //! frame head that specifies the length of the frame. The
5 //! `length_delimited` module provides utilities for handling the length
6 //! based framing. This allows the consumer to work with entire frames
7 //! without having to worry about buffering or other framing logic.
8 //!
9 //! # Getting started
10 //!
11 //! If implementing a protocol from scratch, using length delimited framing
12 //! is an easy way to get started. [`Codec::new()`] will return a length
13 //! delimited codec using default configuration values. This can then be
14 //! used to construct a framer to adapt a full-duplex byte stream into a
15 //! stream of frames.
16 //!
17 //! ```
18 //! # extern crate tokio;
19 //! use tokio::io::{AsyncRead, AsyncWrite};
20 //! use tokio::codec::*;
21 //!
22 //! fn bind_transport<T: AsyncRead + AsyncWrite>(io: T)
23 //!     -> Framed<T, LengthDelimitedCodec>
24 //! {
25 //!     Framed::new(io, LengthDelimitedCodec::new())
26 //! }
27 //! # pub fn main() {}
28 //! ```
29 //!
30 //! The returned transport implements `Sink + Stream` for `BytesMut`. It
31 //! encodes the frame with a big-endian `u32` header denoting the frame
32 //! payload length:
33 //!
34 //! ```text
35 //! +----------+--------------------------------+
36 //! | len: u32 |          frame payload         |
37 //! +----------+--------------------------------+
38 //! ```
39 //!
40 //! Specifically, given the following:
41 //!
42 //! ```
43 //! # extern crate tokio;
44 //! # extern crate bytes;
45 //! # extern crate futures;
46 //! #
47 //! use tokio::io::{AsyncRead, AsyncWrite};
48 //! use tokio::codec::*;
49 //! use bytes::Bytes;
50 //! use futures::{Sink, Future};
51 //!
52 //! fn write_frame<T: AsyncRead + AsyncWrite>(io: T) {
53 //!     let mut transport = Framed::new(io, LengthDelimitedCodec::new());
54 //!     let frame = Bytes::from("hello world");
55 //!
56 //!     transport.send(frame).wait().unwrap();
57 //! }
58 //! #
59 //! # pub fn main() {}
60 //! ```
61 //!
62 //! The encoded frame will look like this:
63 //!
64 //! ```text
65 //! +---- len: u32 ----+---- data ----+
66 //! | \x00\x00\x00\x0b |  hello world |
67 //! +------------------+--------------+
68 //! ```
69 //!
70 //! # Decoding
71 //!
72 //! [`FramedRead`] adapts an [`AsyncRead`] into a `Stream` of [`BytesMut`],
73 //! such that each yielded [`BytesMut`] value contains the contents of an
74 //! entire frame. There are many configuration parameters enabling
75 //! [`FramedRead`] to handle a wide range of protocols. Here are some
76 //! examples that will cover the various options at a high level.
77 //!
78 //! ## Example 1
79 //!
80 //! The following will parse a `u16` length field at offset 0, including the
81 //! frame head in the yielded `BytesMut`.
82 //!
83 //! ```
84 //! # extern crate tokio;
85 //! # use tokio::io::AsyncRead;
86 //! # use tokio::codec::length_delimited;
87 //! # fn bind_read<T: AsyncRead>(io: T) {
88 //! length_delimited::Builder::new()
89 //!     .length_field_offset(0) // default value
90 //!     .length_field_length(2)
91 //!     .length_adjustment(0)   // default value
92 //!     .num_skip(0) // Do not strip frame header
93 //!     .new_read(io);
94 //! # }
95 //! # pub fn main() {}
96 //! ```
97 //!
98 //! The following frame will be decoded as such:
99 //!
100 //! ```text
101 //!          INPUT                           DECODED
102 //! +-- len ---+--- Payload ---+     +-- len ---+--- Payload ---+
103 //! | \x00\x0B |  Hello world  | --> | \x00\x0B |  Hello world  |
104 //! +----------+---------------+     +----------+---------------+
105 //! ```
106 //!
107 //! The value of the length field is 11 (`\x0B`) which represents the length
108 //! of the payload, `hello world`. By default, [`FramedRead`] assumes that
109 //! the length field represents the number of bytes that **follows** the
110 //! length field. Thus, the entire frame has a length of 13: 2 bytes for the
111 //! frame head + 11 bytes for the payload.
112 //!
113 //! ## Example 2
114 //!
115 //! The following will parse a `u16` length field at offset 0, omitting the
116 //! frame head in the yielded `BytesMut`.
117 //!
118 //! ```
119 //! # extern crate tokio;
120 //! # use tokio::io::AsyncRead;
121 //! # use tokio::codec::length_delimited;
122 //! # fn bind_read<T: AsyncRead>(io: T) {
123 //! length_delimited::Builder::new()
124 //!     .length_field_offset(0) // default value
125 //!     .length_field_length(2)
126 //!     .length_adjustment(0)   // default value
127 //!     // `num_skip` is not needed, the default is to skip
128 //!     .new_read(io);
129 //! # }
130 //! # pub fn main() {}
131 //! ```
132 //!
133 //! The following frame will be decoded as such:
134 //!
135 //! ```text
136 //!          INPUT                        DECODED
137 //! +-- len ---+--- Payload ---+     +--- Payload ---+
138 //! | \x00\x0B |  Hello world  | --> |  Hello world  |
139 //! +----------+---------------+     +---------------+
140 //! ```
141 //!
142 //! This is similar to the first example, the only difference is that the
143 //! frame head is **not** included in the yielded `BytesMut` value.
144 //!
145 //! ## Example 3
146 //!
147 //! The following will parse a `u16` length field at offset 0, including the
148 //! frame head in the yielded `BytesMut`. In this case, the length field
149 //! **includes** the frame head length.
150 //!
151 //! ```
152 //! # extern crate tokio;
153 //! # use tokio::io::AsyncRead;
154 //! # use tokio::codec::length_delimited;
155 //! # fn bind_read<T: AsyncRead>(io: T) {
156 //! length_delimited::Builder::new()
157 //!     .length_field_offset(0) // default value
158 //!     .length_field_length(2)
159 //!     .length_adjustment(-2)  // size of head
160 //!     .num_skip(0)
161 //!     .new_read(io);
162 //! # }
163 //! # pub fn main() {}
164 //! ```
165 //!
166 //! The following frame will be decoded as such:
167 //!
168 //! ```text
169 //!          INPUT                           DECODED
170 //! +-- len ---+--- Payload ---+     +-- len ---+--- Payload ---+
171 //! | \x00\x0D |  Hello world  | --> | \x00\x0D |  Hello world  |
172 //! +----------+---------------+     +----------+---------------+
173 //! ```
174 //!
175 //! In most cases, the length field represents the length of the payload
176 //! only, as shown in the previous examples. However, in some protocols the
177 //! length field represents the length of the whole frame, including the
178 //! head. In such cases, we specify a negative `length_adjustment` to adjust
179 //! the value provided in the frame head to represent the payload length.
180 //!
181 //! ## Example 4
182 //!
183 //! The following will parse a 3 byte length field at offset 0 in a 5 byte
184 //! frame head, including the frame head in the yielded `BytesMut`.
185 //!
186 //! ```
187 //! # extern crate tokio;
188 //! # use tokio::io::AsyncRead;
189 //! # use tokio::codec::length_delimited;
190 //! # fn bind_read<T: AsyncRead>(io: T) {
191 //! length_delimited::Builder::new()
192 //!     .length_field_offset(0) // default value
193 //!     .length_field_length(3)
194 //!     .length_adjustment(2)  // remaining head
195 //!     .num_skip(0)
196 //!     .new_read(io);
197 //! # }
198 //! # pub fn main() {}
199 //! ```
200 //!
201 //! The following frame will be decoded as such:
202 //!
203 //! ```text
204 //!                  INPUT
205 //! +---- len -----+- head -+--- Payload ---+
206 //! | \x00\x00\x0B | \xCAFE |  Hello world  |
207 //! +--------------+--------+---------------+
208 //!
209 //!                  DECODED
210 //! +---- len -----+- head -+--- Payload ---+
211 //! | \x00\x00\x0B | \xCAFE |  Hello world  |
212 //! +--------------+--------+---------------+
213 //! ```
214 //!
215 //! A more advanced example that shows a case where there is extra frame
216 //! head data between the length field and the payload. In such cases, it is
217 //! usually desirable to include the frame head as part of the yielded
218 //! `BytesMut`. This lets consumers of the length delimited framer to
219 //! process the frame head as needed.
220 //!
221 //! The positive `length_adjustment` value lets `FramedRead` factor in the
222 //! additional head into the frame length calculation.
223 //!
224 //! ## Example 5
225 //!
226 //! The following will parse a `u16` length field at offset 1 of a 4 byte
227 //! frame head. The first byte and the length field will be omitted from the
228 //! yielded `BytesMut`, but the trailing 2 bytes of the frame head will be
229 //! included.
230 //!
231 //! ```
232 //! # extern crate tokio;
233 //! # use tokio::io::AsyncRead;
234 //! # use tokio::codec::length_delimited;
235 //! # fn bind_read<T: AsyncRead>(io: T) {
236 //! length_delimited::Builder::new()
237 //!     .length_field_offset(1) // length of hdr1
238 //!     .length_field_length(2)
239 //!     .length_adjustment(1)  // length of hdr2
240 //!     .num_skip(3) // length of hdr1 + LEN
241 //!     .new_read(io);
242 //! # }
243 //! # pub fn main() {}
244 //! ```
245 //!
246 //! The following frame will be decoded as such:
247 //!
248 //! ```text
249 //!                  INPUT
250 //! +- hdr1 -+-- len ---+- hdr2 -+--- Payload ---+
251 //! |  \xCA  | \x00\x0B |  \xFE  |  Hello world  |
252 //! +--------+----------+--------+---------------+
253 //!
254 //!          DECODED
255 //! +- hdr2 -+--- Payload ---+
256 //! |  \xFE  |  Hello world  |
257 //! +--------+---------------+
258 //! ```
259 //!
260 //! The length field is situated in the middle of the frame head. In this
261 //! case, the first byte in the frame head could be a version or some other
262 //! identifier that is not needed for processing. On the other hand, the
263 //! second half of the head is needed.
264 //!
265 //! `length_field_offset` indicates how many bytes to skip before starting
266 //! to read the length field.  `length_adjustment` is the number of bytes to
267 //! skip starting at the end of the length field. In this case, it is the
268 //! second half of the head.
269 //!
270 //! ## Example 6
271 //!
272 //! The following will parse a `u16` length field at offset 1 of a 4 byte
273 //! frame head. The first byte and the length field will be omitted from the
274 //! yielded `BytesMut`, but the trailing 2 bytes of the frame head will be
275 //! included. In this case, the length field **includes** the frame head
276 //! length.
277 //!
278 //! ```
279 //! # extern crate tokio;
280 //! # use tokio::io::AsyncRead;
281 //! # use tokio::codec::length_delimited;
282 //! # fn bind_read<T: AsyncRead>(io: T) {
283 //! length_delimited::Builder::new()
284 //!     .length_field_offset(1) // length of hdr1
285 //!     .length_field_length(2)
286 //!     .length_adjustment(-3)  // length of hdr1 + LEN, negative
287 //!     .num_skip(3)
288 //!     .new_read(io);
289 //! # }
290 //! # pub fn main() {}
291 //! ```
292 //!
293 //! The following frame will be decoded as such:
294 //!
295 //! ```text
296 //!                  INPUT
297 //! +- hdr1 -+-- len ---+- hdr2 -+--- Payload ---+
298 //! |  \xCA  | \x00\x0F |  \xFE  |  Hello world  |
299 //! +--------+----------+--------+---------------+
300 //!
301 //!          DECODED
302 //! +- hdr2 -+--- Payload ---+
303 //! |  \xFE  |  Hello world  |
304 //! +--------+---------------+
305 //! ```
306 //!
307 //! Similar to the example above, the difference is that the length field
308 //! represents the length of the entire frame instead of just the payload.
309 //! The length of `hdr1` and `len` must be counted in `length_adjustment`.
310 //! Note that the length of `hdr2` does **not** need to be explicitly set
311 //! anywhere because it already is factored into the total frame length that
312 //! is read from the byte stream.
313 //!
314 //! # Encoding
315 //!
316 //! [`FramedWrite`] adapts an [`AsyncWrite`] into a `Sink` of [`BytesMut`],
317 //! such that each submitted [`BytesMut`] is prefaced by a length field.
318 //! There are fewer configuration options than [`FramedRead`]. Given
319 //! protocols that have more complex frame heads, an encoder should probably
320 //! be written by hand using [`Encoder`].
321 //!
322 //! Here is a simple example, given a `FramedWrite` with the following
323 //! configuration:
324 //!
325 //! ```
326 //! # extern crate tokio;
327 //! # extern crate bytes;
328 //! # use tokio::io::AsyncWrite;
329 //! # use tokio::codec::length_delimited;
330 //! # use bytes::BytesMut;
331 //! # fn write_frame<T: AsyncWrite>(io: T) {
332 //! # let _ =
333 //! length_delimited::Builder::new()
334 //!     .length_field_length(2)
335 //!     .new_write(io);
336 //! # }
337 //! # pub fn main() {}
338 //! ```
339 //!
340 //! A payload of `hello world` will be encoded as:
341 //!
342 //! ```text
343 //! +- len: u16 -+---- data ----+
344 //! |  \x00\x0b  |  hello world |
345 //! +------------+--------------+
346 //! ```
347 //!
348 //! [`FramedRead`]: struct.FramedRead.html
349 //! [`FramedWrite`]: struct.FramedWrite.html
350 //! [`AsyncRead`]: ../../trait.AsyncRead.html
351 //! [`AsyncWrite`]: ../../trait.AsyncWrite.html
352 //! [`Encoder`]: ../trait.Encoder.html
353 //! [`BytesMut`]: https://docs.rs/bytes/0.4/bytes/struct.BytesMut.html
354 
355 use {
356     codec::{
357         Decoder, Encoder, FramedRead, FramedWrite, Framed
358     },
359     io::{
360         AsyncRead, AsyncWrite
361     },
362 };
363 
364 use bytes::{Buf, BufMut, Bytes, BytesMut, IntoBuf};
365 
366 use std::{cmp, fmt};
367 use std::error::Error as StdError;
368 use std::io::{self, Cursor};
369 
370 /// Configure length delimited `LengthDelimitedCodec`s.
371 ///
372 /// `Builder` enables constructing configured length delimited codecs. Note
373 /// that not all configuration settings apply to both encoding and decoding. See
374 /// the documentation for specific methods for more detail.
375 #[derive(Debug, Clone, Copy)]
376 pub struct Builder {
377     // Maximum frame length
378     max_frame_len: usize,
379 
380     // Number of bytes representing the field length
381     length_field_len: usize,
382 
383     // Number of bytes in the header before the length field
384     length_field_offset: usize,
385 
386     // Adjust the length specified in the header field by this amount
387     length_adjustment: isize,
388 
389     // Total number of bytes to skip before reading the payload, if not set,
390     // `length_field_len + length_field_offset`
391     num_skip: Option<usize>,
392 
393     // Length field byte order (little or big endian)
394     length_field_is_big_endian: bool,
395 }
396 
397 /// An error when the number of bytes read is more than max frame length.
398 pub struct FrameTooBig {
399     _priv: (),
400 }
401 
402 /// A codec for frames delimited by a frame head specifying their lengths.
403 ///
404 /// This allows the consumer to work with entire frames without having to worry
405 /// about buffering or other framing logic.
406 ///
407 /// See [module level] documentation for more detail.
408 ///
409 /// [module level]: index.html
410 #[derive(Debug)]
411 pub struct LengthDelimitedCodec {
412     // Configuration values
413     builder: Builder,
414 
415     // Read state
416     state: DecodeState,
417 }
418 
419 #[derive(Debug, Clone, Copy)]
420 enum DecodeState {
421     Head,
422     Data(usize),
423 }
424 
425 // ===== impl LengthDelimitedCodec ======
426 
427 impl LengthDelimitedCodec {
428     /// Creates a new `LengthDelimitedCodec` with the default configuration values.
new() -> Self429     pub fn new() -> Self {
430         Self {
431             builder: Builder::new(),
432             state: DecodeState::Head,
433         }
434     }
435 
436     /// Returns the current max frame setting
437     ///
438     /// This is the largest size this codec will accept from the wire. Larger
439     /// frames will be rejected.
max_frame_length(&self) -> usize440     pub fn max_frame_length(&self) -> usize {
441         self.builder.max_frame_len
442     }
443 
444     /// Updates the max frame setting.
445     ///
446     /// The change takes effect the next time a frame is decoded. In other
447     /// words, if a frame is currently in process of being decoded with a frame
448     /// size greater than `val` but less than the max frame length in effect
449     /// before calling this function, then the frame will be allowed.
set_max_frame_length(&mut self, val: usize)450     pub fn set_max_frame_length(&mut self, val: usize) {
451         self.builder.max_frame_length(val);
452     }
453 
decode_head(&mut self, src: &mut BytesMut) -> io::Result<Option<usize>>454     fn decode_head(&mut self, src: &mut BytesMut) -> io::Result<Option<usize>> {
455         let head_len = self.builder.num_head_bytes();
456         let field_len = self.builder.length_field_len;
457 
458         if src.len() < head_len {
459             // Not enough data
460             return Ok(None);
461         }
462 
463         let n = {
464             let mut src = Cursor::new(&mut *src);
465 
466             // Skip the required bytes
467             src.advance(self.builder.length_field_offset);
468 
469             // match endianess
470             let n = if self.builder.length_field_is_big_endian {
471                 src.get_uint_be(field_len)
472             } else {
473                 src.get_uint_le(field_len)
474             };
475 
476             if n > self.builder.max_frame_len as u64 {
477                 return Err(io::Error::new(io::ErrorKind::InvalidData, FrameTooBig {
478                     _priv: (),
479                 }));
480             }
481 
482             // The check above ensures there is no overflow
483             let n = n as usize;
484 
485             // Adjust `n` with bounds checking
486             let n = if self.builder.length_adjustment < 0 {
487                 n.checked_sub(-self.builder.length_adjustment as usize)
488             } else {
489                 n.checked_add(self.builder.length_adjustment as usize)
490             };
491 
492             // Error handling
493             match n {
494                 Some(n) => n,
495                 None => return Err(io::Error::new(io::ErrorKind::InvalidInput, "provided length would overflow after adjustment")),
496             }
497         };
498 
499         let num_skip = self.builder.get_num_skip();
500 
501         if num_skip > 0 {
502             let _ = src.split_to(num_skip);
503         }
504 
505         // Ensure that the buffer has enough space to read the incoming
506         // payload
507         src.reserve(n);
508 
509         return Ok(Some(n));
510     }
511 
decode_data(&self, n: usize, src: &mut BytesMut) -> io::Result<Option<BytesMut>>512     fn decode_data(&self, n: usize, src: &mut BytesMut) -> io::Result<Option<BytesMut>> {
513         // At this point, the buffer has already had the required capacity
514         // reserved. All there is to do is read.
515         if src.len() < n {
516             return Ok(None);
517         }
518 
519         Ok(Some(src.split_to(n)))
520     }
521 }
522 
523 impl Decoder for LengthDelimitedCodec {
524     type Item = BytesMut;
525     type Error = io::Error;
526 
decode(&mut self, src: &mut BytesMut) -> io::Result<Option<BytesMut>>527     fn decode(&mut self, src: &mut BytesMut) -> io::Result<Option<BytesMut>> {
528         let n = match self.state {
529             DecodeState::Head => {
530                 match try!(self.decode_head(src)) {
531                     Some(n) => {
532                         self.state = DecodeState::Data(n);
533                         n
534                     }
535                     None => return Ok(None),
536                 }
537             }
538             DecodeState::Data(n) => n,
539         };
540 
541         match try!(self.decode_data(n, src)) {
542             Some(data) => {
543                 // Update the decode state
544                 self.state = DecodeState::Head;
545 
546                 // Make sure the buffer has enough space to read the next head
547                 src.reserve(self.builder.num_head_bytes());
548 
549                 Ok(Some(data))
550             }
551             None => Ok(None),
552         }
553     }
554 }
555 
556 impl Encoder for LengthDelimitedCodec {
557     type Item = Bytes;
558     type Error = io::Error;
559 
encode(&mut self, data: Bytes, dst: &mut BytesMut) -> Result<(), io::Error>560     fn encode(&mut self, data: Bytes, dst: &mut BytesMut) -> Result<(), io::Error> {
561         let n = (&data).into_buf().remaining();
562 
563         if n > self.builder.max_frame_len {
564             return Err(io::Error::new(io::ErrorKind::InvalidInput, FrameTooBig {
565                 _priv: (),
566             }));
567         }
568 
569         // Adjust `n` with bounds checking
570         let n = if self.builder.length_adjustment < 0 {
571             n.checked_add(-self.builder.length_adjustment as usize)
572         } else {
573             n.checked_sub(self.builder.length_adjustment as usize)
574         };
575 
576         let n = n.ok_or_else(|| io::Error::new(
577             io::ErrorKind::InvalidInput,
578             "provided length would overflow after adjustment",
579         ))?;
580 
581         if self.builder.length_field_is_big_endian {
582             dst.put_uint_be(n as u64, self.builder.length_field_len);
583         } else {
584             dst.put_uint_le(n as u64, self.builder.length_field_len);
585         }
586 
587         // Write the frame to the buffer
588         dst.extend_from_slice(&data[..]);
589 
590         Ok(())
591     }
592 }
593 
594 // ===== impl Builder =====
595 
596 impl Builder {
597     /// Creates a new length delimited codec builder with default configuration
598     /// values.
599     ///
600     /// # Examples
601     ///
602     /// ```
603     /// # extern crate tokio;
604     /// # use tokio::io::AsyncRead;
605     /// use tokio::codec::length_delimited::Builder;
606     ///
607     /// # fn bind_read<T: AsyncRead>(io: T) {
608     /// Builder::new()
609     ///     .length_field_offset(0)
610     ///     .length_field_length(2)
611     ///     .length_adjustment(0)
612     ///     .num_skip(0)
613     ///     .new_read(io);
614     /// # }
615     /// # pub fn main() {}
616     /// ```
new() -> Builder617     pub fn new() -> Builder {
618         Builder {
619             // Default max frame length of 8MB
620             max_frame_len: 8 * 1_024 * 1_024,
621 
622             // Default byte length of 4
623             length_field_len: 4,
624 
625             // Default to the header field being at the start of the header.
626             length_field_offset: 0,
627 
628             length_adjustment: 0,
629 
630             // Total number of bytes to skip before reading the payload, if not set,
631             // `length_field_len + length_field_offset`
632             num_skip: None,
633 
634             // Default to reading the length field in network (big) endian.
635             length_field_is_big_endian: true,
636         }
637     }
638 
639     /// Read the length field as a big endian integer
640     ///
641     /// This is the default setting.
642     ///
643     /// This configuration option applies to both encoding and decoding.
644     ///
645     /// # Examples
646     ///
647     /// ```
648     /// # extern crate tokio;
649     /// # use tokio::io::AsyncRead;
650     /// use tokio::codec::length_delimited::Builder;
651     ///
652     /// # fn bind_read<T: AsyncRead>(io: T) {
653     /// Builder::new()
654     ///     .big_endian()
655     ///     .new_read(io);
656     /// # }
657     /// # pub fn main() {}
658     /// ```
big_endian(&mut self) -> &mut Self659     pub fn big_endian(&mut self) -> &mut Self {
660         self.length_field_is_big_endian = true;
661         self
662     }
663 
664     /// Read the length field as a little endian integer
665     ///
666     /// The default setting is big endian.
667     ///
668     /// This configuration option applies to both encoding and decoding.
669     ///
670     /// # Examples
671     ///
672     /// ```
673     /// # extern crate tokio;
674     /// # use tokio::io::AsyncRead;
675     /// use tokio::codec::length_delimited::Builder;
676     ///
677     /// # fn bind_read<T: AsyncRead>(io: T) {
678     /// Builder::new()
679     ///     .little_endian()
680     ///     .new_read(io);
681     /// # }
682     /// # pub fn main() {}
683     /// ```
little_endian(&mut self) -> &mut Self684     pub fn little_endian(&mut self) -> &mut Self {
685         self.length_field_is_big_endian = false;
686         self
687     }
688 
689     /// Read the length field as a native endian integer
690     ///
691     /// The default setting is big endian.
692     ///
693     /// This configuration option applies to both encoding and decoding.
694     ///
695     /// # Examples
696     ///
697     /// ```
698     /// # extern crate tokio;
699     /// # use tokio::io::AsyncRead;
700     /// use tokio::codec::length_delimited::Builder;
701     ///
702     /// # fn bind_read<T: AsyncRead>(io: T) {
703     /// Builder::new()
704     ///     .native_endian()
705     ///     .new_read(io);
706     /// # }
707     /// # pub fn main() {}
708     /// ```
native_endian(&mut self) -> &mut Self709     pub fn native_endian(&mut self) -> &mut Self {
710         if cfg!(target_endian = "big") {
711             self.big_endian()
712         } else {
713             self.little_endian()
714         }
715     }
716 
717     /// Sets the max frame length
718     ///
719     /// This configuration option applies to both encoding and decoding. The
720     /// default value is 8MB.
721     ///
722     /// When decoding, the length field read from the byte stream is checked
723     /// against this setting **before** any adjustments are applied. When
724     /// encoding, the length of the submitted payload is checked against this
725     /// setting.
726     ///
727     /// When frames exceed the max length, an `io::Error` with the custom value
728     /// of the `FrameTooBig` type will be returned.
729     ///
730     /// # Examples
731     ///
732     /// ```
733     /// # extern crate tokio;
734     /// # use tokio::io::AsyncRead;
735     /// use tokio::codec::length_delimited::Builder;
736     ///
737     /// # fn bind_read<T: AsyncRead>(io: T) {
738     /// Builder::new()
739     ///     .max_frame_length(8 * 1024)
740     ///     .new_read(io);
741     /// # }
742     /// # pub fn main() {}
743     /// ```
max_frame_length(&mut self, val: usize) -> &mut Self744     pub fn max_frame_length(&mut self, val: usize) -> &mut Self {
745         self.max_frame_len = val;
746         self
747     }
748 
749     /// Sets the number of bytes used to represent the length field
750     ///
751     /// The default value is `4`. The max value is `8`.
752     ///
753     /// This configuration option applies to both encoding and decoding.
754     ///
755     /// # Examples
756     ///
757     /// ```
758     /// # extern crate tokio;
759     /// # use tokio::io::AsyncRead;
760     /// use tokio::codec::length_delimited::Builder;
761     ///
762     /// # fn bind_read<T: AsyncRead>(io: T) {
763     /// Builder::new()
764     ///     .length_field_length(4)
765     ///     .new_read(io);
766     /// # }
767     /// # pub fn main() {}
768     /// ```
length_field_length(&mut self, val: usize) -> &mut Self769     pub fn length_field_length(&mut self, val: usize) -> &mut Self {
770         assert!(val > 0 && val <= 8, "invalid length field length");
771         self.length_field_len = val;
772         self
773     }
774 
775     /// Sets the number of bytes in the header before the length field
776     ///
777     /// This configuration option only applies to decoding.
778     ///
779     /// # Examples
780     ///
781     /// ```
782     /// # extern crate tokio;
783     /// # use tokio::io::AsyncRead;
784     /// use tokio::codec::length_delimited::Builder;
785     ///
786     /// # fn bind_read<T: AsyncRead>(io: T) {
787     /// Builder::new()
788     ///     .length_field_offset(1)
789     ///     .new_read(io);
790     /// # }
791     /// # pub fn main() {}
792     /// ```
length_field_offset(&mut self, val: usize) -> &mut Self793     pub fn length_field_offset(&mut self, val: usize) -> &mut Self {
794         self.length_field_offset = val;
795         self
796     }
797 
798     /// Delta between the payload length specified in the header and the real
799     /// payload length
800     ///
801     /// # Examples
802     ///
803     /// ```
804     /// # extern crate tokio;
805     /// # use tokio::io::AsyncRead;
806     /// use tokio::codec::length_delimited::Builder;
807     ///
808     /// # fn bind_read<T: AsyncRead>(io: T) {
809     /// Builder::new()
810     ///     .length_adjustment(-2)
811     ///     .new_read(io);
812     /// # }
813     /// # pub fn main() {}
814     /// ```
length_adjustment(&mut self, val: isize) -> &mut Self815     pub fn length_adjustment(&mut self, val: isize) -> &mut Self {
816         self.length_adjustment = val;
817         self
818     }
819 
820     /// Sets the number of bytes to skip before reading the payload
821     ///
822     /// Default value is `length_field_len + length_field_offset`
823     ///
824     /// This configuration option only applies to decoding
825     ///
826     /// # Examples
827     ///
828     /// ```
829     /// # extern crate tokio;
830     /// # use tokio::io::AsyncRead;
831     /// use tokio::codec::length_delimited::Builder;
832     ///
833     /// # fn bind_read<T: AsyncRead>(io: T) {
834     /// Builder::new()
835     ///     .num_skip(4)
836     ///     .new_read(io);
837     /// # }
838     /// # pub fn main() {}
839     /// ```
num_skip(&mut self, val: usize) -> &mut Self840     pub fn num_skip(&mut self, val: usize) -> &mut Self {
841         self.num_skip = Some(val);
842         self
843     }
844 
845     /// Create a configured length delimited `LengthDelimitedCodec`
846     ///
847     /// # Examples
848     ///
849     /// ```
850     /// # extern crate tokio;
851     /// # use tokio::io::AsyncRead;
852     /// use tokio::codec::length_delimited::Builder;
853     /// # pub fn main() {
854     /// Builder::new()
855     ///     .length_field_offset(0)
856     ///     .length_field_length(2)
857     ///     .length_adjustment(0)
858     ///     .num_skip(0)
859     ///     .new_codec();
860     /// # }
861     /// ```
new_codec(&self) -> LengthDelimitedCodec862     pub fn new_codec(&self) -> LengthDelimitedCodec {
863         LengthDelimitedCodec {
864             builder: *self,
865             state: DecodeState::Head,
866         }
867     }
868 
869     /// Create a configured length delimited `FramedRead`
870     ///
871     /// # Examples
872     ///
873     /// ```
874     /// # extern crate tokio;
875     /// # use tokio::io::AsyncRead;
876     /// use tokio::codec::length_delimited::Builder;
877     ///
878     /// # fn bind_read<T: AsyncRead>(io: T) {
879     /// Builder::new()
880     ///     .length_field_offset(0)
881     ///     .length_field_length(2)
882     ///     .length_adjustment(0)
883     ///     .num_skip(0)
884     ///     .new_read(io);
885     /// # }
886     /// # pub fn main() {}
887     /// ```
new_read<T>(&self, upstream: T) -> FramedRead<T, LengthDelimitedCodec> where T: AsyncRead,888     pub fn new_read<T>(&self, upstream: T) -> FramedRead<T, LengthDelimitedCodec>
889         where T: AsyncRead,
890     {
891         FramedRead::new(upstream, self.new_codec())
892     }
893 
894     /// Create a configured length delimited `FramedWrite`
895     ///
896     /// # Examples
897     ///
898     /// ```
899     /// # extern crate tokio;
900     /// # extern crate bytes;
901     /// # use tokio::io::AsyncWrite;
902     /// # use tokio::codec::length_delimited;
903     /// # use bytes::BytesMut;
904     /// # fn write_frame<T: AsyncWrite>(io: T) {
905     /// length_delimited::Builder::new()
906     ///     .length_field_length(2)
907     ///     .new_write(io);
908     /// # }
909     /// # pub fn main() {}
910     /// ```
new_write<T>(&self, inner: T) -> FramedWrite<T, LengthDelimitedCodec> where T: AsyncWrite,911     pub fn new_write<T>(&self, inner: T) -> FramedWrite<T, LengthDelimitedCodec>
912         where T: AsyncWrite,
913     {
914         FramedWrite::new(inner, self.new_codec())
915     }
916 
917     /// Create a configured length delimited `Framed`
918     ///
919     /// # Examples
920     ///
921     /// ```
922     /// # extern crate tokio;
923     /// # extern crate bytes;
924     /// # use tokio::io::{AsyncRead, AsyncWrite};
925     /// # use tokio::codec::length_delimited;
926     /// # use bytes::BytesMut;
927     /// # fn write_frame<T: AsyncRead + AsyncWrite>(io: T) {
928     /// # let _ =
929     /// length_delimited::Builder::new()
930     ///     .length_field_length(2)
931     ///     .new_framed(io);
932     /// # }
933     /// # pub fn main() {}
934     /// ```
new_framed<T>(&self, inner: T) -> Framed<T, LengthDelimitedCodec> where T: AsyncRead + AsyncWrite,935     pub fn new_framed<T>(&self, inner: T) -> Framed<T, LengthDelimitedCodec>
936         where T: AsyncRead + AsyncWrite,
937     {
938         Framed::new(inner, self.new_codec())
939     }
940 
num_head_bytes(&self) -> usize941     fn num_head_bytes(&self) -> usize {
942         let num = self.length_field_offset + self.length_field_len;
943         cmp::max(num, self.num_skip.unwrap_or(0))
944     }
945 
get_num_skip(&self) -> usize946     fn get_num_skip(&self) -> usize {
947         self.num_skip.unwrap_or(self.length_field_offset + self.length_field_len)
948     }
949 }
950 
951 
952 // ===== impl FrameTooBig =====
953 
954 impl fmt::Debug for FrameTooBig {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result955     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
956         f.debug_struct("FrameTooBig")
957             .finish()
958     }
959 }
960 
961 impl fmt::Display for FrameTooBig {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result962     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
963         f.write_str(self.description())
964     }
965 }
966 
967 impl StdError for FrameTooBig {
description(&self) -> &str968     fn description(&self) -> &str {
969         "frame size too big"
970     }
971 }
972