diff options
| author | mat <github@matdoes.dev> | 2022-05-01 23:06:56 -0500 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2022-05-01 23:06:56 -0500 |
| commit | bec2da64d81883e3ea909452e71e17b9d22b2adc (patch) | |
| tree | d4f94abc09534768f2531a4c23f54dcc2dab2814 /azalea-nbt/src | |
| parent | 4d75415130a008f83c3bd594ca4cefd01f3d53dd (diff) | |
| parent | db2fcecdc38ea7a43b098c6282dd906b73981f97 (diff) | |
| download | azalea-drasl-bec2da64d81883e3ea909452e71e17b9d22b2adc.tar.xz | |
Merge branch 'main' into chunk-decoding
Diffstat (limited to 'azalea-nbt/src')
| -rwxr-xr-x | azalea-nbt/src/decode.rs | 88 |
1 files changed, 36 insertions, 52 deletions
diff --git a/azalea-nbt/src/decode.rs b/azalea-nbt/src/decode.rs index 3e2f7adb..7f2ca754 100755 --- a/azalea-nbt/src/decode.rs +++ b/azalea-nbt/src/decode.rs @@ -1,64 +1,57 @@ use crate::Error; use crate::Tag; -use async_compression::tokio::bufread::{GzipDecoder, ZlibDecoder}; -use async_recursion::async_recursion; +use byteorder::{ReadBytesExt, BE}; +use flate2::read::{GzDecoder, ZlibDecoder}; use std::collections::HashMap; -use tokio::io::AsyncBufRead; -use tokio::io::{AsyncRead, AsyncReadExt}; +use std::io::BufRead; +use std::io::Read; #[inline] -async fn read_string<R>(stream: &mut R) -> Result<String, Error> -where - R: AsyncRead + std::marker::Unpin, -{ - let length = stream.read_u16().await?; +fn read_string(stream: &mut impl Read) -> Result<String, Error> { + let length = stream.read_u16::<BE>()?; let mut buf = Vec::with_capacity(length as usize); for _ in 0..length { - buf.push(stream.read_u8().await?); + buf.push(stream.read_u8()?); } Ok(String::from_utf8(buf)?) } impl Tag { #[inline] - #[async_recursion] - async fn read_known<R>(stream: &mut R, id: u8) -> Result<Tag, Error> - where - R: AsyncRead + std::marker::Unpin + std::marker::Send, - { + fn read_known(stream: &mut impl Read, id: u8) -> Result<Tag, Error> { let tag = match id { // Signifies the end of a TAG_Compound. It is only ever used inside // a TAG_Compound, and is not named despite being in a TAG_Compound 0 => Tag::End, // A single signed byte - 1 => Tag::Byte(stream.read_i8().await?), + 1 => Tag::Byte(stream.read_i8()?), // A single signed, big endian 16 bit integer - 2 => Tag::Short(stream.read_i16().await?), + 2 => Tag::Short(stream.read_i16::<BE>()?), // A single signed, big endian 32 bit integer - 3 => Tag::Int(stream.read_i32().await?), + 3 => Tag::Int(stream.read_i32::<BE>()?), // A single signed, big endian 64 bit integer - 4 => Tag::Long(stream.read_i64().await?), + 4 => Tag::Long(stream.read_i64::<BE>()?), // A single, big endian IEEE-754 single-precision floating point // number (NaN possible) - 5 => Tag::Float(stream.read_f32().await?), + 5 => Tag::Float(stream.read_f32::<BE>()?), // A single, big endian IEEE-754 double-precision floating point // number (NaN possible) - 6 => Tag::Double(stream.read_f64().await?), + 6 => Tag::Double(stream.read_f64::<BE>()?), // A length-prefixed array of signed bytes. The prefix is a signed // integer (thus 4 bytes) 7 => { - let length = stream.read_i32().await?; + let length = stream.read_i32::<BE>()?; let mut bytes = Vec::with_capacity(length as usize); for _ in 0..length { - bytes.push(stream.read_i8().await?); + bytes.push(stream.read_i8()?); } Tag::ByteArray(bytes) } // A length-prefixed modified UTF-8 string. The prefix is an // unsigned short (thus 2 bytes) signifying the length of the // string in bytes - 8 => Tag::String(read_string(stream).await?), + 8 => Tag::String(read_string(stream)?), // A list of nameless tags, all of the same type. The list is // prefixed with the Type ID of the items it contains (thus 1 // byte), and the length of the list as a signed integer (a further @@ -68,11 +61,11 @@ impl Tag { // another reference implementation by Mojang uses 1 instead; // parsers should accept any type if the length is <= 0). 9 => { - let type_id = stream.read_u8().await?; - let length = stream.read_i32().await?; + let type_id = stream.read_u8()?; + let length = stream.read_i32::<BE>()?; let mut list = Vec::with_capacity(length as usize); for _ in 0..length { - list.push(Tag::read_known(stream, type_id).await?); + list.push(Tag::read_known(stream, type_id)?); } Tag::List(list) } @@ -81,12 +74,12 @@ impl Tag { // we default to capacity 4 because it'll probably not be empty let mut map = HashMap::with_capacity(4); loop { - let tag_id = stream.read_u8().await.unwrap_or(0); + let tag_id = stream.read_u8().unwrap_or(0); if tag_id == 0 { break; } - let name = read_string(stream).await?; - let tag = Tag::read_known(stream, tag_id).await?; + let name = read_string(stream)?; + let tag = Tag::read_known(stream, tag_id)?; map.insert(name, tag); } Tag::Compound(map) @@ -95,20 +88,20 @@ impl Tag { // signed integer (thus 4 bytes) and indicates the number of 4 byte // integers. 11 => { - let length = stream.read_i32().await?; + let length = stream.read_i32::<BE>()?; let mut ints = Vec::with_capacity(length as usize); for _ in 0..length { - ints.push(stream.read_i32().await?); + ints.push(stream.read_i32::<BE>()?); } Tag::IntArray(ints) } // A length-prefixed array of signed longs. The prefix is a signed // integer (thus 4 bytes) and indicates the number of 8 byte longs. 12 => { - let length = stream.read_i32().await?; + let length = stream.read_i32::<BE>()?; let mut longs = Vec::with_capacity(length as usize); for _ in 0..length { - longs.push(stream.read_i64().await?); + longs.push(stream.read_i64::<BE>()?); } Tag::LongArray(longs) } @@ -117,38 +110,29 @@ impl Tag { Ok(tag) } - pub async fn read<R>(stream: &mut R) -> Result<Tag, Error> - where - R: AsyncRead + std::marker::Unpin + std::marker::Send, - { + pub fn read(stream: &mut impl Read) -> Result<Tag, Error> { // default to compound tag // the parent compound only ever has one item - let tag_id = stream.read_u8().await.unwrap_or(0); + let tag_id = stream.read_u8().unwrap_or(0); if tag_id == 0 { return Ok(Tag::End); } - let name = read_string(stream).await?; - let tag = Tag::read_known(stream, tag_id).await?; + let name = read_string(stream)?; + let tag = Tag::read_known(stream, tag_id)?; let mut map = HashMap::with_capacity(1); map.insert(name, tag); Ok(Tag::Compound(map)) } - pub async fn read_zlib<R>(stream: &mut R) -> Result<Tag, Error> - where - R: AsyncBufRead + std::marker::Unpin + std::marker::Send, - { + pub fn read_zlib(stream: &mut impl BufRead) -> Result<Tag, Error> { let mut gz = ZlibDecoder::new(stream); - Tag::read(&mut gz).await + Tag::read(&mut gz) } - pub async fn read_gzip<R>(stream: &mut R) -> Result<Tag, Error> - where - R: AsyncBufRead + std::marker::Unpin + std::marker::Send, - { - let mut gz = GzipDecoder::new(stream); - Tag::read(&mut gz).await + pub fn read_gzip(stream: &mut impl Read) -> Result<Tag, Error> { + let mut gz = GzDecoder::new(stream); + Tag::read(&mut gz) } } |
