Skip to content

Commit 2fe17e0

Browse files
committed
work on deserialization
1 parent aa069b7 commit 2fe17e0

File tree

15 files changed

+382
-209
lines changed

15 files changed

+382
-209
lines changed

pumpkin-nbt/src/compound.rs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::deserializer::ReadAdaptor;
2+
use crate::serializer::WriteAdaptor;
23
use crate::tag::NbtTag;
34
use crate::{get_nbt_string, Error, Nbt, END_ID};
4-
use bytes::{BufMut, Bytes, BytesMut};
55
use std::io::{ErrorKind, Read, Write};
66
use std::vec::IntoIter;
77

@@ -56,19 +56,16 @@ impl NbtCompound {
5656
Ok(compound)
5757
}
5858

59-
pub fn serialize_content(&self) -> Bytes {
60-
let mut bytes = BytesMut::new();
59+
pub fn serialize_content<W>(&self, w: &mut WriteAdaptor<W>) -> Result<(), Error>
60+
where
61+
W: Write,
62+
{
6163
for (name, tag) in &self.child_tags {
62-
bytes.put_u8(tag.get_type_id());
63-
bytes.put(NbtTag::String(name.clone()).serialize_data());
64-
bytes.put(tag.serialize_data());
64+
w.write_u8_be(tag.get_type_id())?;
65+
NbtTag::String(name.clone()).serialize_data(w)?;
66+
tag.serialize_data(w)?;
6567
}
66-
bytes.put_u8(END_ID);
67-
bytes.freeze()
68-
}
69-
70-
pub fn serialize_content_to_writer<W: Write>(&self, mut writer: W) -> std::io::Result<()> {
71-
writer.write_all(&self.serialize_content())?;
68+
w.write_u8_be(END_ID)?;
7269
Ok(())
7370
}
7471

@@ -152,19 +149,19 @@ impl NbtCompound {
152149
self.get(name).and_then(|tag| tag.extract_string())
153150
}
154151

155-
pub fn get_list(&self, name: &str) -> Option<&Vec<NbtTag>> {
152+
pub fn get_list(&self, name: &str) -> Option<&[NbtTag]> {
156153
self.get(name).and_then(|tag| tag.extract_list())
157154
}
158155

159156
pub fn get_compound(&self, name: &str) -> Option<&NbtCompound> {
160157
self.get(name).and_then(|tag| tag.extract_compound())
161158
}
162159

163-
pub fn get_int_array(&self, name: &str) -> Option<&Vec<i32>> {
160+
pub fn get_int_array(&self, name: &str) -> Option<&[i32]> {
164161
self.get(name).and_then(|tag| tag.extract_int_array())
165162
}
166163

167-
pub fn get_long_array(&self, name: &str) -> Option<&Vec<i64>> {
164+
pub fn get_long_array(&self, name: &str) -> Option<&[i64]> {
168165
self.get(name).and_then(|tag| tag.extract_long_array())
169166
}
170167
}

pumpkin-nbt/src/deserializer.rs

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl<R: Read> ReadAdaptor<R> {
9999
Ok(f64::from_be_bytes(buf))
100100
}
101101

102-
pub fn read_to_bytes(&mut self, count: usize) -> Result<Bytes> {
102+
pub fn read_boxed_slice(&mut self, count: usize) -> Result<Box<[u8]>> {
103103
let mut buf = vec![0u8; count];
104104
self.reader
105105
.read_exact(&mut buf)
@@ -113,6 +113,7 @@ impl<R: Read> ReadAdaptor<R> {
113113
pub struct Deserializer<R: Read> {
114114
input: ReadAdaptor<R>,
115115
tag_to_deserialize: Option<u8>,
116+
in_list: bool,
116117
is_named: bool,
117118
}
118119

@@ -121,6 +122,7 @@ impl<R: Read> Deserializer<R> {
121122
Deserializer {
122123
input: ReadAdaptor { reader: input },
123124
tag_to_deserialize: None,
125+
in_list: false,
124126
is_named,
125127
}
126128
}
@@ -148,7 +150,7 @@ impl<'de, R: Read> de::Deserializer<'de> for &mut Deserializer<R> {
148150
type Error = Error;
149151

150152
forward_to_deserialize_any! {
151-
u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit unit_struct seq tuple tuple_struct
153+
i8 i16 i32 i64 f32 f64 char str string unit unit_struct seq tuple tuple_struct
152154
ignored_any bytes enum newtype_struct byte_buf option
153155
}
154156

@@ -195,6 +197,51 @@ impl<'de, R: Read> de::Deserializer<'de> for &mut Deserializer<R> {
195197
result
196198
}
197199

200+
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
201+
where
202+
V: Visitor<'de>,
203+
{
204+
if self.in_list {
205+
let value = self.input.get_u8_be()?;
206+
visitor.visit_u8::<Error>(value)
207+
} else {
208+
panic!("{:?}", self.tag_to_deserialize);
209+
210+
/*
211+
Err(Error::UnsupportedType(
212+
"u8; NBT only supports signed values".to_string(),
213+
))
214+
*/
215+
}
216+
}
217+
218+
fn deserialize_u16<V>(self, _visitor: V) -> Result<V::Value>
219+
where
220+
V: Visitor<'de>,
221+
{
222+
Err(Error::UnsupportedType(
223+
"u16; NBT only supports signed values".to_string(),
224+
))
225+
}
226+
227+
fn deserialize_u32<V>(self, _visitor: V) -> Result<V::Value>
228+
where
229+
V: Visitor<'de>,
230+
{
231+
Err(Error::UnsupportedType(
232+
"u32; NBT only supports signed values".to_string(),
233+
))
234+
}
235+
236+
fn deserialize_u64<V>(self, _visitor: V) -> Result<V::Value>
237+
where
238+
V: Visitor<'de>,
239+
{
240+
Err(Error::UnsupportedType(
241+
"u64; NBT only supports signed values".to_string(),
242+
))
243+
}
244+
198245
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
199246
where
200247
V: Visitor<'de>,
@@ -304,6 +351,10 @@ impl<'de, R: Read> SeqAccess<'de> for ListAccess<'_, R> {
304351

305352
self.remaining_values -= 1;
306353
self.de.tag_to_deserialize = Some(self.list_type);
307-
seed.deserialize(&mut *self.de).map(Some)
354+
self.de.in_list = true;
355+
let result = seed.deserialize(&mut *self.de).map(Some);
356+
self.de.in_list = false;
357+
result
308358
}
309359
}
360+

pumpkin-nbt/src/lib.rs

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ use std::{
44
ops::Deref,
55
};
66

7-
use bytes::{BufMut, Bytes, BytesMut};
7+
use bytes::Bytes;
88
use compound::NbtCompound;
99
use deserializer::ReadAdaptor;
1010
use serde::{de, ser};
1111
use serde::{Deserialize, Deserializer};
12+
use serializer::WriteAdaptor;
1213
use tag::NbtTag;
1314
use thiserror::Error;
1415

@@ -49,6 +50,8 @@ pub enum Error {
4950
Incomplete(io::Error),
5051
#[error("Negative list length {0}")]
5152
NegativeLength(i32),
53+
#[error("Length too large {0}")]
54+
LargeLength(usize),
5255
}
5356

5457
impl ser::Error for Error {
@@ -111,11 +114,15 @@ impl Nbt {
111114
}
112115

113116
pub fn write(&self) -> Bytes {
114-
let mut bytes = BytesMut::new();
115-
bytes.put_u8(COMPOUND_ID);
116-
bytes.put(NbtTag::String(self.name.to_string()).serialize_data());
117-
bytes.put(self.root_tag.serialize_content());
118-
bytes.freeze()
117+
let mut bytes = Vec::new();
118+
let mut writer = WriteAdaptor::new(&mut bytes);
119+
writer.write_u8_be(COMPOUND_ID).unwrap();
120+
NbtTag::String(self.name.to_string())
121+
.serialize_data(&mut writer)
122+
.unwrap();
123+
self.root_tag.serialize_content(&mut writer).unwrap();
124+
125+
bytes.into()
119126
}
120127

121128
pub fn write_to_writer<W: Write>(&self, mut writer: W) -> Result<(), io::Error> {
@@ -125,10 +132,13 @@ impl Nbt {
125132

126133
/// Writes NBT tag, without name of root compound.
127134
pub fn write_unnamed(&self) -> Bytes {
128-
let mut bytes = BytesMut::new();
129-
bytes.put_u8(COMPOUND_ID);
130-
bytes.put(self.root_tag.serialize_content());
131-
bytes.freeze()
135+
let mut bytes = Vec::new();
136+
let mut writer = WriteAdaptor::new(&mut bytes);
137+
138+
writer.write_u8_be(COMPOUND_ID).unwrap();
139+
self.root_tag.serialize_content(&mut writer).unwrap();
140+
141+
bytes.into()
132142
}
133143

134144
pub fn write_unnamed_to_writer<W: Write>(&self, mut writer: W) -> Result<(), io::Error> {
@@ -169,7 +179,7 @@ impl AsMut<NbtCompound> for Nbt {
169179

170180
pub fn get_nbt_string<R: Read>(bytes: &mut ReadAdaptor<R>) -> Result<String, Error> {
171181
let len = bytes.get_u16_be()? as usize;
172-
let string_bytes = bytes.read_to_bytes(len)?;
182+
let string_bytes = bytes.read_boxed_slice(len)?;
173183
let string = cesu8::from_java_cesu8(&string_bytes).map_err(|_| Error::Cesu8DecodingError)?;
174184
Ok(string.to_string())
175185
}
@@ -204,6 +214,7 @@ impl_array!(BytesArray, "byte");
204214

205215
#[cfg(test)]
206216
mod test {
217+
use std::io::Read;
207218
use std::sync::LazyLock;
208219

209220
use flate2::read::GzDecoder;
@@ -212,6 +223,7 @@ mod test {
212223
use pumpkin_world::world_info::{DataPacks, LevelData, WorldGenSettings, WorldVersion};
213224

214225
use crate::deserializer::from_bytes;
226+
use crate::serializer::to_bytes;
215227
use crate::BytesArray;
216228
use crate::IntArray;
217229
use crate::LongArray;
@@ -237,8 +249,10 @@ mod test {
237249
float: 1.00,
238250
string: "Hello test".to_string(),
239251
};
240-
let bytes = to_bytes_unnamed(&test).unwrap();
241-
let recreated_struct: Test = from_bytes_unnamed(&mut &bytes[..]).unwrap();
252+
253+
let mut bytes = Vec::new();
254+
to_bytes_unnamed(&test, &mut bytes).unwrap();
255+
let recreated_struct: Test = from_bytes_unnamed(&bytes[..]).unwrap();
242256

243257
assert_eq!(test, recreated_struct);
244258
}
@@ -260,8 +274,10 @@ mod test {
260274
int_array: vec![13, 1321, 2],
261275
long_array: vec![1, 0, 200301, 1],
262276
};
263-
let bytes = to_bytes_unnamed(&test).unwrap();
264-
let recreated_struct: TestArray = from_bytes_unnamed(&mut &bytes[..]).unwrap();
277+
278+
let mut bytes = Vec::new();
279+
to_bytes_unnamed(&test, &mut bytes).unwrap();
280+
let recreated_struct: TestArray = from_bytes_unnamed(&bytes[..]).unwrap();
265281

266282
assert_eq!(test, recreated_struct);
267283
}
@@ -316,13 +332,40 @@ mod test {
316332
});
317333

318334
#[test]
319-
fn test_serialize_deserialize_level_dat() {
335+
fn test_deserialize_level_dat() {
320336
let raw_compressed_nbt = include_bytes!("../assets/level.dat");
321337
assert!(!raw_compressed_nbt.is_empty());
322338

323339
let decoder = GzDecoder::new(&raw_compressed_nbt[..]);
324-
let level_dat: LevelDat = from_bytes(decoder).unwrap();
340+
let level_dat: LevelDat = from_bytes(decoder).expect("Failed to decode from file");
325341

326342
assert_eq!(level_dat, *LEVEL_DAT);
327343
}
344+
345+
#[test]
346+
fn test_serialize_level_dat() {
347+
let raw_compressed_nbt = include_bytes!("../assets/level.dat");
348+
assert!(!raw_compressed_nbt.is_empty());
349+
350+
let mut decoder = GzDecoder::new(&raw_compressed_nbt[..]);
351+
let mut raw_bytes = Vec::new();
352+
decoder.read_to_end(&mut raw_bytes).unwrap();
353+
354+
let mut serialized = Vec::new();
355+
to_bytes(&*LEVEL_DAT, "".to_string(), &mut serialized).expect("Failed to encode to bytes");
356+
raw_bytes
357+
.iter()
358+
.zip(serialized.iter())
359+
.enumerate()
360+
.for_each(|(index, (expected_byte, serialized_byte))| {
361+
if expected_byte != serialized_byte {
362+
panic!("{} vs {} ({})", expected_byte, serialized_byte, index);
363+
}
364+
});
365+
366+
let level_dat_again: LevelDat =
367+
from_bytes(&serialized[..]).expect("Failed to decode from bytes");
368+
369+
assert_eq!(level_dat_again, *LEVEL_DAT);
370+
}
328371
}

0 commit comments

Comments
 (0)