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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
#![unstable(feature = "read_buf", issue = "78485")]

#[cfg(test)]
mod tests;

use crate::fmt::{self, Debug, Formatter};
use crate::io::{Result, Write};
use crate::mem::{self, MaybeUninit};
use crate::{cmp, ptr};

/// 增量填充和初始化的借用字节缓冲区。
///
/// 这种类型是一种 "double cursor"。
/// 它跟踪缓冲区中的三个区域:缓冲区开头的区域已被逻辑填充数据,已在某个时刻初始化但尚未逻辑填充的区域,以及完全未初始化的末尾区域。
///
/// 填充区域保证是初始化区域的子集。
///
/// 总之,缓冲区的内容可以可视化为:
///
/// ```not_rust
/// [             capacity              ]
/// [ filled |         unfilled         ]
/// [    initialized    | uninitialized ]
/// ```
///
/// `BorrowedBuf` 是通过一个独特的引用 (`&mut`) 围绕一些现有数据 (或数据容量) 创建的。`BorrowedBuf` 可以配置 (例如,使用 `clear` 或 `set_init`),但不能直接写入。
/// 要写入缓冲区,请使用 `unfilled` 创建一个 `BorrowedCursor`。
/// 游标对缓冲区的未填充部分具有只写访问权限 (您可以将其视为只写迭代器)。
///
/// 生命周期 `'data` 是,底层,数据的生命周期的界限。
///
pub struct BorrowedBuf<'data> {
    /// 缓冲区的,底层,数据。
    buf: &'data mut [MaybeUninit<u8>],
    /// 已知要填充的 `self.buf` 的长度。
    filled: usize,
    /// 已知要初始化的 `self.buf` 的长度。
    init: usize,
}

impl Debug for BorrowedBuf<'_> {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        f.debug_struct("BorrowedBuf")
            .field("init", &self.init)
            .field("filled", &self.filled)
            .field("capacity", &self.capacity())
            .finish()
    }
}

/// 从完全初始化的切片创建一个新的 `BorrowedBuf`。
impl<'data> From<&'data mut [u8]> for BorrowedBuf<'data> {
    #[inline]
    fn from(slice: &'data mut [u8]) -> BorrowedBuf<'data> {
        let len = slice.len();

        BorrowedBuf {
            // SAFETY: 初始化数据永远不会变为未初始化是 BorrowedBuf 的不,变体
            buf: unsafe { (slice as *mut [u8]).as_uninit_slice_mut().unwrap() },
            filled: 0,
            init: len,
        }
    }
}

/// 从未初始化的缓冲区创建一个新的 `BorrowedBuf`。
///
/// 如果已知缓冲区的一部分已经初始化,则使用 `set_init`。
impl<'data> From<&'data mut [MaybeUninit<u8>]> for BorrowedBuf<'data> {
    #[inline]
    fn from(buf: &'data mut [MaybeUninit<u8>]) -> BorrowedBuf<'data> {
        BorrowedBuf { buf, filled: 0, init: 0 }
    }
}

impl<'data> BorrowedBuf<'data> {
    /// 返回缓冲区的总容量。
    #[inline]
    pub fn capacity(&self) -> usize {
        self.buf.len()
    }

    /// 返回缓冲区填充部分的长度。
    #[inline]
    pub fn len(&self) -> usize {
        self.filled
    }

    /// 返回缓冲区初始化部分的长度。
    #[inline]
    pub fn init_len(&self) -> usize {
        self.init
    }

    /// 返回对缓冲区填充部分的共享引用。
    #[inline]
    pub fn filled(&self) -> &[u8] {
        // SAFETY: 我们只对缓冲区的填充部分进行切片,这总是有效的
        unsafe { MaybeUninit::slice_assume_init_ref(&self.buf[0..self.filled]) }
    }

    /// 返回缓冲区未填充部分上的游标。
    #[inline]
    pub fn unfilled<'this>(&'this mut self) -> BorrowedCursor<'this> {
        BorrowedCursor {
            start: self.filled,
            // SAFETY: 我们从不分配给 `BorrowedCursor::buf`,因此以协变方式处理其生命周期是安全的。
            //
            buf: unsafe {
                mem::transmute::<&'this mut BorrowedBuf<'data>, &'this mut BorrowedBuf<'this>>(self)
            },
        }
    }

    /// 清除缓冲区,将填充区域重置为空。
    ///
    /// 初始化的字节数不变,缓冲区的内容也不变。
    #[inline]
    pub fn clear(&mut self) -> &mut Self {
        self.filled = 0;
        self
    }

    /// 断言缓冲区的前 `n` 个字节已初始化。
    ///
    /// `BorrowedBuf` 假定字节永远不会被取消初始化,因此当调用该方法时使用的字节数少于已知要初始化的字节数时,该方法什么也不做。
    ///
    ///
    /// # Safety
    ///
    /// 调用者必须确保缓冲区的前 `n` 个未填充字节已经初始化。
    #[inline]
    pub unsafe fn set_init(&mut self, n: usize) -> &mut Self {
        self.init = cmp::max(self.init, n);
        self
    }
}

/// [`BorrowedBuf`](BorrowedBuf) 未填充部分的可写视图。
///
/// 提供对底层 `BorrowedBuf` 的已初始化和未初始化部分的访问。
/// 可以使用 [`append`](BorrowedCursor::append) 将数据直接写入游标,也可以通过获取部分或全部游标的切片并写入切片来间接写入数据。
///
/// 在间接情况下,调用者必须在写入后调用 [`advance`](BorrowedCursor::advance) 来通知游标已经写入了多少字节。
///
/// 一旦数据被写入游标,它就成为底层 `BorrowedBuf` 的填充部分的一部分,并且不能再被游标访问或重写。
/// 即,游标跟踪底层 `BorrowedBuf` 的未填充部分。
///
/// 生命周期 `'a` 是底层缓冲区的生命周期的界限 (这意味着它是该缓冲区中数据的传递界限)。
///
///
///
#[derive(Debug)]
pub struct BorrowedCursor<'a> {
    /// 底层缓冲区。
    // 安全不,变体: 当我们创建一个 `BorrowedCursor` 时,我们将 buf 的类型视为 `BorrowedBuf` 的生命周期中的协,变体。
    // 只有当我们从不通过分配来替换 `buf` 时,这才是安全的,所以不要那样做!
    //
    buf: &'a mut BorrowedBuf<'a>,
    /// 创建游标时,底层,缓冲区的填充部分的长度。
    ///
    start: usize,
}

impl<'a> BorrowedCursor<'a> {
    /// 通过使用较小的生命周期克隆它来重新借用此游标。
    ///
    /// 由于游标保持对其底层缓冲区的唯一访问,因此当新游标存在时,借用的游标不可访问。
    ///
    #[inline]
    pub fn reborrow<'this>(&'this mut self) -> BorrowedCursor<'this> {
        BorrowedCursor {
            // SAFETY: 我们从不分配给 `BorrowedCursor::buf`,因此以协变方式处理其生命周期是安全的。
            //
            buf: unsafe {
                mem::transmute::<&'this mut BorrowedBuf<'a>, &'this mut BorrowedBuf<'this>>(
                    self.buf,
                )
            },
            start: self.start,
        }
    }

    /// 返回游标中的可用空间。
    #[inline]
    pub fn capacity(&self) -> usize {
        self.buf.capacity() - self.buf.filled
    }

    /// 返回自从 `BorrowedBuf` 创建以来写入此游标的字节数。
    ///
    /// 请注意,如果此游标是另一个游标的重新借用克隆,则返回的计数是通过任一游标写入的计数,而不是自游标重新借用以来的计数。
    ///
    #[inline]
    pub fn written(&self) -> usize {
        self.buf.filled - self.start
    }

    /// 将共享引用返回到游标的初始化部分。
    #[inline]
    pub fn init_ref(&self) -> &[u8] {
        // SAFETY: 我们只对缓冲区的初始化部分进行切片,这始终是有效的
        unsafe { MaybeUninit::slice_assume_init_ref(&self.buf.buf[self.buf.filled..self.buf.init]) }
    }

    /// 返回游标的初始化部分的,可变引用。
    #[inline]
    pub fn init_mut(&mut self) -> &mut [u8] {
        // SAFETY: 我们只对缓冲区的初始化部分进行切片,这始终是有效的
        unsafe {
            MaybeUninit::slice_assume_init_mut(&mut self.buf.buf[self.buf.filled..self.buf.init])
        }
    }

    /// 将一个,可变引用,返回到游标的未初始化部分。
    ///
    /// 取消初始化这些字节中的任何一个都是安全的。
    #[inline]
    pub fn uninit_mut(&mut self) -> &mut [MaybeUninit<u8>] {
        &mut self.buf.buf[self.buf.init..]
    }

    /// 返回对整个游标的引用。
    ///
    /// # Safety
    ///
    /// 调用者不得取消初始化游标初始化部分中的任何字节。
    #[inline]
    pub unsafe fn as_mut(&mut self) -> &mut [MaybeUninit<u8>] {
        &mut self.buf.buf[self.buf.filled..]
    }

    /// 通过断言 `n` 字节已被填充来前进游标。
    ///
    /// 推进后,`n` 字节不再可以通过游标访问,只能通过底层缓冲区访问。
    /// 即,缓冲区的填充部分增加了 `n` 个元素,而其未填充部分 (以及该游标的容量) 缩小了 `n` 个元素。
    ///
    ///
    /// # Safety
    ///
    /// 调用者必须确保游标的前 `n` 字节已正确初始化。
    ///
    #[inline]
    pub unsafe fn advance(&mut self, n: usize) -> &mut Self {
        self.buf.filled += n;
        self.buf.init = cmp::max(self.buf.init, self.buf.filled);
        self
    }

    /// 初始化游标中的所有字节。
    #[inline]
    pub fn ensure_init(&mut self) -> &mut Self {
        let uninit = self.uninit_mut();
        // SAFETY: 0 是 MaybeUninit<u8> 的有效值,并且长度与分配匹配,因为它来自切片引用。
        //
        unsafe {
            ptr::write_bytes(uninit.as_mut_ptr(), 0, uninit.len());
        }
        self.buf.init = self.buf.capacity();

        self
    }

    /// 断言游标的前 `n` 个未填充字节已初始化。
    ///
    /// `BorrowedBuf` 假定字节永远不会被取消初始化,因此当调用该方法时使用的字节数少于已知要初始化的字节数时,该方法什么也不做。
    ///
    ///
    /// # Safety
    ///
    /// 调用者必须确保缓冲区的前 `n` 个字节已经被初始化。
    #[inline]
    pub unsafe fn set_init(&mut self, n: usize) -> &mut Self {
        self.buf.init = cmp::max(self.buf.init, self.buf.filled + n);
        self
    }

    /// 将数据,追加,到游标,在其缓冲区中推进位置。
    ///
    /// # Panics
    ///
    /// 如果 `self.capacity()` 小于 `buf.len()`,则发生 panic。
    #[inline]
    pub fn append(&mut self, buf: &[u8]) {
        assert!(self.capacity() >= buf.len());

        // SAFETY: 我们不会取消初始化切片的任何元素
        unsafe {
            MaybeUninit::write_slice(&mut self.as_mut()[..buf.len()], buf);
        }

        // SAFETY: 我们只是将 buf 的全部内容添加到了填充部分。
        unsafe {
            self.set_init(buf.len());
        }
        self.buf.filled += buf.len();
    }
}

impl<'a> Write for BorrowedCursor<'a> {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        self.append(buf);
        Ok(buf.len())
    }

    fn flush(&mut self) -> Result<()> {
        Ok(())
    }
}