3 个版本 (破坏性更新)
0.3.0 | 2023年3月2日 |
---|---|
0.1.0 | 2022年11月2日 |
0.0.0 | 2022年11月2日 |
#1 in #filled
24KB
335 行代码,不包括注释
owned-buf
用于读取可能未初始化内存的拥有型缓冲区类型。是 BorrowedBuf
的拥有等效类型。
lib.rs
:
一个拥有型、固定长度的字节(u8
)缓冲区及辅助类型。
主要类型是 OwnedBuf
,它是一个拥有字节的抽象包装类型。 OwnedSlice
和 OwnedCursor
分别提供对 OwnedBuf
已填充部分的读取访问和对未填充部分的写入访问。
OwnedBuf
主要用于IO操作获取提供缓冲区的所有权的场景,例如 async OwnedRead
。
OwnedBuf
的数据可以是已填充的(即,数据已写入字节)或未填充的。未填充的数据可以是初始化或未初始化的。一个 OwnedBuf
可以同时包含这三种类型的数据,并跟踪字节的状况。
生命周期
OwnedBuf
永远不会直接创建。相反,一个现有的字节序列(例如,一个 Vec<u8>
)被转换为一个 OwnedBuf
。与切片不同,之前的序列类型被消耗,其内存的所有权转移到 OwnedBuf
(内存本身不移动)。
然后使用 OwnedBuf
。它被转换为一个 OwnedCursor
来写入,并转换为一个 OwnedSlice
来读取。这些类型可以根据需要转换回 OwnedBuf
。每次转换时,所有权都传递到新的类型。如果需要,可以重置 OwnedBuf
。
OwnedBuf
可以转换回原始序列类型。写入到 OwnedBuf
的任何数据都可以读取。序列类型可以用通常的方式使用,包括其销毁。如果一个 OwnedBuf
没有转换回先前的类型,那么它的析构函数会在创建缓冲区时调用一个函数。通常,这会将缓冲区转换回原始序列类型并调用其析构函数。
析构函数安全性
OwnedBuf
将析构函数作为一个函数指针,并在OwnedBuf
的析构函数中调用它。函数指针被标记为unsafe
,安全性不变量是OwnedBuf
是由析构函数期望的集合类型创建的。当OwnedBuf
被创建时,必须确保此不变量,因此OwnedBuf::new
是unsafe
。
用户类型转换
本模块包含将OwnedBuf
从和到Vec<u8>
或Vec<MaybeUninit<u8>>
转换的功能。OwnedBuf
旨在与任何拥有字节的序列一起使用。要创建OwnedBuf
,请使用OwnedBuf::new
,您将提供数据指针、一些元数据和析构函数(见下文)。要从OwnedBuf
转换,您将使用into_raw_parts
来获取OwnedBuf
的内部状态,然后以通常的方式创建序列类型。
OwnedBuf
的析构函数类型为&'static dyn Fn(&mut OwnedBuf<A>)
,它传递对析构函数的引用,但是,可以保证在调用析构函数后不会访问OwnedBuf
。通常,析构函数将使用std::ptr::read
来获取OwnedBuf
的值,将其转换为原始序列类型,并隐式调用其析构函数。
字段
OwnedBuf
的字段是私有的,不能直接修改,这有助于确保安全性不变量。然而,使用new
创建OwnedBuf
或调用into_raw_parts
将公开所有其字段。这些字段仅用于实现与其他集合类型之间的转换,而不是用于最终用户。我们将在这里总结字段,而不是在多个函数中。
data: *mut MaybeUninit<u8>
缓冲区中数据的指针dtor: unsafe fn(&mut OwnedBuf)
基于后缓冲区的析构函数的函数指针user_data: *const ()
指向任何数据的指针,打算由self.dtor
使用capacity: usize
缓冲区的总大小filled: usize
已知的缓冲区中字节的数量init: usize
已知的缓冲区中已初始化的字节数量
示例
从 Vec
创建 OwnedBuf
let vec = vec![1u8, 2, 3];
let buf: OwnedBuf = vec.into();
// Use `filled` to view `buf` as an `OwnedSlice` to read from it.
assert_eq!(1, buf.filled()[0]);
// `Vec`'s destructor will be called via `OwnedBuf`'s.
向 OwnedBuf
写入并将它转换回 Vec
let vec: Vec<u8> = Vec::with_capacity(8);
let buf: OwnedBuf = vec.into();
assert_eq!(0, buf.filled_len());
assert_eq!(8, buf.capacity());
// Get a cursor to write into the `OwnedBuf`.
let mut cursor = buf.unfilled();
cursor.write_slice(&[0, 1, 2, 3]);
// Convert the cursor back into an `OwnedBuf`.
let buf = cursor.into_buf();
assert_eq!(4, buf.filled_len());
let vec = unsafe { buf.into_vec() };
assert_eq!(4, vec.len());
assert_eq!(8, vec.capacity());
assert_eq!(3, vec[3]);