Compare commits
No commits in common. "c367042d5809a2943248c0c4fabddb6c5ebcad1d" and "393083891c3dc5bfec696a863781cd248db6c419" have entirely different histories.
c367042d58
...
393083891c
@ -9,11 +9,11 @@
|
||||
- [x] JavaNetAfter1_20_2
|
||||
- [x] BedrockDisk
|
||||
- [x] BedrockNetVarInt
|
||||
- [x] 写入
|
||||
- [ ] 写入
|
||||
- [x] Java
|
||||
- [x] JavaNetAfter1_20_2
|
||||
- [x] BedrockDisk
|
||||
- [x] BedrockNetVarInt
|
||||
- [ ] BedrockDisk
|
||||
- [ ] BedrockNetVarInt
|
||||
- [ ] `Serde` 支持
|
||||
- [ ] `Serialize`
|
||||
- [ ] `Deserialize`
|
||||
|
@ -200,9 +200,7 @@ fn test_v5(mut data: Vec<u8>) {
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
test_lib!(
|
||||
{
|
||||
let _nbt_data = shen_nbt5::NbtValue::from_binary::<shen_nbt5::nbt_version::Java>(
|
||||
data.as_mut_slice(),
|
||||
);
|
||||
let _nbt_data = shen_nbt5::NbtValue::from_binary(data.as_mut_slice());
|
||||
},
|
||||
"nbt v5",
|
||||
len
|
||||
@ -258,10 +256,7 @@ fn cli_read_test() {
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
let start_time = std::time::Instant::now();
|
||||
// let nbt_data = shen_nbt4::Value::from_vec(data);
|
||||
|
||||
let nbt_data =
|
||||
shen_nbt5::NbtValue::from_binary::<shen_nbt5::nbt_version::Java>(data.as_mut_slice())
|
||||
.unwrap();
|
||||
let nbt_data = shen_nbt5::NbtValue::from_binary(data.as_mut_slice());
|
||||
let end_time = std::time::Instant::now();
|
||||
println!("=== shen nbt 5 ===");
|
||||
println!("time: {:?}", end_time - start_time);
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "shen-nbt5"
|
||||
version = "0.4.0"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
@ -29,13 +29,13 @@ impl nbt_version::NbtReadTrait for nbt_version::Java {
|
||||
#[inline]
|
||||
fn read_i32_array(reader: &mut NbtReader) -> NbtResult<Vec<i32>> {
|
||||
let len = reader.read_be_i32() as usize;
|
||||
let value = reader.read_be_i32_array(len);
|
||||
let value = reader.read_i32_array(len);
|
||||
Ok(value)
|
||||
}
|
||||
#[inline]
|
||||
fn read_i64_array(reader: &mut NbtReader) -> NbtResult<Vec<i64>> {
|
||||
let len = reader.read_be_i32() as usize;
|
||||
let value = reader.read_be_i64_array(len);
|
||||
let value = reader.read_i64_array(len);
|
||||
Ok(value)
|
||||
}
|
||||
#[inline]
|
||||
@ -159,13 +159,13 @@ impl NbtReadTrait for BedrockDisk {
|
||||
#[inline]
|
||||
fn read_i32_array(reader: &mut NbtReader) -> NbtResult<Vec<i32>> {
|
||||
let len = reader.read_le_i32() as usize;
|
||||
let value = reader.read_le_i32_array(len);
|
||||
let value = reader.read_i32_array(len);
|
||||
Ok(value)
|
||||
}
|
||||
#[inline]
|
||||
fn read_i64_array(reader: &mut NbtReader) -> NbtResult<Vec<i64>> {
|
||||
let len = reader.read_le_i32() as usize;
|
||||
let value = reader.read_le_i64_array(len);
|
||||
let value = reader.read_i64_array(len);
|
||||
Ok(value)
|
||||
}
|
||||
#[inline]
|
||||
@ -256,12 +256,12 @@ impl NbtReadTrait for BedrockNetVarInt {
|
||||
}
|
||||
fn read_i32_array(reader: &mut NbtReader) -> NbtResult<Vec<i32>> {
|
||||
let len = reader.read_zigzag_var_i32()? as usize;
|
||||
let value = reader.read_le_i32_array(len);
|
||||
let value = reader.read_i32_array(len);
|
||||
Ok(value)
|
||||
}
|
||||
fn read_i64_array(reader: &mut NbtReader) -> NbtResult<Vec<i64>> {
|
||||
let len = reader.read_zigzag_var_i32()? as usize;
|
||||
let value = reader.read_le_i64_array(len);
|
||||
let value = reader.read_i64_array(len);
|
||||
Ok(value)
|
||||
}
|
||||
fn read_compound(reader: &mut NbtReader) -> NbtResult<Vec<(String, NbtValue)>> {
|
||||
@ -727,7 +727,7 @@ impl NbtReader<'_> {
|
||||
///
|
||||
/// 长度溢出会导致 UB
|
||||
#[inline]
|
||||
pub unsafe fn read_be_i32_array_unsafe(&mut self, len: usize) -> Vec<i32> {
|
||||
pub unsafe fn read_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();
|
||||
@ -743,7 +743,7 @@ impl NbtReader<'_> {
|
||||
///
|
||||
/// 长度溢出会导致 panic
|
||||
#[inline]
|
||||
pub fn read_be_i32_array(&mut self, len: usize) -> Vec<i32> {
|
||||
pub fn read_i32_array(&mut self, len: usize) -> Vec<i32> {
|
||||
let value = self.data[self.cursor..self.cursor + len * 4]
|
||||
.chunks_exact(4)
|
||||
.map(|n| i32::from_be_bytes(n[0..4].try_into().unwrap()))
|
||||
@ -757,7 +757,7 @@ impl NbtReader<'_> {
|
||||
///
|
||||
/// 长度溢出会导致 UB
|
||||
#[inline]
|
||||
pub unsafe fn read_be_i64_array_unsafe(&mut self, len: usize) -> Vec<i64> {
|
||||
pub unsafe fn read_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();
|
||||
@ -773,7 +773,7 @@ impl NbtReader<'_> {
|
||||
///
|
||||
/// 长度溢出会导致 panic
|
||||
#[inline]
|
||||
pub fn read_be_i64_array(&mut self, len: usize) -> Vec<i64> {
|
||||
pub fn read_i64_array(&mut self, len: usize) -> Vec<i64> {
|
||||
let value = self.data[self.cursor..self.cursor + len * 8]
|
||||
.chunks_exact(8)
|
||||
.map(|n| i64::from_be_bytes(n[0..8].try_into().unwrap()))
|
||||
@ -781,48 +781,6 @@ impl NbtReader<'_> {
|
||||
self.cursor += len * 8;
|
||||
value
|
||||
}
|
||||
/// 读取指定长度的 le i16 数组
|
||||
///
|
||||
/// # 安全性
|
||||
///
|
||||
/// 长度溢出会导致 panic
|
||||
#[inline]
|
||||
pub fn read_le_i16_array(&mut self, len: usize) -> Vec<i16> {
|
||||
let value = self.data[self.cursor..self.cursor + len * 2]
|
||||
.chunks_exact(2)
|
||||
.map(|n| i16::from_le_bytes(n[0..2].try_into().unwrap()))
|
||||
.collect();
|
||||
self.cursor += len * 2;
|
||||
value
|
||||
}
|
||||
/// 读取指定长度的 le i32 数组
|
||||
///
|
||||
/// # 安全性
|
||||
///
|
||||
/// 长度溢出会导致 panic
|
||||
#[inline]
|
||||
pub fn read_le_i32_array(&mut self, len: usize) -> Vec<i32> {
|
||||
let value = self.data[self.cursor..self.cursor + len * 4]
|
||||
.chunks_exact(4)
|
||||
.map(|n| i32::from_le_bytes(n[0..4].try_into().unwrap()))
|
||||
.collect();
|
||||
self.cursor += len * 4;
|
||||
value
|
||||
}
|
||||
/// 读取指定长度的 le i64 数组
|
||||
///
|
||||
/// # 安全性
|
||||
///
|
||||
/// 长度溢出会导致 panic
|
||||
#[inline]
|
||||
pub fn read_le_i64_array(&mut self, len: usize) -> Vec<i64> {
|
||||
let value = self.data[self.cursor..self.cursor + len * 8]
|
||||
.chunks_exact(8)
|
||||
.map(|n| i64::from_le_bytes(n[0..8].try_into().unwrap()))
|
||||
.collect();
|
||||
self.cursor += len * 8;
|
||||
value
|
||||
}
|
||||
/// 读取指定长度的 utf-8 字符串
|
||||
///
|
||||
/// # 安全性
|
||||
|
@ -260,9 +260,9 @@ mod unsafe_test {
|
||||
let mut value = gen_datas(4 * 100);
|
||||
let mut reader = NbtReader::new(&mut value);
|
||||
unsafe {
|
||||
let value = reader.read_be_i32_array_unsafe(100);
|
||||
let value = reader.read_i32_array_unsafe(100);
|
||||
reader.roll_back(100 * 4);
|
||||
let safe_value = reader.read_be_i32_array(100);
|
||||
let safe_value = reader.read_i32_array(100);
|
||||
assert_eq!(value, safe_value);
|
||||
assert_eq!(reader.cursor, 100 * 4);
|
||||
}
|
||||
@ -273,9 +273,9 @@ mod unsafe_test {
|
||||
let mut value = gen_datas(8 * 100);
|
||||
let mut reader = NbtReader::new(&mut value);
|
||||
unsafe {
|
||||
let value = reader.read_be_i64_array_unsafe(100);
|
||||
let value = reader.read_i64_array_unsafe(100);
|
||||
reader.roll_back(100 * 8);
|
||||
let safe_value = reader.read_be_i64_array(100);
|
||||
let safe_value = reader.read_i64_array(100);
|
||||
assert_eq!(value, safe_value);
|
||||
assert_eq!(reader.cursor, 100 * 8);
|
||||
}
|
||||
|
@ -202,339 +202,3 @@ impl NbtWriteTrait for JavaNetAfter1_20_2 {
|
||||
Ok(buff)
|
||||
}
|
||||
}
|
||||
|
||||
/// 比较痛苦的一集
|
||||
impl NbtWriteTrait for BedrockDisk {
|
||||
#[inline]
|
||||
fn write_i8_array(writer: &mut Vec<u8>, data: &[i8]) {
|
||||
// 写入长度
|
||||
writer.extend_from_slice(&(data.len() as i32).to_le_bytes());
|
||||
// 写入数据
|
||||
writer.extend_from_slice(data.iter().map(|x| *x as u8).collect::<Vec<u8>>().as_slice());
|
||||
}
|
||||
#[inline]
|
||||
fn write_i32_array(writer: &mut Vec<u8>, data: &[i32]) {
|
||||
// 写入长度
|
||||
writer.extend_from_slice(&(data.len() as i32).to_le_bytes());
|
||||
// 写入数据
|
||||
writer.extend_from_slice(
|
||||
&data.iter().map(|x| x.to_le_bytes()).collect::<Vec<[u8; 4]>>().concat(),
|
||||
);
|
||||
}
|
||||
#[inline]
|
||||
fn write_i64_array(writer: &mut Vec<u8>, data: &[i64]) {
|
||||
// 写入长度
|
||||
writer.extend_from_slice(&(data.len() as i32).to_le_bytes());
|
||||
// 写入数据
|
||||
writer.extend_from_slice(
|
||||
&data.iter().map(|x| x.to_le_bytes()).collect::<Vec<[u8; 8]>>().concat(),
|
||||
);
|
||||
}
|
||||
#[inline]
|
||||
fn write_nbt_string(writer: &mut Vec<u8>, data: &str) {
|
||||
// 写入长度
|
||||
writer.extend_from_slice(&(data.len() as u16).to_le_bytes());
|
||||
// 写入数据
|
||||
writer.extend_from_slice(data.as_bytes());
|
||||
}
|
||||
#[inline]
|
||||
fn write_list(writer: &mut Vec<u8>, data: &[NbtValue]) -> NbtResult<()> {
|
||||
if data.is_empty() {
|
||||
// 写入一个空的 tag
|
||||
writer.extend_from_slice(&0i8.to_le_bytes());
|
||||
return Ok(());
|
||||
}
|
||||
// 遍历检查一遍所有的 tag 是否一致
|
||||
let tag = data.first().unwrap().tag();
|
||||
if !data.iter().all(|x| x.tag() == tag) {
|
||||
return Err(NbtError::ListTypeNotSame(data.iter().map(|x| x.tag()).collect()));
|
||||
}
|
||||
// 写入 tag
|
||||
writer.push(tag);
|
||||
// 写入长度
|
||||
writer.extend_from_slice(&(data.len() as i32).to_le_bytes());
|
||||
// 写入数据
|
||||
for i in data {
|
||||
match i {
|
||||
NbtValue::Byte(x) => writer.push(*x as u8),
|
||||
NbtValue::Short(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Int(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Long(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Float(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Double(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::ByteArray(x) => Self::write_i8_array(writer, x),
|
||||
NbtValue::IntArray(x) => Self::write_i32_array(writer, x),
|
||||
NbtValue::LongArray(x) => Self::write_i64_array(writer, x),
|
||||
NbtValue::String(x) => Self::write_nbt_string(writer, x),
|
||||
NbtValue::List(x) => Self::write_list(writer, x)?,
|
||||
NbtValue::Compound(name, data) => {
|
||||
Self::write_compound(writer, name.as_ref(), data)?
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
#[inline]
|
||||
fn write_compound(
|
||||
writer: &mut Vec<u8>,
|
||||
name: Option<&String>,
|
||||
data: &[(String, NbtValue)],
|
||||
) -> NbtResult<()> {
|
||||
// 写入自己的名字
|
||||
Self::write_nbt_string(writer, name.unwrap_or(&"".to_string()));
|
||||
for (key, value) in data {
|
||||
// 写入 tag
|
||||
writer.push(value.tag());
|
||||
// 写入 key
|
||||
Self::write_nbt_string(writer, key);
|
||||
// 写入 value
|
||||
match value {
|
||||
NbtValue::Byte(x) => writer.push(*x as u8),
|
||||
NbtValue::Short(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Int(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Long(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Float(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Double(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::ByteArray(x) => Self::write_i8_array(writer, x),
|
||||
NbtValue::IntArray(x) => Self::write_i32_array(writer, x),
|
||||
NbtValue::LongArray(x) => Self::write_i64_array(writer, x),
|
||||
NbtValue::String(x) => Self::write_nbt_string(writer, x),
|
||||
NbtValue::List(x) => Self::write_list(writer, x)?,
|
||||
NbtValue::Compound(name, data) => {
|
||||
Self::write_compound(writer, name.as_ref(), data)?
|
||||
}
|
||||
}
|
||||
}
|
||||
// 写入结束 tag
|
||||
writer.push(0);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_to(value: &NbtValue, buff: &mut Vec<u8>) -> NbtResult<()> {
|
||||
// 写入 tag
|
||||
match value {
|
||||
NbtValue::Compound(name, data) => {
|
||||
buff.push(value.tag());
|
||||
Self::write_compound(buff, name.as_ref(), data)?
|
||||
}
|
||||
NbtValue::List(data) => {
|
||||
buff.push(value.tag());
|
||||
Self::write_list(buff, data)?
|
||||
}
|
||||
x => return Err(NbtError::WrongRootType(x.tag())),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_to_with_name(name: &str, value: &NbtValue, buff: &mut Vec<u8>) -> NbtResult<()> {
|
||||
// 写入 tag
|
||||
buff.push(value.tag());
|
||||
// 写入 key
|
||||
Self::write_nbt_string(buff, name);
|
||||
// 写入 value
|
||||
Self::write_to(value, buff)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn to_binary(value: &NbtValue) -> NbtResult<Vec<u8>> {
|
||||
let mut buff = Vec::new();
|
||||
BedrockDisk::write_to(value, &mut buff)?;
|
||||
Ok(buff)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn var_i32_to_bytes(value: i32) -> Vec<u8> {
|
||||
let mut buff = Vec::new();
|
||||
let mut value = value;
|
||||
loop {
|
||||
let mut temp = (value & 0b01111111) as u8;
|
||||
value >>= 7;
|
||||
if value != 0 {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
buff.push(temp);
|
||||
if value == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
buff
|
||||
}
|
||||
|
||||
pub fn var_i64_to_bytes(value: i64) -> Vec<u8> {
|
||||
let mut buff = Vec::new();
|
||||
let mut value = value;
|
||||
loop {
|
||||
let mut temp = (value & 0b01111111) as u8;
|
||||
value >>= 7;
|
||||
if value != 0 {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
buff.push(temp);
|
||||
if value == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
buff
|
||||
}
|
||||
|
||||
pub fn zigzag_var_i32_to_bytes(value: i32) -> Vec<u8> {
|
||||
let mut buff = Vec::new();
|
||||
let mut value = (value << 1) ^ (value >> 31);
|
||||
loop {
|
||||
let mut temp = (value & 0b01111111) as u8;
|
||||
value >>= 7;
|
||||
if value != 0 {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
buff.push(temp);
|
||||
if value == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
buff
|
||||
}
|
||||
|
||||
pub fn zigzag_var_i64_to_bytes(value: i64) -> Vec<u8> {
|
||||
let mut buff = Vec::new();
|
||||
let mut value = (value << 1) ^ (value >> 63);
|
||||
loop {
|
||||
let mut temp = (value & 0b01111111) as u8;
|
||||
value >>= 7;
|
||||
if value != 0 {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
buff.push(temp);
|
||||
if value == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
buff
|
||||
}
|
||||
|
||||
/// 最痛苦的一集
|
||||
impl NbtWriteTrait for BedrockNetVarInt {
|
||||
fn write_i8_array(writer: &mut Vec<u8>, data: &[i8]) {
|
||||
// zigzag var i32
|
||||
writer.extend_from_slice(&zigzag_var_i32_to_bytes(data.len() as i32));
|
||||
writer.extend_from_slice(data.iter().map(|x| *x as u8).collect::<Vec<u8>>().as_slice());
|
||||
}
|
||||
fn write_i32_array(writer: &mut Vec<u8>, data: &[i32]) {
|
||||
// zigzag var i32
|
||||
writer.extend_from_slice(&zigzag_var_i32_to_bytes(data.len() as i32));
|
||||
writer.extend_from_slice(
|
||||
&data.iter().map(|x| x.to_le_bytes()).collect::<Vec<[u8; 4]>>().concat(),
|
||||
);
|
||||
}
|
||||
fn write_i64_array(writer: &mut Vec<u8>, data: &[i64]) {
|
||||
// zigzag var i32
|
||||
writer.extend_from_slice(&zigzag_var_i32_to_bytes(data.len() as i32));
|
||||
writer.extend_from_slice(
|
||||
&data.iter().map(|x| x.to_le_bytes()).collect::<Vec<[u8; 8]>>().concat(),
|
||||
);
|
||||
}
|
||||
fn write_nbt_string(writer: &mut Vec<u8>, data: &str) {
|
||||
// zigzag var i32
|
||||
writer.extend_from_slice(&zigzag_var_i32_to_bytes(data.len() as i32));
|
||||
writer.extend_from_slice(data.as_bytes());
|
||||
}
|
||||
fn write_list(writer: &mut Vec<u8>, data: &[NbtValue]) -> NbtResult<()> {
|
||||
if data.is_empty() {
|
||||
// 写入一个空的 tag
|
||||
writer.extend_from_slice(&0i8.to_le_bytes());
|
||||
return Ok(());
|
||||
}
|
||||
// 遍历检查一遍所有的 tag 是否一致
|
||||
let tag = data.first().unwrap().tag();
|
||||
if !data.iter().all(|x| x.tag() == tag) {
|
||||
return Err(NbtError::ListTypeNotSame(data.iter().map(|x| x.tag()).collect()));
|
||||
}
|
||||
// 写入 tag
|
||||
writer.push(tag);
|
||||
// zigzag var i32
|
||||
writer.extend_from_slice(&zigzag_var_i32_to_bytes(data.len() as i32));
|
||||
// 写入数据
|
||||
for i in data {
|
||||
match i {
|
||||
NbtValue::Byte(x) => writer.push(*x as u8),
|
||||
NbtValue::Short(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Int(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Long(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Float(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Double(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::ByteArray(x) => Self::write_i8_array(writer, x),
|
||||
NbtValue::IntArray(x) => Self::write_i32_array(writer, x),
|
||||
NbtValue::LongArray(x) => Self::write_i64_array(writer, x),
|
||||
NbtValue::String(x) => Self::write_nbt_string(writer, x),
|
||||
NbtValue::List(x) => Self::write_list(writer, x)?,
|
||||
NbtValue::Compound(name, data) => {
|
||||
Self::write_compound(writer, name.as_ref(), data)?
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn write_compound(
|
||||
writer: &mut Vec<u8>,
|
||||
name: Option<&String>,
|
||||
data: &[(String, NbtValue)],
|
||||
) -> NbtResult<()> {
|
||||
// 写入自己的名字
|
||||
Self::write_nbt_string(writer, name.unwrap_or(&"".to_string()));
|
||||
for (key, value) in data {
|
||||
// 写入 tag
|
||||
writer.push(value.tag());
|
||||
// 写入 key
|
||||
Self::write_nbt_string(writer, key);
|
||||
// 写入 value
|
||||
match value {
|
||||
NbtValue::Byte(x) => writer.push(*x as u8),
|
||||
NbtValue::Short(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Int(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Long(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Float(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::Double(x) => writer.extend_from_slice(&x.to_le_bytes()),
|
||||
NbtValue::ByteArray(x) => Self::write_i8_array(writer, x),
|
||||
NbtValue::IntArray(x) => Self::write_i32_array(writer, x),
|
||||
NbtValue::LongArray(x) => Self::write_i64_array(writer, x),
|
||||
NbtValue::String(x) => Self::write_nbt_string(writer, x),
|
||||
NbtValue::List(x) => Self::write_list(writer, x)?,
|
||||
NbtValue::Compound(name, data) => {
|
||||
Self::write_compound(writer, name.as_ref(), data)?
|
||||
}
|
||||
}
|
||||
}
|
||||
// 写入结束 tag
|
||||
writer.push(0);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_to(value: &NbtValue, buff: &mut Vec<u8>) -> NbtResult<()> {
|
||||
// 写入 tag
|
||||
match value {
|
||||
NbtValue::Compound(name, data) => {
|
||||
buff.push(value.tag());
|
||||
Self::write_compound(buff, name.as_ref(), data)?
|
||||
}
|
||||
NbtValue::List(data) => {
|
||||
buff.push(value.tag());
|
||||
Self::write_list(buff, data)?
|
||||
}
|
||||
x => return Err(NbtError::WrongRootType(x.tag())),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn write_to_with_name(name: &str, value: &NbtValue, buff: &mut Vec<u8>) -> NbtResult<()> {
|
||||
// 写入 tag
|
||||
buff.push(value.tag());
|
||||
// 写入 key
|
||||
Self::write_nbt_string(buff, name);
|
||||
// 写入 value
|
||||
Self::write_to(value, buff)?;
|
||||
Ok(())
|
||||
}
|
||||
fn to_binary(value: &NbtValue) -> NbtResult<Vec<u8>> {
|
||||
let mut buff = Vec::new();
|
||||
BedrockNetVarInt::write_to(value, &mut buff)?;
|
||||
Ok(buff)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user