Coverage Report

Created: 2025-11-28 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/hyper-1.6.0/src/common/buf.rs
Line
Count
Source
1
use std::collections::VecDeque;
2
use std::io::IoSlice;
3
4
use bytes::{Buf, BufMut, Bytes, BytesMut};
5
6
pub(crate) struct BufList<T> {
7
    bufs: VecDeque<T>,
8
}
9
10
impl<T: Buf> BufList<T> {
11
0
    pub(crate) fn new() -> BufList<T> {
12
0
        BufList {
13
0
            bufs: VecDeque::new(),
14
0
        }
15
0
    }
16
17
    #[inline]
18
0
    pub(crate) fn push(&mut self, buf: T) {
19
0
        debug_assert!(buf.has_remaining());
20
0
        self.bufs.push_back(buf);
21
0
    }
22
23
    #[inline]
24
0
    pub(crate) fn bufs_cnt(&self) -> usize {
25
0
        self.bufs.len()
26
0
    }
27
}
28
29
impl<T: Buf> Buf for BufList<T> {
30
    #[inline]
31
0
    fn remaining(&self) -> usize {
32
0
        self.bufs.iter().map(|buf| buf.remaining()).sum()
33
0
    }
34
35
    #[inline]
36
0
    fn chunk(&self) -> &[u8] {
37
0
        self.bufs.front().map(Buf::chunk).unwrap_or_default()
38
0
    }
39
40
    #[inline]
41
0
    fn advance(&mut self, mut cnt: usize) {
42
0
        while cnt > 0 {
43
            {
44
0
                let front = &mut self.bufs[0];
45
0
                let rem = front.remaining();
46
0
                if rem > cnt {
47
0
                    front.advance(cnt);
48
0
                    return;
49
0
                } else {
50
0
                    front.advance(rem);
51
0
                    cnt -= rem;
52
0
                }
53
            }
54
0
            self.bufs.pop_front();
55
        }
56
0
    }
57
58
    #[inline]
59
0
    fn chunks_vectored<'t>(&'t self, dst: &mut [IoSlice<'t>]) -> usize {
60
0
        if dst.is_empty() {
61
0
            return 0;
62
0
        }
63
0
        let mut vecs = 0;
64
0
        for buf in &self.bufs {
65
0
            vecs += buf.chunks_vectored(&mut dst[vecs..]);
66
0
            if vecs == dst.len() {
67
0
                break;
68
0
            }
69
        }
70
0
        vecs
71
0
    }
72
73
    #[inline]
74
0
    fn copy_to_bytes(&mut self, len: usize) -> Bytes {
75
        // Our inner buffer may have an optimized version of copy_to_bytes, and if the whole
76
        // request can be fulfilled by the front buffer, we can take advantage.
77
0
        match self.bufs.front_mut() {
78
0
            Some(front) if front.remaining() == len => {
79
0
                let b = front.copy_to_bytes(len);
80
0
                self.bufs.pop_front();
81
0
                b
82
            }
83
0
            Some(front) if front.remaining() > len => front.copy_to_bytes(len),
84
            _ => {
85
0
                assert!(len <= self.remaining(), "`len` greater than remaining");
86
0
                let mut bm = BytesMut::with_capacity(len);
87
0
                bm.put(self.take(len));
88
0
                bm.freeze()
89
            }
90
        }
91
0
    }
92
}
93
94
#[cfg(test)]
95
mod tests {
96
    use std::ptr;
97
98
    use super::*;
99
100
    fn hello_world_buf() -> BufList<Bytes> {
101
        BufList {
102
            bufs: vec![Bytes::from("Hello"), Bytes::from(" "), Bytes::from("World")].into(),
103
        }
104
    }
105
106
    #[test]
107
    fn to_bytes_shorter() {
108
        let mut bufs = hello_world_buf();
109
        let old_ptr = bufs.chunk().as_ptr();
110
        let start = bufs.copy_to_bytes(4);
111
        assert_eq!(start, "Hell");
112
        assert!(ptr::eq(old_ptr, start.as_ptr()));
113
        assert_eq!(bufs.chunk(), b"o");
114
        assert!(ptr::eq(old_ptr.wrapping_add(4), bufs.chunk().as_ptr()));
115
        assert_eq!(bufs.remaining(), 7);
116
    }
117
118
    #[test]
119
    fn to_bytes_eq() {
120
        let mut bufs = hello_world_buf();
121
        let old_ptr = bufs.chunk().as_ptr();
122
        let start = bufs.copy_to_bytes(5);
123
        assert_eq!(start, "Hello");
124
        assert!(ptr::eq(old_ptr, start.as_ptr()));
125
        assert_eq!(bufs.chunk(), b" ");
126
        assert_eq!(bufs.remaining(), 6);
127
    }
128
129
    #[test]
130
    fn to_bytes_longer() {
131
        let mut bufs = hello_world_buf();
132
        let start = bufs.copy_to_bytes(7);
133
        assert_eq!(start, "Hello W");
134
        assert_eq!(bufs.remaining(), 4);
135
    }
136
137
    #[test]
138
    fn one_long_buf_to_bytes() {
139
        let mut buf = BufList::new();
140
        buf.push(b"Hello World" as &[_]);
141
        assert_eq!(buf.copy_to_bytes(5), "Hello");
142
        assert_eq!(buf.chunk(), b" World");
143
    }
144
145
    #[test]
146
    #[should_panic(expected = "`len` greater than remaining")]
147
    fn buf_to_bytes_too_many() {
148
        hello_world_buf().copy_to_bytes(42);
149
    }
150
}