优化读取函数,添加安全性检查和文档注释

This commit is contained in:
shenjack 2024-03-09 13:21:25 +08:00
parent be3fbe811a
commit 9437cc4cd9
Signed by: shenjack
GPG Key ID: 7B1134A979775551
2 changed files with 92 additions and 22 deletions

View File

@ -37,13 +37,7 @@ macro_rules! read_uncheck {
macro_rules! read { macro_rules! read {
($name:ident, $ty:ty, $size:literal) => { ($name:ident, $ty:ty, $size:literal) => {
#[doc = concat!("读取 ", stringify!($ty), " 类型 ", $size, " 长度的数据")] #[doc = concat!("读取 ", stringify!($ty), " 类型 ", $size, " 长度的数据")]
pub fn $name(&mut self) -> $ty { pub fn $name(&mut self) -> $ty { let buff = &self.data[self.cursor..self.cursor + $size]; }
let value = self.data[self.cursor..self.cursor + $size]
.iter()
.fold(0, |acc, &x| (acc << 8) | x as $ty);
self.cursor += $size;
value
}
}; };
} }
@ -71,6 +65,68 @@ impl NbtReader<'_> {
read_uncheck!(read_u32_unchecked, u32, 4); read_uncheck!(read_u32_unchecked, u32, 4);
read_uncheck!(read_i64_unchecked, i64, 8); read_uncheck!(read_i64_unchecked, i64, 8);
read_uncheck!(read_u64_unchecked, u64, 8); read_uncheck!(read_u64_unchecked, u64, 8);
/// 安全的读取 i16 类型的数据
///
/// 转换大小端(大端)
///
/// 会在超出长度时 panic
pub fn read_i16(&mut self) -> i16 {
let value = i16::from_be_bytes([self.data[self.cursor], self.data[self.cursor + 1]]);
self.cursor += 2;
value
}
/// 安全的读取 u16 类型的数据
///
/// 转换大小端(大端)
///
/// 会在超出长度时 panic
pub fn read_u16(&mut self) -> u16 { self.read_i16() as u16 }
/// 安全的读取 i32 类型的数据
///
/// 转换大小端(大端)
///
/// 会在超出长度时 panic
pub fn read_i32(&mut self) -> i32 {
let value = i32::from_be_bytes([
self.data[self.cursor],
self.data[self.cursor + 1],
self.data[self.cursor + 2],
self.data[self.cursor + 3],
]);
self.cursor += 4;
value
}
/// 安全的读取 u32 类型的数据
///
/// 转换大小端(大端)
///
/// 会在超出长度时 panic
pub fn read_u32(&mut self) -> u32 { self.read_i32() as u32 }
/// 安全的读取 i64 类型的数据
///
/// 转换大小端(大端)
///
/// 会在超出长度时 panic
pub fn read_i64(&mut self) -> i64 {
let value = i64::from_be_bytes([
self.data[self.cursor],
self.data[self.cursor + 1],
self.data[self.cursor + 2],
self.data[self.cursor + 3],
self.data[self.cursor + 4],
self.data[self.cursor + 5],
self.data[self.cursor + 6],
self.data[self.cursor + 7],
]);
self.cursor += 8;
value
}
/// 安全的读取 u64 类型的数据
///
/// 转换大小端(大端)
///
/// 会在超出长度时 panic
pub fn read_u64(&mut self) -> u64 { self.read_i64() as u64 }
/// 读取一个 f32 类型的数据 /// 读取一个 f32 类型的数据
/// ///
/// 转换大小端 /// 转换大小端
@ -94,12 +150,21 @@ impl NbtReader<'_> {
self.cursor += 8; self.cursor += 8;
f64::from_bits(value.to_be()) f64::from_bits(value.to_be())
} }
/// 读取指定长度的 u8 数组
///
/// # 安全性
///
/// 长度溢出会导致 panic
pub fn read_u8_array(&mut self, len: usize) -> &[u8] { pub fn read_u8_array(&mut self, len: usize) -> &[u8] {
let value = &self.data[self.cursor..self.cursor + len]; let value = &self.data[self.cursor..self.cursor + len];
self.cursor += len; self.cursor += len;
value value
} }
/// 读取指定长度的 i8 数组
///
/// # 安全性
///
/// 长度溢出会导致 UB
pub fn read_i8_array(&mut self, len: usize) -> &[i8] { pub fn read_i8_array(&mut self, len: usize) -> &[i8] {
let value = unsafe { let value = unsafe {
std::slice::from_raw_parts(self.data[self.cursor..].as_ptr() as *const i8, len) std::slice::from_raw_parts(self.data[self.cursor..].as_ptr() as *const i8, len)
@ -107,12 +172,17 @@ impl NbtReader<'_> {
self.cursor += len; self.cursor += len;
value value
} }
/// 读取指定长度的 utf-8 字符串
///
/// # 安全性
///
/// 长度溢出会导致 panic
pub fn read_string(&mut self, len: usize) -> String { pub fn read_string(&mut self, len: usize) -> String {
let value = String::from_utf8_lossy(&self.data[self.cursor..self.cursor + len]); let value = String::from_utf8_lossy(&self.data[self.cursor..self.cursor + len]);
self.cursor += len; self.cursor += len;
value.into_owned() value.into_owned()
} }
pub fn read_int_array(&mut self, len: usize) -> &[i32] { pub fn read_i32_array_unchecked(&mut self, len: usize) -> &[i32] {
unsafe { unsafe {
println!("data: {:?}", self.data); println!("data: {:?}", self.data);
let value = let value =
@ -125,7 +195,7 @@ impl NbtReader<'_> {
value value
} }
} }
pub fn read_long_array(&mut self, len: usize) -> &[i64] { pub fn read_i64_array(&mut self, len: usize) -> &[i64] {
unsafe { unsafe {
println!("data: {:?}", self.data); println!("data: {:?}", self.data);
let value = let value =

View File

@ -65,7 +65,7 @@ fn read_array() {
fn read_int_array() { fn read_int_array() {
let mut value = 1234567890_i32.to_be_bytes(); let mut value = 1234567890_i32.to_be_bytes();
let mut reader = NbtReader::new(&mut value); let mut reader = NbtReader::new(&mut value);
assert_eq!(reader.read_int_array(1), &[1234567890_i32]); assert_eq!(reader.read_i32_array_unchecked(1), &[1234567890_i32]);
assert_eq!(reader.cursor, 4); assert_eq!(reader.cursor, 4);
} }
@ -73,6 +73,6 @@ fn read_int_array() {
fn read_long_array() { fn read_long_array() {
let mut value = 1234567890_i64.to_be_bytes(); let mut value = 1234567890_i64.to_be_bytes();
let mut reader = NbtReader::new(&mut value); let mut reader = NbtReader::new(&mut value);
assert_eq!(reader.read_long_array(1), &[1234567890_i64]); assert_eq!(reader.read_i64_array(1), &[1234567890_i64]);
assert_eq!(reader.cursor, 8); assert_eq!(reader.cursor, 8);
} }