1use bytes::{Buf, BufMut, Bytes, BytesMut};
6use std::{
7 collections::VecDeque,
8 io::IoSlice,
9 iter::{FromIterator, FusedIterator},
10 sync::OnceLock,
11};
12
13#[derive(Clone, Debug, Default)]
17pub struct BufList {
18 bufs: VecDeque<Bytes>,
20
21 start_pos: OnceLock<Box<[u64]>>,
24}
25
26impl BufList {
27 #[inline]
29 pub fn new() -> Self {
30 Self::default()
31 }
32
33 #[inline]
34 pub(crate) fn get_start_pos(&self) -> &[u64] {
35 self.start_pos.get_or_init(|| {
36 let mut start_pos = Vec::with_capacity(self.bufs.len() + 1);
37 let mut next = 0u64;
38 for chunk in self.bufs.iter() {
39 start_pos.push(next);
40 next += chunk.len() as u64;
41 }
42 start_pos.push(next);
44 start_pos.into_boxed_slice()
45 })
46 }
47
48 #[inline]
50 pub fn with_capacity(capacity: usize) -> Self {
51 Self {
52 bufs: VecDeque::with_capacity(capacity),
53 start_pos: OnceLock::new(),
54 }
55 }
56
57 #[inline]
68 pub fn num_chunks(&self) -> usize {
69 self.bufs.len()
70 }
71
72 #[inline]
83 pub fn num_bytes(&self) -> usize {
84 self.remaining()
85 }
86
87 #[inline]
99 pub fn get_chunk(&self, index: usize) -> Option<&Bytes> {
100 self.bufs.get(index)
101 }
102
103 #[inline]
105 pub fn iter(&self) -> Iter<'_> {
106 Iter {
107 iter: self.bufs.iter(),
108 }
109 }
110
111 pub fn push_chunk<B: Buf>(&mut self, mut data: B) -> Bytes {
136 self.start_pos = OnceLock::new();
138
139 let len = data.remaining();
140 let bytes = data.copy_to_bytes(len);
145
146 if len > 0 {
148 self.bufs.push_back(bytes.clone());
149 }
150
151 bytes
153 }
154}
155
156impl<B: Buf> Extend<B> for BufList {
157 fn extend<T: IntoIterator<Item = B>>(&mut self, iter: T) {
158 self.start_pos = OnceLock::new();
160
161 for buf in iter.into_iter() {
162 self.push_chunk(buf);
163 }
164 }
165}
166
167impl<B: Buf> FromIterator<B> for BufList {
168 fn from_iter<T: IntoIterator<Item = B>>(iter: T) -> Self {
169 let mut buf_list = BufList::new();
170 for buf in iter.into_iter() {
171 buf_list.push_chunk(buf);
172 }
173 buf_list
174 }
175}
176
177impl IntoIterator for BufList {
178 type Item = Bytes;
179 type IntoIter = IntoIter;
180
181 #[inline]
182 fn into_iter(self) -> Self::IntoIter {
183 IntoIter {
184 iter: self.bufs.into_iter(),
185 }
186 }
187}
188
189impl<'a> IntoIterator for &'a BufList {
190 type Item = &'a Bytes;
191 type IntoIter = Iter<'a>;
192
193 #[inline]
194 fn into_iter(self) -> Self::IntoIter {
195 self.iter()
196 }
197}
198
199impl AsRef<BufList> for BufList {
200 fn as_ref(&self) -> &BufList {
201 self
202 }
203}
204
205impl Buf for BufList {
206 fn remaining(&self) -> usize {
207 self.bufs.iter().map(Buf::remaining).sum()
208 }
209
210 fn chunk(&self) -> &[u8] {
211 self.bufs.front().map(Buf::chunk).unwrap_or(&[])
212 }
213
214 fn chunks_vectored<'iovs>(&'iovs self, iovs: &mut [IoSlice<'iovs>]) -> usize {
215 if iovs.is_empty() {
217 return 0;
218 }
219
220 let mut filled = 0;
223 for buf in &self.bufs {
224 filled += buf.chunks_vectored(&mut iovs[filled..]);
225 if filled == iovs.len() {
226 return filled;
227 }
228 }
229
230 filled
231 }
232
233 fn advance(&mut self, mut amt: usize) {
234 self.start_pos = OnceLock::new();
236
237 while amt > 0 {
238 let rem = self.bufs[0].remaining();
239 if rem > amt {
243 self.bufs[0].advance(amt);
244 return;
245 }
246
247 self.bufs[0].advance(rem);
250 amt -= rem;
251
252 self.bufs.pop_front();
253 }
254 }
255
256 fn copy_to_bytes(&mut self, len: usize) -> Bytes {
257 self.start_pos = OnceLock::new();
259
260 match self.bufs.front_mut() {
264 Some(first) if len <= first.remaining() => {
265 let buf = first.copy_to_bytes(len);
266 if first.remaining() == 0 {
269 self.bufs.pop_front();
270 }
271
272 buf
273 }
274 _ => {
275 assert!(
276 len <= self.remaining(),
277 "`len` ({}) greater than remaining ({})",
278 len,
279 self.remaining()
280 );
281 let mut buf = BytesMut::with_capacity(len);
282 buf.put(self.take(len));
283 buf.freeze()
284 }
285 }
286 }
287}
288
289impl<T: Into<Bytes>> From<T> for BufList {
290 fn from(value: T) -> Self {
291 let mut buf_list = BufList::with_capacity(1);
292 buf_list.push_chunk(value.into());
293 buf_list
294 }
295}
296
297#[derive(Clone, Debug)]
301pub struct IntoIter {
302 iter: std::collections::vec_deque::IntoIter<Bytes>,
303}
304
305impl Iterator for IntoIter {
306 type Item = Bytes;
307
308 #[inline]
309 fn next(&mut self) -> Option<Self::Item> {
310 self.iter.next()
311 }
312
313 #[inline]
314 fn size_hint(&self) -> (usize, Option<usize>) {
315 self.iter.size_hint()
316 }
317}
318
319impl DoubleEndedIterator for IntoIter {
320 #[inline]
321 fn next_back(&mut self) -> Option<Self::Item> {
322 self.iter.next_back()
323 }
324}
325
326impl ExactSizeIterator for IntoIter {
327 #[inline]
328 fn len(&self) -> usize {
329 self.iter.len()
330 }
331}
332
333impl FusedIterator for IntoIter {}
334
335#[derive(Clone, Debug)]
339pub struct Iter<'a> {
340 iter: std::collections::vec_deque::Iter<'a, Bytes>,
341}
342
343impl<'a> Iterator for Iter<'a> {
344 type Item = &'a Bytes;
345
346 #[inline]
347 fn next(&mut self) -> Option<Self::Item> {
348 self.iter.next()
349 }
350
351 #[inline]
355 fn size_hint(&self) -> (usize, Option<usize>) {
356 self.iter.size_hint()
357 }
358
359 #[inline]
361 fn fold<B, F>(self, init: B, f: F) -> B
362 where
363 Self: Sized,
364 F: FnMut(B, Self::Item) -> B,
365 {
366 self.iter.fold(init, f)
367 }
368
369 #[inline]
372 fn nth(&mut self, n: usize) -> Option<Self::Item> {
373 self.iter.nth(n)
374 }
375
376 #[inline]
377 fn last(self) -> Option<Self::Item>
378 where
379 Self: Sized,
380 {
381 self.iter.last()
382 }
383}
384
385impl<'a> DoubleEndedIterator for Iter<'a> {
386 #[inline]
387 fn next_back(&mut self) -> Option<Self::Item> {
388 self.iter.next_back()
389 }
390
391 #[inline]
392 fn rfold<B, F>(self, init: B, f: F) -> B
393 where
394 Self: Sized,
395 F: FnMut(B, Self::Item) -> B,
396 {
397 self.iter.rfold(init, f)
398 }
399
400 }
402
403impl<'a> ExactSizeIterator for Iter<'a> {
404 #[inline]
405 fn len(&self) -> usize {
406 self.iter.len()
407 }
408}
409
410impl<'a> FusedIterator for Iter<'a> {}