优化NbtReader读取方法

This commit is contained in:
shenjack 2024-03-09 13:55:20 +08:00
parent 98cf4c77ee
commit 4c696d7178
Signed by: shenjack
GPG Key ID: 7B1134A979775551
2 changed files with 52 additions and 54 deletions

View File

@ -63,6 +63,7 @@ impl NbtReader<'_> {
/// 转换大小端(大端) /// 转换大小端(大端)
/// ///
/// 会在超出长度时 panic /// 会在超出长度时 panic
#[inline]
pub fn read_i16(&mut self) -> i16 { pub fn read_i16(&mut self) -> i16 {
let value = i16::from_be_bytes([self.data[self.cursor], self.data[self.cursor + 1]]); let value = i16::from_be_bytes([self.data[self.cursor], self.data[self.cursor + 1]]);
self.cursor += 2; self.cursor += 2;
@ -73,12 +74,14 @@ impl NbtReader<'_> {
/// 转换大小端(大端) /// 转换大小端(大端)
/// ///
/// 会在超出长度时 panic /// 会在超出长度时 panic
#[inline]
pub fn read_u16(&mut self) -> u16 { self.read_i16() as u16 } pub fn read_u16(&mut self) -> u16 { self.read_i16() as u16 }
/// 安全的读取 i32 类型的数据 /// 安全的读取 i32 类型的数据
/// ///
/// 转换大小端(大端) /// 转换大小端(大端)
/// ///
/// 会在超出长度时 panic /// 会在超出长度时 panic
#[inline]
pub fn read_i32(&mut self) -> i32 { pub fn read_i32(&mut self) -> i32 {
let value = i32::from_be_bytes([ let value = i32::from_be_bytes([
self.data[self.cursor], self.data[self.cursor],
@ -94,12 +97,14 @@ impl NbtReader<'_> {
/// 转换大小端(大端) /// 转换大小端(大端)
/// ///
/// 会在超出长度时 panic /// 会在超出长度时 panic
#[inline]
pub fn read_u32(&mut self) -> u32 { self.read_i32() as u32 } pub fn read_u32(&mut self) -> u32 { self.read_i32() as u32 }
/// 安全的读取 i64 类型的数据 /// 安全的读取 i64 类型的数据
/// ///
/// 转换大小端(大端) /// 转换大小端(大端)
/// ///
/// 会在超出长度时 panic /// 会在超出长度时 panic
#[inline]
pub fn read_i64(&mut self) -> i64 { pub fn read_i64(&mut self) -> i64 {
let value = i64::from_be_bytes([ let value = i64::from_be_bytes([
self.data[self.cursor], self.data[self.cursor],
@ -119,41 +124,22 @@ impl NbtReader<'_> {
/// 转换大小端(大端) /// 转换大小端(大端)
/// ///
/// 会在超出长度时 panic /// 会在超出长度时 panic
#[inline]
pub fn read_u64(&mut self) -> u64 { self.read_i64() as u64 } pub fn read_u64(&mut self) -> u64 { self.read_i64() as u64 }
/// 读取一个 f32 类型的数据 /// 读取一个 f32 类型的数据
/// ///
/// 转换大小端 /// 转换大小端
/// ///
/// 会在超出长度时 panic /// 会在超出长度时 panic
pub fn read_f32(&mut self) -> f32 { #[inline]
let value = f32::from_be_bytes([ pub fn read_f32(&mut self) -> f32 { f32::from_bits(self.read_u32()) }
self.data[self.cursor],
self.data[self.cursor + 1],
self.data[self.cursor + 2],
self.data[self.cursor + 3],
]);
self.cursor += 4;
value
}
/// 读取一个 f64 类型的数据 /// 读取一个 f64 类型的数据
/// ///
/// 转换大小端 /// 转换大小端
/// ///
/// 会在超出长度时 panic /// 会在超出长度时 panic
pub fn read_f64(&mut self) -> f64 { #[inline]
let value = f64::from_be_bytes([ pub fn read_f64(&mut self) -> f64 { f64::from_bits(self.read_u64()) }
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
}
/// 读取一个 f32 类型的数据 /// 读取一个 f32 类型的数据
/// ///
/// 转换大小端 /// 转换大小端
@ -182,6 +168,7 @@ impl NbtReader<'_> {
/// # 安全性 /// # 安全性
/// ///
/// 长度溢出会导致 panic /// 长度溢出会导致 panic
#[inline]
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;
@ -204,6 +191,7 @@ impl NbtReader<'_> {
/// # 安全性 /// # 安全性
/// ///
/// 长度溢出会导致 panic /// 长度溢出会导致 panic
#[inline]
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;

View File

@ -66,45 +66,55 @@ mod safe_test {
#[test] #[test]
fn read_fxx() { fn read_fxx() {
let mut data = vec![ let mut data = Vec::with_capacity(12);
0x40, 0x49, 0x0f, 0xdb, 0x40, 0x49, 0x0f, 0xdb, 0x40, 0x49, 0x0f, 0xdb, 0x40, 0x49, data.extend_from_slice(&std::f32::consts::PI.to_be_bytes());
0x0f, 0xdb, data.extend_from_slice(&std::f64::consts::PI.to_be_bytes());
]; println!("{:?}", data);
let mut reader = NbtReader::new(&mut data); let mut reader = NbtReader::new(&mut data);
println!("{}", f32::from_be_bytes([0x40, 0x49, 0x0f, 0xdb])); assert_eq!(reader.read_f32(), std::f32::consts::PI);
assert_eq!(reader.read_f32(), 3.1415927);
assert_eq!(reader.cursor, 4); assert_eq!(reader.cursor, 4);
assert_eq!(reader.read_f64(), 3.14159265); assert_eq!(reader.read_f64(), std::f64::consts::PI);
assert_eq!(reader.cursor, 12); assert_eq!(reader.cursor, 12);
} }
#[test]
fn read_string() {
let mut data = Vec::with_capacity(20);
data.extend("Hello world!啊?".as_bytes());
let len = data.len();
println!("{:?}", data);
let mut reader = NbtReader::new(&mut data);
assert_eq!(reader.read_string(len), "Hello world!啊?");
assert_eq!(reader.cursor, 18);
}
} }
mod unsafe_test { mod unsafe_test {
use super::*; use super::*;
}
#[test] #[test]
fn read_array() { fn read_array() {
let mut data = vec![0x01, 0x02, 0x03, 0x04]; let mut data = vec![0x01, 0x02, 0x03, 0x04];
let mut reader = NbtReader::new(&mut data); let mut reader = NbtReader::new(&mut data);
assert_eq!(reader.read_u8_array(2), &[0x01, 0x02]); assert_eq!(reader.read_u8_array(2), &[0x01, 0x02]);
assert_eq!(reader.cursor, 2); assert_eq!(reader.cursor, 2);
assert_eq!(reader.read_i8_array_unchecked(2), &[0x03, 0x04]); assert_eq!(reader.read_i8_array_unchecked(2), &[0x03, 0x04]);
assert_eq!(reader.cursor, 4); assert_eq!(reader.cursor, 4);
} }
#[test] #[test]
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_i32_array_unchecked(1), &[1234567890_i32]); assert_eq!(reader.read_i32_array_unchecked(1), &[1234567890_i32]);
assert_eq!(reader.cursor, 4); assert_eq!(reader.cursor, 4);
} }
#[test] #[test]
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_i64_array(1), &[1234567890_i64]); assert_eq!(reader.read_i64_array(1), &[1234567890_i64]);
assert_eq!(reader.cursor, 8); assert_eq!(reader.cursor, 8);
}
} }