修复未对齐问题, 添加一个 readi16 be api(虽说用不上
This commit is contained in:
parent
1d8a7400eb
commit
395a26bd41
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "shen-nbt5"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
edition = "2021"
|
||||
description = "Just A FASSST NBT parser/writer"
|
||||
homepage = "https://github.com/shenjackyuanjie/nbt-rust"
|
||||
|
@ -721,6 +721,26 @@ impl NbtReader<'_> {
|
||||
self.cursor += len;
|
||||
value
|
||||
}
|
||||
/// 读取指定长度的 i16 数组
|
||||
///
|
||||
/// # 安全性
|
||||
///
|
||||
/// 长度溢出会导致 UB
|
||||
#[inline]
|
||||
pub unsafe fn read_be_i16_array_unsafe(&mut self, len: usize) -> Vec<i16> {
|
||||
let mut value: Vec<i16> = Vec::with_capacity(len);
|
||||
std::ptr::copy_nonoverlapping(
|
||||
self.data[self.cursor..].as_ptr() as *const u8,
|
||||
value.as_ptr() as *mut u8,
|
||||
len * 2,
|
||||
);
|
||||
value.set_len(len);
|
||||
for n in &mut value {
|
||||
*n = n.to_be();
|
||||
}
|
||||
self.cursor += len * 2;
|
||||
value
|
||||
}
|
||||
/// 读取指定长度的 i32 数组
|
||||
///
|
||||
/// # 安全性
|
||||
@ -728,15 +748,39 @@ impl NbtReader<'_> {
|
||||
/// 长度溢出会导致 UB
|
||||
#[inline]
|
||||
pub unsafe fn read_be_i32_array_unsafe(&mut self, len: usize) -> Vec<i32> {
|
||||
let value =
|
||||
std::slice::from_raw_parts(self.data[self.cursor..].as_ptr() as *const i32, len);
|
||||
let mut value = value.to_vec();
|
||||
let mut value: Vec<i32> = Vec::with_capacity(len);
|
||||
std::ptr::copy_nonoverlapping(
|
||||
self.data[self.cursor..].as_ptr() as *const u8,
|
||||
value.as_ptr() as *mut u8,
|
||||
len * 4,
|
||||
);
|
||||
value.set_len(len);
|
||||
for n in &mut value {
|
||||
*n = n.to_be();
|
||||
}
|
||||
self.cursor += len * 4;
|
||||
value
|
||||
}
|
||||
/// 读取指定长度的 i64 数组
|
||||
///
|
||||
/// # 安全性
|
||||
///
|
||||
/// 长度溢出会导致 UB
|
||||
#[inline]
|
||||
pub unsafe fn read_be_i64_array_unsafe(&mut self, len: usize) -> Vec<i64> {
|
||||
let mut value: Vec<i64> = Vec::with_capacity(len);
|
||||
std::ptr::copy_nonoverlapping(
|
||||
self.data[self.cursor..].as_ptr() as *const u8,
|
||||
value.as_ptr() as *mut u8,
|
||||
len * 8,
|
||||
);
|
||||
value.set_len(len);
|
||||
for n in &mut value {
|
||||
*n = n.to_be();
|
||||
}
|
||||
self.cursor += len * 8;
|
||||
value
|
||||
}
|
||||
/// 读取指定长度的 i32 数组
|
||||
///
|
||||
/// # 安全性
|
||||
@ -755,22 +799,6 @@ impl NbtReader<'_> {
|
||||
///
|
||||
/// # 安全性
|
||||
///
|
||||
/// 长度溢出会导致 UB
|
||||
#[inline]
|
||||
pub unsafe fn read_be_i64_array_unsafe(&mut self, len: usize) -> Vec<i64> {
|
||||
let value =
|
||||
std::slice::from_raw_parts(self.data[self.cursor..].as_ptr() as *const i64, len);
|
||||
let mut value = value.to_vec();
|
||||
for n in &mut value {
|
||||
*n = n.to_be();
|
||||
}
|
||||
self.cursor += len * 8;
|
||||
value
|
||||
}
|
||||
/// 读取指定长度的 i64 数组
|
||||
///
|
||||
/// # 安全性
|
||||
///
|
||||
/// 长度溢出会导致 panic
|
||||
#[inline]
|
||||
pub fn read_be_i64_array(&mut self, len: usize) -> Vec<i64> {
|
||||
|
@ -280,6 +280,46 @@ mod unsafe_test {
|
||||
assert_eq!(reader.cursor, 100 * 8);
|
||||
}
|
||||
}
|
||||
|
||||
/// 未对齐的地址
|
||||
#[test]
|
||||
fn unaligned_read_u16_array() {
|
||||
let mut value = vec![0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04];
|
||||
let mut reader = NbtReader::new(&mut value);
|
||||
let value = reader.read_u8();
|
||||
assert_eq!(value, 0x01);
|
||||
assert_eq!(reader.cursor, 1);
|
||||
unsafe {
|
||||
// 读取 u16 数组
|
||||
let array = reader.read_be_i16_array_unsafe(3);
|
||||
assert_eq!(array, vec![0x0203, 0x0401, 0x0203]);
|
||||
assert_eq!(reader.cursor, 7);
|
||||
let value = reader.read_u8();
|
||||
assert_eq!(value, 0x04);
|
||||
assert_eq!(reader.cursor, 8);
|
||||
}
|
||||
}
|
||||
|
||||
/// 依然是未对齐
|
||||
/// 只不过是 u32/i32
|
||||
#[test]
|
||||
fn unaligned_read_x32_array() {
|
||||
let mut value = gen_datas(202);
|
||||
let mut reader = NbtReader::new(&mut value);
|
||||
let value = reader.read_u8();
|
||||
assert_eq!(value, 0x00);
|
||||
assert_eq!(reader.cursor, 1);
|
||||
unsafe {
|
||||
let array = reader.read_be_i32_array_unsafe(50);
|
||||
reader.roll_back(50 * 4);
|
||||
let safe_array = reader.read_be_i32_array(50);
|
||||
assert_eq!(array, safe_array);
|
||||
assert_eq!(reader.cursor, 201);
|
||||
}
|
||||
let value = reader.read_u8();
|
||||
assert_eq!(value, 201);
|
||||
assert_eq!(reader.cursor, 202);
|
||||
}
|
||||
}
|
||||
|
||||
mod nbt {
|
||||
|
Loading…
Reference in New Issue
Block a user