aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/byte_order.rs319
-rw-r--r--src/lib.rs4
-rw-r--r--src/nbt.rs86
-rw-r--r--src/types.rs99
-rw-r--r--src/utils.rs68
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
diff --git a/src/lib.rs b/src/lib.rs
index 1a41cce..418400f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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;
diff --git a/src/nbt.rs b/src/nbt.rs
index 057ca25..8dfaa9b 100644
--- a/src/nbt.rs
+++ b/src/nbt.rs
@@ -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 {