diff options
-rw-r--r-- | src/byte_order.rs | 319 | ||||
-rw-r--r-- | src/lib.rs | 4 | ||||
-rw-r--r-- | src/nbt.rs | 86 | ||||
-rw-r--r-- | src/types.rs | 99 | ||||
-rw-r--r-- | src/utils.rs | 68 |
5 files changed, 395 insertions, 181 deletions
diff --git a/src/byte_order.rs b/src/byte_order.rs new file mode 100644 index 0000000..f1c40e3 --- /dev/null +++ b/src/byte_order.rs @@ -0,0 +1,319 @@ +use crate::{DeserializeResult, Deserialized, DeserializeErr}; +use crate::utils::take; +use core::convert::TryInto; + +pub type ProtoByteOrder = BigEndian; + +pub trait ByteOrder { + fn write_u2long(v: u128) -> [u8; 16]; + + fn write_2long(v: i128) -> [u8; 16] { + Self::write_u2long(v as u128) + } + + fn read_u2long(data: &[u8]) -> DeserializeResult<u128>; + + fn read_2long(data: &[u8]) -> DeserializeResult<i128> { + Ok(Self::read_u2long(data)?.map(move |data| data as i128)) + } + + fn write_ulong(v: u64) -> [u8; 8]; + + fn write_long(v: i64) -> [u8; 8] { + Self::write_ulong(v as u64) + } + + fn read_ulong(data: &[u8]) -> DeserializeResult<u64>; + + fn read_long(data: &[u8]) -> DeserializeResult<i64> { + Ok(Self::read_ulong(data)?.map(move |data| data as i64)) + } + + fn write_uint(v: u32) -> [u8; 4]; + + fn write_int(v: i32) -> [u8; 4] { + Self::write_uint(v as u32) + } + + fn read_uint(data: &[u8]) -> DeserializeResult<u32>; + + fn read_int(data: &[u8]) -> DeserializeResult<i32> { + Ok(Self::read_uint(data)?.map(move |data| data as i32)) + } + + fn write_ushort(v: u16) -> [u8; 2]; + + fn write_short(v: i16) -> [u8; 2] { + Self::write_ushort(v as u16) + } + + fn read_ushort(data: &[u8]) -> DeserializeResult<u16>; + + fn read_short(data: &[u8]) -> DeserializeResult<i16> { + Ok(Self::read_ushort(data)?.map(move |data| data as i16)) + } + + fn read_ubyte(data: &[u8]) -> DeserializeResult<u8> { + match data.split_first() { + Some((byte, rest)) => Deserialized::ok(*byte, rest), + None => Err(DeserializeErr::Eof) + } + } + + fn read_byte(data: &[u8]) -> DeserializeResult<i8> { + Ok(Self::read_ubyte(data)?.map(move |b| b as i8)) + } + + fn write_float(v: f32) -> [u8; 4]; + + fn read_float(data: &[u8]) -> DeserializeResult<f32>; + + fn write_double(v: f64) -> [u8; 8]; + + fn read_double(data: &[u8]) -> DeserializeResult<f64>; +} + +pub struct BigEndian; + +impl ByteOrder for BigEndian { + fn write_u2long(v: u128) -> [u8; 16] { + [ + ((v >> 120) as u8), + ((v >> 112) as u8), + ((v >> 104) as u8), + ((v >> 96) as u8), + ((v >> 88) as u8), + ((v >> 80) as u8), + ((v >> 72) as u8), + ((v >> 64) as u8), + ((v >> 56) as u8), + ((v >> 48) as u8), + ((v >> 40) as u8), + ((v >> 32) as u8), + ((v >> 24) as u8), + ((v >> 16) as u8), + ((v >> 8) as u8), + (v as u8), + ] + } + + fn read_u2long(data: &[u8]) -> DeserializeResult<'_, u128> { + Ok(take(16, data)?.map(move |bytes| { + ((bytes[0] as u128) << 120) | + ((bytes[1] as u128) << 112) | + ((bytes[2] as u128) << 104) | + ((bytes[3] as u128) << 96) | + ((bytes[4] as u128) << 88) | + ((bytes[5] as u128) << 80) | + ((bytes[6] as u128) << 72) | + ((bytes[7] as u128) << 64) | + ((bytes[8] as u128) << 56) | + ((bytes[9] as u128) << 48) | + ((bytes[10] as u128) << 40) | + ((bytes[11] as u128) << 32) | + ((bytes[12] as u128) << 24) | + ((bytes[13] as u128) << 16) | + ((bytes[14] as u128) << 8) | + (bytes[15] as u128) + })) + } + + fn write_ulong(v: u64) -> [u8; 8] { + [ + ((v >> 56) as u8), + ((v >> 48) as u8), + ((v >> 40) as u8), + ((v >> 32) as u8), + ((v >> 24) as u8), + ((v >> 16) as u8), + ((v >> 8) as u8), + (v as u8), + ] + } + + fn read_ulong(data: &[u8]) -> DeserializeResult<'_, u64> { + Ok(take(8, data)?.map(move |bytes| { + ((bytes[0] as u64) << 56) | + ((bytes[1] as u64) << 48) | + ((bytes[2] as u64) << 40) | + ((bytes[3] as u64) << 32) | + ((bytes[4] as u64) << 24) | + ((bytes[5] as u64) << 16) | + ((bytes[6] as u64) << 8) | + (bytes[7] as u64) + })) + } + + fn write_uint(v: u32) -> [u8; 4] { + [ + ((v >> 24) as u8), + ((v >> 16) as u8), + ((v >> 8) as u8), + (v as u8), + ] + } + + fn read_uint(data: &[u8]) -> DeserializeResult<'_, u32> { + Ok(take(4, data)?.map(move |bytes| { + ((bytes[0] as u32) << 24) | + ((bytes[1] as u32) << 16) | + ((bytes[2] as u32) << 8) | + (bytes[3] as u32) + })) + } + + fn write_ushort(v: u16) -> [u8; 2] { + [ + ((v >> 8) as u8), + (v as u8), + ] + } + + fn read_ushort(data: &[u8]) -> DeserializeResult<'_, u16> { + Ok(take(2, data)? + .map(move |bytes| ((bytes[0] as u16) << 8) | (bytes[1] as u16))) + } + + fn write_float(v: f32) -> [u8; 4] { + v.to_be_bytes() + } + + fn read_float(data: &[u8]) -> DeserializeResult<'_, f32> { + Ok(take(4, data)?.map(move |bytes| { + f32::from_be_bytes(bytes.try_into().expect("is exactly 4 long")) + })) + + } + + fn write_double(v: f64) -> [u8; 8] { + v.to_be_bytes() + } + + fn read_double(data: &[u8]) -> DeserializeResult<'_, f64> { + Ok(take(8, data)?.map(move |bytes| { + f64::from_be_bytes(bytes.try_into().expect("is exactly 8 long")) + })) + } +} + +pub struct LittleEndian; + +impl ByteOrder for LittleEndian { + fn write_u2long(v: u128) -> [u8; 16] { + [ + v as u8, + (v >> 8) as u8, + (v >> 16) as u8, + (v >> 24) as u8, + (v >> 32) as u8, + (v >> 40) as u8, + (v >> 48) as u8, + (v >> 56) as u8, + (v >> 64) as u8, + (v >> 72) as u8, + (v >> 80) as u8, + (v >> 88) as u8, + (v >> 96) as u8, + (v >> 104) as u8, + (v >> 112) as u8, + (v >> 120) as u8, + ] + } + + fn read_u2long(data: &[u8]) -> DeserializeResult<'_, u128> { + Ok(take(16, data)?.map(move |bytes| { + (bytes[0] as u128) | + ((bytes[1] as u128) << 8) | + ((bytes[2] as u128) << 16) | + ((bytes[3] as u128) << 24) | + ((bytes[4] as u128) << 32) | + ((bytes[5] as u128) << 40) | + ((bytes[6] as u128) << 48) | + ((bytes[7] as u128) << 56) | + ((bytes[8] as u128) << 64) | + ((bytes[9] as u128) << 72) | + ((bytes[10] as u128) << 80) | + ((bytes[11] as u128) << 88) | + ((bytes[12] as u128) << 96) | + ((bytes[13] as u128) << 104) | + ((bytes[14] as u128) << 112) | + ((bytes[15] as u128) << 120) + })) + } + + fn write_ulong(v: u64) -> [u8; 8] { + [ + v as u8, + (v >> 8) as u8, + (v >> 16) as u8, + (v >> 24) as u8, + (v >> 32) as u8, + (v >> 40) as u8, + (v >> 48) as u8, + (v >> 56) as u8 + ] + } + + fn read_ulong(data: &[u8]) -> DeserializeResult<'_, u64> { + Ok(take(8, data)?.map(move |bytes| { + (bytes[0] as u64) | + ((bytes[1] as u64) << 8) | + ((bytes[2] as u64) << 16) | + ((bytes[3] as u64) << 24) | + ((bytes[4] as u64) << 32) | + ((bytes[5] as u64) << 40) | + ((bytes[6] as u64) << 48) | + ((bytes[7] as u64) << 56) + })) + } + + fn write_uint(v: u32) -> [u8; 4] { + [ + v as u8, + (v >> 8) as u8, + (v >> 16) as u8, + (v >> 24) as u8, + ] + } + + fn read_uint(data: &[u8]) -> DeserializeResult<'_, u32> { + Ok(take(4, data)?.map(move |bytes| { + (bytes[0] as u32) | + ((bytes[1] as u32) << 8) | + ((bytes[2] as u32) << 16) | + ((bytes[3] as u32) << 24) + })) + } + + fn write_ushort(v: u16) -> [u8; 2] { + [ + v as u8, + (v >> 8) as u8, + ] + } + + fn read_ushort(data: &[u8]) -> DeserializeResult<'_, u16> { + Ok(take(4, data)? + .map(move |bytes| (bytes[0] as u16) | ((bytes[1] as u16) << 8))) + } + + fn write_float(v: f32) -> [u8; 4] { + v.to_le_bytes() + } + + fn read_float(data: &[u8]) -> DeserializeResult<'_, f32> { + Ok(take(4, data)?.map(move |bytes| { + f32::from_le_bytes(bytes.try_into().expect("is exactly 4 long")) + })) + } + + fn write_double(v: f64) -> [u8; 8] { + v.to_le_bytes() + } + + fn read_double(data: &[u8]) -> DeserializeResult<'_, f64> { + Ok(take(8, data)?.map(move |bytes| { + f64::from_le_bytes(bytes.try_into().expect("is exactly 8 long")) + })) + } +}
\ No newline at end of file @@ -15,11 +15,11 @@ pub mod types; pub mod utils; pub mod uuid; pub mod v1_15_2; - mod chat; +mod byte_order; pub use deserialize::*; pub use serialize::*; #[cfg(all(test, feature = "std"))] -mod test_macros;
\ No newline at end of file +mod test_macros; @@ -1,11 +1,10 @@ -use crate::utils::{ - read_int, read_long, read_one_byte, read_short, take, write_int, write_long, write_short, -}; +use crate::utils::take; use crate::{DeserializeErr, DeserializeResult, Deserialized}; use alloc::{string::{String, ToString}, borrow::ToOwned, fmt, vec::Vec, vec, format}; #[cfg(all(test, feature = "std"))] use crate::protocol::TestRandom; +use crate::byte_order::{ProtoByteOrder, ByteOrder}; #[derive(Clone, Debug, PartialEq)] pub struct NamedTag { @@ -193,10 +192,7 @@ fn write_contents<F>(contents: &Vec<F>) -> String // reads from the root level fn read_nbt_data(data: &[u8]) -> DeserializeResult<NamedTag> { - let Deserialized { - value: tag_type_id, - data: _, - } = read_one_byte(data)?; + let Deserialized { value: tag_type_id, data: _ } = ProtoByteOrder::read_ubyte(data)?; match tag_type_id { 0x0A => read_named_tag(data), other => Err(DeserializeErr::NbtInvalidStartTag(other)), @@ -205,10 +201,7 @@ fn read_nbt_data(data: &[u8]) -> DeserializeResult<NamedTag> { // reads any named tag: read id -> read name -> read tag with id -> name tag with name pub fn read_named_tag(data: &[u8]) -> DeserializeResult<NamedTag> { - let Deserialized { - value: tag_type_id, - data, - } = read_one_byte(data)?; + let Deserialized { value: tag_type_id, data } = ProtoByteOrder::read_ubyte(data)?; if tag_type_id == 0x00 { // tag end Deserialized::ok(Tag::End.with_name(""), data) @@ -239,32 +232,32 @@ pub fn read_tag(tag_type_id: u8, data: &[u8]) -> DeserializeResult<Tag> { } fn read_tag_byte(data: &[u8]) -> DeserializeResult<Tag> { - Ok(read_one_byte(data)?.map(move |byte| Tag::Byte(byte as i8))) + Ok(ProtoByteOrder::read_byte(data)?.map(Tag::Byte)) } fn read_tag_short(data: &[u8]) -> DeserializeResult<Tag> { - Ok(read_short(data)?.map(move |i| Tag::Short(i as i16))) + Ok(ProtoByteOrder::read_short(data)?.map(Tag::Short)) } fn read_tag_int(data: &[u8]) -> DeserializeResult<Tag> { - Ok(read_int(data)?.map(move |i| Tag::Int(i as i32))) + Ok(ProtoByteOrder::read_int(data)?.map(Tag::Int)) } fn read_tag_long(data: &[u8]) -> DeserializeResult<Tag> { - Ok(read_long(data)?.map(move |i| Tag::Long(i as i64))) + Ok(ProtoByteOrder::read_long(data)?.map(Tag::Long)) } fn read_tag_float(data: &[u8]) -> DeserializeResult<Tag> { - Ok(read_int(data)?.map(move |i| Tag::Float(f32::from_bits(i as u32)))) + Ok(ProtoByteOrder::read_float(data)?.map(Tag::Float)) } fn read_tag_double(data: &[u8]) -> DeserializeResult<Tag> { - Ok(read_long(data)?.map(move |i| Tag::Double(f64::from_bits(i as u64)))) + Ok(ProtoByteOrder::read_double(data)?.map(Tag::Double)) } fn read_tag_byte_array(data: &[u8]) -> DeserializeResult<Tag> { - Ok(read_int(data)? - .and_then(move |size, rest| take(size as usize)(rest))? + Ok(ProtoByteOrder::read_int(data)? + .and_then(move |size, rest| take(size as usize, rest))? .map(move |arr| Tag::ByteArray(Vec::from(arr)))) } @@ -273,18 +266,17 @@ fn read_tag_string(data: &[u8]) -> DeserializeResult<Tag> { } fn read_tag_list(data: &[u8]) -> DeserializeResult<Tag> { - let Deserialized { value: contents_tag_type_id, data } = read_one_byte(data)?; - let Deserialized { value: list_length, data } = read_int(data)?; + let Deserialized { value: contents_tag_type_id, data } = ProtoByteOrder::read_ubyte(data)?; + let Deserialized { value: list_length, data } = ProtoByteOrder::read_int(data)?; if list_length == 0 { Deserialized::ok(Tag::List(vec![]), data) } else { let mut out_vec = Vec::with_capacity(list_length as usize); let mut remaining_data = data; for _ in 0..list_length { - let Deserialized { - value: element, - data: rest, - } = read_tag(contents_tag_type_id, &remaining_data)?; + let Deserialized { value: element, data: rest } = + read_tag(contents_tag_type_id, &remaining_data)?; + out_vec.push(element); remaining_data = rest; } @@ -312,19 +304,11 @@ fn read_tag_compound(data: &[u8]) -> DeserializeResult<Tag> { } fn read_tag_int_array(data: &[u8]) -> DeserializeResult<Tag> { - read_array_tag( - data, - move |data| Ok(read_int(data)?.map(move |r| r as i32)), - Tag::IntArray, - ) + read_array_tag(data, ProtoByteOrder::read_int, Tag::IntArray) } fn read_tag_long_array(data: &[u8]) -> DeserializeResult<Tag> { - read_array_tag( - data, - move |data| Ok(read_long(data)?.map(move |r| r as i64)), - Tag::LongArray, - ) + read_array_tag(data, ProtoByteOrder::read_long, Tag::LongArray) } fn read_array_tag<'a, R, F, M>( @@ -336,7 +320,7 @@ fn read_array_tag<'a, R, F, M>( F: Fn(&'a [u8]) -> DeserializeResult<'a, R>, M: Fn(Vec<R>) -> Tag, { - let Deserialized { value: count, data } = read_int(data)?.map(move |v| v as i32); + let Deserialized { value: count, data } = ProtoByteOrder::read_int(data)?.map(move |v| v as i32); if count < 0 { Err(DeserializeErr::NbtBadLength(count as isize)) } else { @@ -356,8 +340,8 @@ fn read_array_tag<'a, R, F, M>( } fn read_string(data: &[u8]) -> DeserializeResult<String> { - read_short(data)? - .and_then(move |length, data| take(length as usize)(data))? + ProtoByteOrder::read_short(data)? + .and_then(move |length, data| take(length as usize, data))? .try_map(move |bytes| { String::from_utf8(Vec::from(bytes)) .map_err(move |err| DeserializeErr::BadStringEncoding(err)) @@ -373,7 +357,7 @@ impl NamedTag { } else { let payload_bytes = self.payload.bytes(); let name_len = self.name.len(); - let name_len_bytes = write_short(name_len as u16); + let name_len_bytes = ProtoByteOrder::write_ushort(name_len as u16); let mut out = Vec::with_capacity(1 + name_len_bytes.len() + name_len + payload_bytes.len()); out.push(type_id); @@ -407,15 +391,15 @@ impl Tag { pub fn bytes(&self) -> Vec<u8> { match self { Tag::Byte(b) => vec![*b as u8], - Tag::Short(v) => Vec::from(write_short(*v as u16)), - Tag::Int(v) => Vec::from(write_int(*v as u32)), - Tag::Long(v) => Vec::from(write_long(*v as u64)), - Tag::Float(v) => Vec::from(write_int(v.to_bits())), - Tag::Double(v) => Vec::from(write_long(v.to_bits())), + Tag::Short(v) => Vec::from(ProtoByteOrder::write_short(*v)), + Tag::Int(v) => Vec::from(ProtoByteOrder::write_int(*v)), + Tag::Long(v) => Vec::from(ProtoByteOrder::write_long(*v)), + Tag::Float(v) => Vec::from(ProtoByteOrder::write_float(*v)), + Tag::Double(v) => Vec::from(ProtoByteOrder::write_double(*v)), Tag::ByteArray(v) => { let n = v.len(); let mut out = Vec::with_capacity(n + 4); - let size_bytes = write_int(n as u32); + let size_bytes = ProtoByteOrder::write_uint(n as u32); out.extend_from_slice(&size_bytes); out.extend(v); out @@ -423,7 +407,7 @@ impl Tag { Tag::String(v) => { let n = v.len(); let mut out = Vec::with_capacity(n + 2); - let size_bytes = write_short(n as u16); + let size_bytes = ProtoByteOrder::write_ushort(n as u16); out.extend_from_slice(&size_bytes); out.extend(v.bytes()); out @@ -452,7 +436,7 @@ impl Tag { let mut out = Vec::new(); out.push(elem_id); - let count_bytes = write_int(count as u32); + let count_bytes = ProtoByteOrder::write_uint(count as u32); out.extend_from_slice(&count_bytes); out.extend(v.iter().flat_map(move |elem| elem.bytes().into_iter())); out @@ -468,10 +452,10 @@ impl Tag { Tag::IntArray(v) => { let n = v.len(); let mut out = Vec::with_capacity(4 + (4 * n)); - let n_bytes = write_int(n as u32); + let n_bytes = ProtoByteOrder::write_uint(n as u32); out.extend_from_slice(&n_bytes); for value in v { - let bytes = write_int(*value as u32); + let bytes = ProtoByteOrder::write_int(*value); out.extend_from_slice(&bytes); } out @@ -479,10 +463,10 @@ impl Tag { Tag::LongArray(v) => { let n = v.len(); let mut out = Vec::with_capacity(4 + (8 * n)); - let n_bytes = write_int(n as u32); + let n_bytes = ProtoByteOrder::write_uint(n as u32); out.extend_from_slice(&n_bytes); for value in v { - let bytes = write_long(*value as u64); + let bytes = ProtoByteOrder::write_long(*value); out.extend_from_slice(&bytes); } out diff --git a/src/types.rs b/src/types.rs index 1c4ac71..ac2334c 100644 --- a/src/types.rs +++ b/src/types.rs @@ -9,6 +9,7 @@ pub use super::chat::*; #[cfg(all(test, feature = "std"))] use crate::protocol::TestRandom; +use crate::byte_order::{ProtoByteOrder, ByteOrder}; // bool impl Serialize for bool { @@ -19,7 +20,7 @@ impl Serialize for bool { impl Deserialize for bool { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - read_one_byte(data)?.try_map(move |b| match b { + ProtoByteOrder::read_ubyte(data)?.try_map(move |b| match b { 0x00 => Ok(false), 0x01 => Ok(true), other => Err(DeserializeErr::InvalidBool(other)), @@ -43,7 +44,7 @@ impl Serialize for u8 { impl Deserialize for u8 { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - read_one_byte(data) + ProtoByteOrder::read_ubyte(data) } } @@ -63,7 +64,7 @@ impl Serialize for i8 { impl Deserialize for i8 { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - Ok(read_one_byte(data)?.map(move |byte| byte as i8)) + ProtoByteOrder::read_byte(data) } } @@ -77,14 +78,14 @@ impl TestRandom for i8 { // u16 impl Serialize for u16 { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { - let data = write_short(*self); - to.serialize_bytes(&data[..]) + let data = ProtoByteOrder::write_ushort(*self); + to.serialize_bytes(&data) } } impl Deserialize for u16 { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - read_short(data) + ProtoByteOrder::read_ushort(data) } } @@ -98,15 +99,14 @@ impl TestRandom for u16 { // i16 impl Serialize for i16 { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { - (*self as u16).mc_serialize(to) + let data = ProtoByteOrder::write_short(*self); + to.serialize_bytes(&data) } } impl Deserialize for i16 { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - u16::mc_deserialize(data)? - .map(move |other| other as i16) - .into() + ProtoByteOrder::read_short(data) } } @@ -120,14 +120,14 @@ impl TestRandom for i16 { // int impl Serialize for i32 { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { - let data = write_int(*self as u32); + let data = ProtoByteOrder::write_int(*self); to.serialize_bytes(&data[..]) } } impl Deserialize for i32 { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - Ok(read_int(data)?.map(move |v| v as i32)) + ProtoByteOrder::read_int(data) } } @@ -141,14 +141,14 @@ impl TestRandom for i32 { // long impl Serialize for i64 { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { - let data = write_long(*self as u64); + let data = ProtoByteOrder::write_long(*self); to.serialize_bytes(&data[..]) } } impl Deserialize for i64 { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - Ok(read_long(data)?.map(move |v| v as i64)) + ProtoByteOrder::read_long(data) } } @@ -163,16 +163,14 @@ impl TestRandom for i64 { impl Serialize for f32 { //noinspection ALL fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { - let data = (*self).to_be_bytes(); + let data = ProtoByteOrder::write_float(*self); to.serialize_bytes(&data[..]) } } impl Deserialize for f32 { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - i32::mc_deserialize(data)? - .map(move |r| f32::from_bits(r as u32)) - .into() + ProtoByteOrder::read_float(data) } } @@ -187,16 +185,14 @@ impl TestRandom for f32 { impl Serialize for f64 { //noinspection ALL fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { - let data = (*self).to_be_bytes(); + let data = ProtoByteOrder::write_double(*self); to.serialize_bytes(&data[..]) } } impl Deserialize for f64 { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - i64::mc_deserialize(data)? - .map(move |r| f64::from_bits(r as u64)) - .into() + ProtoByteOrder::read_double(data) } } @@ -323,10 +319,7 @@ fn deserialize_var_num(orig_data: &[u8], max_bytes: usize) -> DeserializeResult< if i == max_bytes { return DeserializeErr::VarNumTooLong(Vec::from(&orig_data[..i])).into(); } - let Deserialized { - value: byte, - data: rest, - } = read_one_byte(data)?; + let Deserialized { value: byte, data: rest} = ProtoByteOrder::read_ubyte(data)?; data = rest; has_more = byte & 0x80 != 0; v |= ((byte as u64) & 0x7F) << bit_place; @@ -351,7 +344,7 @@ impl Deserialize for String { if length.0 < 0 { Err(DeserializeErr::NegativeLength(length)) } else { - take(length.0 as usize)(rest)?.try_map(move |taken| { + take(length.0 as usize, rest)?.try_map(move |taken| { String::from_utf8(taken.to_vec()).map_err(DeserializeErr::BadStringEncoding) }) } @@ -396,30 +389,30 @@ impl Serialize for IntPosition { } else { self.x as u64 } & 0x3FFFFFF; + let z_raw = if self.z < 0 { (self.z + 0x2000000) as u64 | 0x2000000 } else { self.z as u64 } & 0x3FFFFFF; + let y_raw = if self.y < 0 { (self.y + 0x800) as u64 | 0x800 } else { self.y as u64 } & 0xFFF; - let data_raw = ((x_raw << 38) | (z_raw << 12) | y_raw) as u64; - let data_i64 = data_raw as i64; - to.serialize_other(&data_i64) + let data = ProtoByteOrder::write_ulong(((x_raw << 38) | (z_raw << 12) | y_raw) as u64); + to.serialize_bytes(&data) } } impl Deserialize for IntPosition { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - let Deserialized { value: raw, data } = i64::mc_deserialize(data)?; - let raw_unsigned = raw as u64; - let mut x = ((raw_unsigned >> 38) as u32) & 0x3FFFFFF; - let mut z = ((raw_unsigned >> 12) & 0x3FFFFFF) as u32; - let mut y = ((raw_unsigned & 0xFFF) as u16) & 0xFFF; + let Deserialized { value: raw, data } = ProtoByteOrder::read_ulong(data)?; + let mut x = ((raw >> 38) as u32) & 0x3FFFFFF; + let mut z = ((raw >> 12) & 0x3FFFFFF) as u32; + let mut y = ((raw & 0xFFF) as u16) & 0xFFF; if (x & 0x2000000) != 0 { // is the 26th bit set @@ -470,7 +463,7 @@ impl Serialize for Angle { impl Deserialize for Angle { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - Ok(read_one_byte(data)?.map(move |b| Angle { value: b })) + Ok(ProtoByteOrder::read_ubyte(data)?.map(move |b| Angle { value: b })) } } @@ -487,34 +480,14 @@ impl TestRandom for Angle { impl Serialize for UUID4 { fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { - let bytes = self.to_u128().to_be_bytes(); + let bytes = ProtoByteOrder::write_u2long(self.to_u128()); to.serialize_bytes(&bytes[..]) } } impl Deserialize for UUID4 { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - take(16)(data)? - .map(move |bytes| { - let raw = (bytes[0] as u128) << 120 - | (bytes[1] as u128) << 112 - | (bytes[2] as u128) << 104 - | (bytes[3] as u128) << 96 - | (bytes[4] as u128) << 88 - | (bytes[5] as u128) << 80 - | (bytes[6] as u128) << 72 - | (bytes[7] as u128) << 64 - | (bytes[8] as u128) << 56 - | (bytes[9] as u128) << 48 - | (bytes[10] as u128) << 40 - | (bytes[11] as u128) << 32 - | (bytes[12] as u128) << 24 - | (bytes[13] as u128) << 16 - | (bytes[14] as u128) << 8 - | bytes[15] as u128; - UUID4::from(raw) - }) - .into() + Ok(ProtoByteOrder::read_u2long(data)?.map(move |raw| UUID4::from(raw))) } } @@ -695,14 +668,8 @@ impl Serialize for Slot { impl Deserialize for Slot { fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - let Deserialized { - value: item_id, - data, - } = VarInt::mc_deserialize(data)?; - let Deserialized { - value: item_count, - data, - } = i8::mc_deserialize(data)?; + let Deserialized { value: item_id, data} = VarInt::mc_deserialize(data)?; + let Deserialized { value: item_count, data} = i8::mc_deserialize(data)?; if data.is_empty() { return Err(DeserializeErr::Eof); } diff --git a/src/utils.rs b/src/utils.rs index fcfcb70..4223cac 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,70 +1,14 @@ -use crate::{DeserializeErr, DeserializeResult, Deserialized}; +use crate::{DeserializeErr, DeserializeResult}; use alloc::string::String; -pub fn read_one_byte(data: &[u8]) -> DeserializeResult<u8> { - match data.split_first() { - Some((byte, rest)) => Deserialized::ok(*byte, rest), - None => Err(DeserializeErr::Eof), - } -} - -pub fn take(amount: usize) -> impl for<'b> Fn(&'b [u8]) -> DeserializeResult<'b, &'b [u8]> { - move |data| { - if data.len() < amount { - Err(DeserializeErr::Eof) - } else { - Ok(data.split_at(amount).into()) - } +pub fn take(amount: usize, data: &[u8]) -> DeserializeResult<&[u8]> { + if data.len() < amount { + Err(DeserializeErr::Eof) + } else { + Ok(data.split_at(amount).into()) } } -pub fn read_long(data: &[u8]) -> DeserializeResult<u64> { - Ok(take(8)(data)?.map(move |bytes| { - (bytes[0] as u64) << 56 - | (bytes[1] as u64) << 48 - | (bytes[2] as u64) << 40 - | (bytes[3] as u64) << 32 - | (bytes[4] as u64) << 24 - | (bytes[5] as u64) << 16 - | (bytes[6] as u64) << 8 - | (bytes[7] as u64) - })) -} - -pub fn write_long(v: u64) -> [u8; 8] { - [ - (v >> 56) as u8, - (v >> 48) as u8, - (v >> 40) as u8, - (v >> 32) as u8, - (v >> 24) as u8, - (v >> 16) as u8, - (v >> 8) as u8, - v as u8, - ] -} - -pub fn read_int(data: &[u8]) -> DeserializeResult<u32> { - Ok(take(4)(data)?.map(move |bytes| { - (bytes[0] as u32) << 24 - | (bytes[1] as u32) << 16 - | (bytes[2] as u32) << 8 - | (bytes[3] as u32) - })) -} - -pub fn write_int(v: u32) -> [u8; 4] { - [(v >> 24) as u8, (v >> 16) as u8, (v >> 8) as u8, v as u8] -} - -pub fn read_short(data: &[u8]) -> DeserializeResult<u16> { - Ok(take(2)(data)?.map(move |bytes| (bytes[0] as u16) << 8 | (bytes[1] as u16))) -} - -pub fn write_short(v: u16) -> [u8; 2] { - [(v >> 8) as u8, v as u8] -} - pub fn hex(data: &[u8]) -> String { let mut str = String::with_capacity(data.len() * 2); for byte_ref in data { |