修复未对齐问题, 添加一个 readi16 be api(虽说用不上
This commit is contained in:
parent
1d8a7400eb
commit
395a26bd41
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "shen-nbt5"
|
name = "shen-nbt5"
|
||||||
version = "0.4.3"
|
version = "0.4.4"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Just A FASSST NBT parser/writer"
|
description = "Just A FASSST NBT parser/writer"
|
||||||
homepage = "https://github.com/shenjackyuanjie/nbt-rust"
|
homepage = "https://github.com/shenjackyuanjie/nbt-rust"
|
||||||
|
@ -237,7 +237,7 @@ impl std::fmt::Display for NbtError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 核心 Value
|
/// 核心 Value
|
||||||
///
|
///
|
||||||
/// 暂时不支持 `from_value` 和 `to_value`
|
/// 暂时不支持 `from_value` 和 `to_value`
|
||||||
/// https://github.com/shenjackyuanjie/nbt-rust/issues/1
|
/// https://github.com/shenjackyuanjie/nbt-rust/issues/1
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
@ -721,6 +721,26 @@ impl NbtReader<'_> {
|
|||||||
self.cursor += len;
|
self.cursor += len;
|
||||||
value
|
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 数组
|
/// 读取指定长度的 i32 数组
|
||||||
///
|
///
|
||||||
/// # 安全性
|
/// # 安全性
|
||||||
@ -728,15 +748,39 @@ impl NbtReader<'_> {
|
|||||||
/// 长度溢出会导致 UB
|
/// 长度溢出会导致 UB
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn read_be_i32_array_unsafe(&mut self, len: usize) -> Vec<i32> {
|
pub unsafe fn read_be_i32_array_unsafe(&mut self, len: usize) -> Vec<i32> {
|
||||||
let value =
|
let mut value: Vec<i32> = Vec::with_capacity(len);
|
||||||
std::slice::from_raw_parts(self.data[self.cursor..].as_ptr() as *const i32, len);
|
std::ptr::copy_nonoverlapping(
|
||||||
let mut value = value.to_vec();
|
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 {
|
for n in &mut value {
|
||||||
*n = n.to_be();
|
*n = n.to_be();
|
||||||
}
|
}
|
||||||
self.cursor += len * 4;
|
self.cursor += len * 4;
|
||||||
value
|
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 数组
|
/// 读取指定长度的 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
|
/// 长度溢出会导致 panic
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn read_be_i64_array(&mut self, len: usize) -> Vec<i64> {
|
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);
|
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 {
|
mod nbt {
|
||||||
|
Loading…
Reference in New Issue
Block a user