1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/// ! `BufReader` 的缓冲区管理逻辑的封装。
///
/// 该模块将 `BufReader` 的基本功能分解出来,以保护两个 core 不,变体:
/// * `buf` 的 `filled` 字节总是被初始化
/// * `pos` 始终 <= `filled` 由于该模块封装了缓冲区管理逻辑,我们可以确保范围 `pos..filled` 始终是缓冲区初始化区域的有效索引。
/// 这意味着想要通过 `buffer` + `consume` 从 `BufReader` 读取的用户代码可以这样做而不会遇到任何运行时边界检查。
///
///
///
///
use crate::cmp;
use crate::io::{self, BorrowedBuf, Read};
use crate::mem::MaybeUninit;

pub struct Buffer {
    // 缓冲区。
    buf: Box<[MaybeUninit<u8>]>,
    // 当前 seek 偏移到 `buf` 中,必须始终 <= `filled`。
    pos: usize,
    // 每个调用到 `fill_buf` 设置 `filled` 以指示在 `buf` 的开头有多少字节被读取的字节初始化。
    //
    filled: usize,
    // 这是所有 `fill_buf` 调用返回的最大字节数。
    // 我们跟踪这一点,以便我们可以准确地告诉 `read_buf` 初始化了多少字节的 buf,以尽可能多地绕过它的防御性初始化。
    //
    // 请注意,虽然这通常与 `filled` 相同,但并非必须如此。
    // 对 `fill_buf` 的调用不需要实际填充缓冲区,对于不需要的 `Read` impls 来说,忽略这一点是一个巨大的性能回归。
    initialized: usize,
}

impl Buffer {
    #[inline]
    pub fn with_capacity(capacity: usize) -> Self {
        let buf = Box::new_uninit_slice(capacity);
        Self { buf, pos: 0, filled: 0, initialized: 0 }
    }

    #[inline]
    pub fn buffer(&self) -> &[u8] {
        // SAFETY: self.pos 和 self.cap 有效,并且 self.cap => self.pos,并且该区域被初始化,因为它们都是这种类型的不,变体。
        //
        unsafe { MaybeUninit::slice_assume_init_ref(self.buf.get_unchecked(self.pos..self.filled)) }
    }

    #[inline]
    pub fn capacity(&self) -> usize {
        self.buf.len()
    }

    #[inline]
    pub fn filled(&self) -> usize {
        self.filled
    }

    #[inline]
    pub fn pos(&self) -> usize {
        self.pos
    }

    // 这仅由断言初始化跟踪正确的测试使用。
    #[cfg(test)]
    pub fn initialized(&self) -> usize {
        self.initialized
    }

    #[inline]
    pub fn discard_buffer(&mut self) {
        self.pos = 0;
        self.filled = 0;
    }

    #[inline]
    pub fn consume(&mut self, amt: usize) {
        self.pos = cmp::min(self.pos + amt, self.filled);
    }

    /// 如果缓冲区中有 `amt` 字节可用,则将包含这些字节的切片传递给 `visitor` 并返回 true。
    /// 如果没有足够的可用字节,则返回 false。
    #[inline]
    pub fn consume_with<V>(&mut self, amt: usize, mut visitor: V) -> bool
    where
        V: FnMut(&[u8]),
    {
        if let Some(claimed) = self.buffer().get(..amt) {
            visitor(claimed);
            // 如果对 self.buffer() 的索引成功,amt 必须是一个有效的增量。
            self.pos += amt;
            true
        } else {
            false
        }
    }

    #[inline]
    pub fn unconsume(&mut self, amt: usize) {
        self.pos = self.pos.saturating_sub(amt);
    }

    #[inline]
    pub fn fill_buf(&mut self, mut reader: impl Read) -> io::Result<&[u8]> {
        // 如果我们已经到达内部缓冲区的末尾,那么我们需要从 reader 获取更多数据。
        // 使用 `>=` 而不是更正确的 `==` 进行分支,以告知编译器 pos..cap 切片始终有效。
        //
        //
        if self.pos >= self.filled {
            debug_assert!(self.pos == self.filled);

            let mut buf = BorrowedBuf::from(&mut *self.buf);
            // SAFETY: `self.filled` 字节将始终被初始化。
            unsafe {
                buf.set_init(self.initialized);
            }

            reader.read_buf(buf.unfilled())?;

            self.pos = 0;
            self.filled = buf.len();
            self.initialized = buf.init_len();
        }
        Ok(self.buffer())
    }
}