更新NbtReader的read_f32_unchecked和read_f64_unchecked方法的文档

This commit is contained in:
shenjack 2024-03-08 20:54:21 +08:00
parent 28f76ad4ad
commit be3fbe811a
Signed by: shenjack
GPG Key ID: 7B1134A979775551
2 changed files with 57 additions and 51 deletions

View File

@ -16,36 +16,37 @@ pub struct NbtReader<'data> {
// pub endian: Endian,
}
macro_rules! read {
macro_rules! read_uncheck {
($name:ident, $ty:ty, $size:literal) => {
#[doc = concat!("读取 ", stringify!($ty), " 类型 ", $size, " 长度的数据")]
///
#[doc = "转换大小端"]
pub fn $name(&mut self) -> $ty {
unsafe {
// 使用 std::ptr::read_unaligned 解决未对齐地址问题
let value =
std::ptr::read_unaligned(self.data[self.cursor..].as_ptr() as *const $ty);
self.cursor += std::mem::size_of::<$ty>();
value.to_be()
}
}
};
($name:ident, $ty:ty, $size:literal, false) => {
#[doc = concat!("读取 ", stringify!($ty), " 类型 ", $size, " 长度的数据")]
///
#[doc = "不转换大小端"]
pub fn $name(&mut self) -> $ty {
unsafe {
// 使用 std::ptr::read_unaligned 解决未对齐地址问题
let value =
std::ptr::read_unaligned(self.data[self.cursor..].as_ptr() as *const $ty);
self.cursor += std::mem::size_of::<$ty>();
value
}
///
/// # 安全性
/// 允许未对齐的地址
/// 长度溢出会导致 UB
pub unsafe fn $name(&mut self) -> $ty {
// 使用 std::ptr::read_unaligned 解决未对齐地址问题
let value = std::ptr::read_unaligned(self.data[self.cursor..].as_ptr() as *const $ty);
self.cursor += std::mem::size_of::<$ty>();
value.to_be()
}
};
}
macro_rules! read {
($name:ident, $ty:ty, $size:literal) => {
#[doc = concat!("读取 ", stringify!($ty), " 类型 ", $size, " 长度的数据")]
pub fn $name(&mut self) -> $ty {
let value = self.data[self.cursor..self.cursor + $size]
.iter()
.fold(0, |acc, &x| (acc << 8) | x as $ty);
self.cursor += $size;
value
}
};
}
impl NbtReader<'_> {
pub fn new(data: &mut [u8]) -> NbtReader {
NbtReader {
@ -64,14 +65,35 @@ impl NbtReader<'_> {
/// 读取一个 i8 类型的数据
#[inline]
pub fn read_i8(&mut self) -> i8 { self.read_u8() as i8 }
read!(read_i16_unchecked, i16, 2);
read!(read_u16_unchecked, u16, 2);
read!(read_i32_unchecked, i32, 4);
read!(read_u32_unchecked, u32, 4);
read!(read_i64_unchecked, i64, 8);
read!(read_u64_unchecked, u64, 8);
read!(read_f32_unchecked, f32, 4, false);
read!(read_f64_unchecked, f64, 8, false);
read_uncheck!(read_i16_unchecked, i16, 2);
read_uncheck!(read_u16_unchecked, u16, 2);
read_uncheck!(read_i32_unchecked, i32, 4);
read_uncheck!(read_u32_unchecked, u32, 4);
read_uncheck!(read_i64_unchecked, i64, 8);
read_uncheck!(read_u64_unchecked, u64, 8);
/// 读取一个 f32 类型的数据
///
/// 转换大小端
///
/// # 安全性
/// 允许未对齐的地址
/// 长度溢出会导致 UB
pub unsafe fn read_f32_unchecked(&mut self) -> f32 {
let value = std::ptr::read_unaligned(self.data[self.cursor..].as_ptr() as *const u32);
self.cursor += 4;
f32::from_bits(value.to_be())
}
/// 读取一个 f64 类型的数据
/// 转换大小端
///
/// # 安全性
/// 允许未对齐的地址
/// 长度溢出会导致 UB
pub unsafe fn read_f64_unchecked(&mut self) -> f64 {
let value = std::ptr::read_unaligned(self.data[self.cursor..].as_ptr() as *const u64);
self.cursor += 8;
f64::from_bits(value.to_be())
}
pub fn read_u8_array(&mut self, len: usize) -> &[u8] {
let value = &self.data[self.cursor..self.cursor + len];

View File

@ -39,32 +39,16 @@ fn read_one_bytes() {
}
#[test]
fn read_data_unchecked() {
let mut datas = gen_datas(100);
let mut reader = NbtReader::new(&mut datas);
fn read_data_safe() {
let mut data = vec![0x01, 0x02, 0x03, 0x04];
let mut reader = NbtReader::new(&mut data);
assert_eq!(reader.read_u8(), 0x00);
assert_eq!(reader.cursor, 1);
assert_eq!(reader.read_i8(), 0x01);
assert_eq!(reader.cursor, 2);
assert_eq!(reader.read_u8(), 0x02);
assert_eq!(reader.cursor, 3);
assert_eq!(reader.read_i16_unchecked(), 0x0304);
assert_eq!(reader.cursor, 5);
assert_eq!(reader.read_u16_unchecked(), 0x0506);
assert_eq!(reader.cursor, 7);
assert_eq!(reader.read_i32_unchecked(), 0x0708090A);
assert_eq!(reader.cursor, 11);
assert_eq!(reader.read_u32_unchecked(), 0x0B0C0D0E);
assert_eq!(reader.cursor, 15);
assert_eq!(reader.read_i64_unchecked(), 0x0F10111213141516);
assert_eq!(reader.cursor, 23);
assert_eq!(reader.read_u64_unchecked(), 0x1718191A1B1C1D1E);
assert_eq!(reader.cursor, 31);
assert_eq!(reader.read_f32_unchecked().to_ne_bytes(), [0x1F, 0x20, 0x21, 0x22]);
assert_eq!(
reader.read_f64_unchecked().to_ne_bytes(),
[0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A]
);
}
#[test]