1 use std::collections::VecDeque;
2 use std::io::IoSlice;
3 
4 use bytes::Buf;
5 
6 pub(crate) struct BufList<T> {
7     bufs: VecDeque<T>,
8 }
9 
10 impl<T: Buf> BufList<T> {
new() -> BufList<T>11     pub(crate) fn new() -> BufList<T> {
12         BufList {
13             bufs: VecDeque::new(),
14         }
15     }
16 
17     #[inline]
push(&mut self, buf: T)18     pub(crate) fn push(&mut self, buf: T) {
19         debug_assert!(buf.has_remaining());
20         self.bufs.push_back(buf);
21     }
22 
23     #[inline]
bufs_cnt(&self) -> usize24     pub(crate) fn bufs_cnt(&self) -> usize {
25         self.bufs.len()
26     }
27 }
28 
29 impl<T: Buf> Buf for BufList<T> {
30     #[inline]
remaining(&self) -> usize31     fn remaining(&self) -> usize {
32         self.bufs.iter().map(|buf| buf.remaining()).sum()
33     }
34 
35     #[inline]
bytes(&self) -> &[u8]36     fn bytes(&self) -> &[u8] {
37         self.bufs.front().map(Buf::bytes).unwrap_or_default()
38     }
39 
40     #[inline]
advance(&mut self, mut cnt: usize)41     fn advance(&mut self, mut cnt: usize) {
42         while cnt > 0 {
43             {
44                 let front = &mut self.bufs[0];
45                 let rem = front.remaining();
46                 if rem > cnt {
47                     front.advance(cnt);
48                     return;
49                 } else {
50                     front.advance(rem);
51                     cnt -= rem;
52                 }
53             }
54             self.bufs.pop_front();
55         }
56     }
57 
58     #[inline]
bytes_vectored<'t>(&'t self, dst: &mut [IoSlice<'t>]) -> usize59     fn bytes_vectored<'t>(&'t self, dst: &mut [IoSlice<'t>]) -> usize {
60         if dst.is_empty() {
61             return 0;
62         }
63         let mut vecs = 0;
64         for buf in &self.bufs {
65             vecs += buf.bytes_vectored(&mut dst[vecs..]);
66             if vecs == dst.len() {
67                 break;
68             }
69         }
70         vecs
71     }
72 }
73