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