1 use std
::collections
::VecDeque
;
4 use bytes
::{Buf, BufMut, Bytes, BytesMut}
;
6 pub(crate) struct BufList
<T
> {
10 impl<T
: Buf
> BufList
<T
> {
11 pub(crate) fn new() -> BufList
<T
> {
13 bufs
: VecDeque
::new(),
18 pub(crate) fn push(&mut self, buf
: T
) {
19 debug_assert
!(buf
.has_remaining());
20 self.bufs
.push_back(buf
);
24 #[cfg(feature = "http1")]
25 pub(crate) fn bufs_cnt(&self) -> usize {
30 impl<T
: Buf
> Buf
for BufList
<T
> {
32 fn remaining(&self) -> usize {
33 self.bufs
.iter().map(|buf
| buf
.remaining()).sum()
37 fn chunk(&self) -> &[u8] {
38 self.bufs
.front().map(Buf
::chunk
).unwrap_or_default()
42 fn advance(&mut self, mut cnt
: usize) {
45 let front
= &mut self.bufs
[0];
46 let rem
= front
.remaining();
55 self.bufs
.pop_front();
60 fn chunks_vectored
<'t
>(&'t
self, dst
: &mut [IoSlice
<'t
>]) -> usize {
65 for buf
in &self.bufs
{
66 vecs
+= buf
.chunks_vectored(&mut dst
[vecs
..]);
67 if vecs
== dst
.len() {
75 fn copy_to_bytes(&mut self, len
: usize) -> Bytes
{
76 // Our inner buffer may have an optimized version of copy_to_bytes, and if the whole
77 // request can be fulfilled by the front buffer, we can take advantage.
78 match self.bufs
.front_mut() {
79 Some(front
) if front
.remaining() == len
=> {
80 let b
= front
.copy_to_bytes(len
);
81 self.bufs
.pop_front();
84 Some(front
) if front
.remaining() > len
=> front
.copy_to_bytes(len
),
86 assert
!(len
<= self.remaining(), "`len` greater than remaining");
87 let mut bm
= BytesMut
::with_capacity(len
);
88 bm
.put(self.take(len
));
101 fn hello_world_buf() -> BufList
<Bytes
> {
103 bufs
: vec
![Bytes
::from("Hello"), Bytes
::from(" "), Bytes
::from("World")].into(),
108 fn to_bytes_shorter() {
109 let mut bufs
= hello_world_buf();
110 let old_ptr
= bufs
.chunk().as_ptr();
111 let start
= bufs
.copy_to_bytes(4);
112 assert_eq
!(start
, "Hell");
113 assert
!(ptr
::eq(old_ptr
, start
.as_ptr()));
114 assert_eq
!(bufs
.chunk(), b
"o");
115 assert
!(ptr
::eq(old_ptr
.wrapping_add(4), bufs
.chunk().as_ptr()));
116 assert_eq
!(bufs
.remaining(), 7);
121 let mut bufs
= hello_world_buf();
122 let old_ptr
= bufs
.chunk().as_ptr();
123 let start
= bufs
.copy_to_bytes(5);
124 assert_eq
!(start
, "Hello");
125 assert
!(ptr
::eq(old_ptr
, start
.as_ptr()));
126 assert_eq
!(bufs
.chunk(), b
" ");
127 assert_eq
!(bufs
.remaining(), 6);
131 fn to_bytes_longer() {
132 let mut bufs
= hello_world_buf();
133 let start
= bufs
.copy_to_bytes(7);
134 assert_eq
!(start
, "Hello W");
135 assert_eq
!(bufs
.remaining(), 4);
139 fn one_long_buf_to_bytes() {
140 let mut buf
= BufList
::new();
141 buf
.push(b
"Hello World" as &[_
]);
142 assert_eq
!(buf
.copy_to_bytes(5), "Hello");
143 assert_eq
!(buf
.chunk(), b
" World");
147 #[should_panic(expected = "`len` greater than remaining")]
148 fn buf_to_bytes_too_many() {
149 hello_world_buf().copy_to_bytes(42);