From a91d2622717a0bd63747caca4d30793ed659cc7b Mon Sep 17 00:00:00 2001 From: MeexReay Date: Thu, 1 May 2025 14:36:30 +0300 Subject: [PATCH] varint alias functions --- src/data/reader.rs | 206 +++++++++++++++++++++++++++++++++++++++++++-- src/data/writer.rs | 103 +++++++++++++++++++++-- src/lib.rs | 6 +- src/packet.rs | 4 +- src/tests.rs | 90 ++++++++++---------- 5 files changed, 346 insertions(+), 63 deletions(-) diff --git a/src/data/reader.rs b/src/data/reader.rs index 85ad464..395fd92 100755 --- a/src/data/reader.rs +++ b/src/data/reader.rs @@ -1,5 +1,5 @@ use crate::ProtocolError; -use std::io::Read; +use std::{io::Read, usize}; use uuid::Uuid; /// Packet data reader trait @@ -13,7 +13,7 @@ pub trait DataReader { } /// Read String fn read_string(&mut self) -> Result { - let size = self.read_varint()? as usize; + let size = self.read_usize_varint()?; match String::from_utf8(self.read_bytes(size)?) { Ok(i) => Ok(i), Err(_) => Err(ProtocolError::StringParseError), @@ -70,7 +70,201 @@ pub trait DataReader { .map(|o| Uuid::from_bytes(o)) } - /// Read VarInt as i32 with size in bytes (varint, size) + /// Read VarInt as u8 + fn read_u8_varint(&mut self) -> Result { + TryInto::::try_into(self.read_varint()?).map_err(|_| ProtocolError::VarIntError) + } + /// Read VarInt as u16 + fn read_u16_varint(&mut self) -> Result { + TryInto::::try_into(self.read_varint()?).map_err(|_| ProtocolError::VarIntError) + } + /// Read VarInt as u32 + /// + /// Returns error if the value is greater than i32::MAX + fn read_u32_varint(&mut self) -> Result { + let val = self.read_varint()?; + if val < 0 { return Err(ProtocolError::VarIntError); } + TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError) + } + /// Read VarInt as usize + fn read_usize_varint(&mut self) -> Result { + Ok(TryInto::::try_into(self.read_varint()?).map_err(|_| ProtocolError::VarIntError)?) + } + /// Read VarInt as i8 + fn read_i8_varint(&mut self) -> Result { + TryInto::::try_into(self.read_varint()?).map_err(|_| ProtocolError::VarIntError) + } + /// Read VarInt as i16 + fn read_i16_varint(&mut self,) -> Result { + TryInto::::try_into(self.read_varint()?).map_err(|_| ProtocolError::VarIntError) + } + /// Read VarInt as i32 + /// + /// *Use [read_varint](DataReader::read_varint) instead* + fn read_i32_varint(&mut self) -> Result { + self.read_varint() + } + /// Read VarInt as isize + fn read_isize_varint(&mut self) -> Result { + Ok(TryInto::::try_into(self.read_varint()?).map_err(|_| ProtocolError::VarIntError)?) + } + + /// Read VarLong as u8 + fn read_u8_varlong(&mut self) -> Result { + TryInto::::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError) + } + /// Read VarLong as u16 + fn read_u16_varlong(&mut self) -> Result { + TryInto::::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError) + } + /// Read VarLong as u32 + fn read_u32_varlong(&mut self) -> Result { + TryInto::::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError) + } + /// Read VarLong as usize + /// + /// Returns error if the value is greater than i64::MAX + fn read_usize_varlong(&mut self) -> Result { + let val = TryInto::::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError)?; + if val as u64 > i64::MAX as u64 { return Err(ProtocolError::VarIntError); } + Ok(val) + } + /// Read VarLong as u64 + /// + /// Returns error if the value is greater than i64::MAX + fn read_u64_varlong(&mut self) -> Result { + let val = self.read_varlong()?; + if val < 0 { return Err(ProtocolError::VarIntError); } + TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError) + } + /// Read VarLong as i8 + fn read_i8_varlong(&mut self) -> Result { + TryInto::::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError) + } + /// Read VarLong as i16 + fn read_i16_varlong(&mut self) -> Result { + TryInto::::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError) + } + /// Read VarLong as i32 + fn read_i32_varlong(&mut self) -> Result { + TryInto::::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError) + } + /// Read VarLong as isize + fn read_isize_varlong(&mut self) -> Result { + Ok(TryInto::::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError)?) + } + /// Read VarLong as i64 + /// + /// *Use [read_varlong](DataReader::read_varlong) instead* + fn read_i64_varlong(&mut self) -> Result { + self.read_varlong() + } + + /// Read VarInt as u8 with size in bytes (value, size) + fn read_u8_varint_size(&mut self) -> Result<(u8, usize), ProtocolError> { + let (val, size) = self.read_varint_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarInt as u16 with size in bytes (value, size) + fn read_u16_varint_size(&mut self) -> Result<(u16, usize), ProtocolError> { + let (val, size) = self.read_varint_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarInt as u32 with size in bytes (value, size) + /// + /// Returns error if the value is greater than i32::MAX + fn read_u32_varint_size(&mut self) -> Result<(u32, usize), ProtocolError> { + let (val, size) = self.read_varint_size()?; + if val < 0 { return Err(ProtocolError::VarIntError); } + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarInt as usize with size in bytes (value, size) + fn read_usize_varint_size(&mut self) -> Result<(usize, usize), ProtocolError> { + let (val, size) = self.read_varint_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarInt as i8 with size in bytes (value, size) + fn read_i8_varint_size(&mut self) -> Result<(i8, usize), ProtocolError> { + let (val, size) = self.read_varint_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarInt as i16 with size in bytes (value, size) + fn read_i16_varint_size(&mut self,) -> Result<(i16, usize), ProtocolError> { + let (val, size) = self.read_varint_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarInt as i32 with size in bytes (value, size) + /// + /// *Use [read_varint_size](DataReader::read_varint_size) instead* + fn read_i32_varint_size(&mut self) -> Result<(i32, usize), ProtocolError> { + self.read_varint_size() + } + /// Read VarInt as isize with size in bytes (value, size) + fn read_isize_varint_size(&mut self) -> Result<(isize, usize), ProtocolError> { + let (val, size) = self.read_varint_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + + /// Read VarLong as u8 with size in bytes (value, size) + fn read_u8_varlong_size(&mut self) -> Result<(u8, usize), ProtocolError> { + let (val, size) = self.read_varlong_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarLong as u16 with size in bytes (value, size) + fn read_u16_varlong_size(&mut self) -> Result<(u16, usize), ProtocolError> { + let (val, size) = self.read_varlong_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarLong as u32 with size in bytes (value, size) + fn read_u32_varlong_size(&mut self) -> Result<(u32, usize), ProtocolError> { + let (val, size) = self.read_varlong_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarLong as usize with size in bytes (value, size) + /// + /// Returns error if the value is greater than i64::MAX + fn read_usize_varlong_size(&mut self) -> Result<(usize, usize), ProtocolError> { + let (val, size) = self.read_varlong_size()?; + let val = TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?; + if val as u64 > i64::MAX as u64 { return Err(ProtocolError::VarIntError); } + Ok((val, size)) + } + /// Read VarLong as u64 with size in bytes (value, size) + /// + /// Returns error if the value is greater than i64::MAX + fn read_u64_varlong_size(&mut self) -> Result<(u64, usize), ProtocolError> { + let (val, size) = self.read_varlong_size()?; + if val < 0 { return Err(ProtocolError::VarIntError); } + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarLong as i8 with size in bytes (value, size) + fn read_i8_varlong_size(&mut self) -> Result<(i8, usize), ProtocolError> { + let (val, size) = self.read_varlong_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarLong as i16 with size in bytes (value, size) + fn read_i16_varlong_size(&mut self) -> Result<(i16, usize), ProtocolError> { + let (val, size) = self.read_varlong_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarLong as i32 with size in bytes (value, size) + fn read_i32_varlong_size(&mut self) -> Result<(i32, usize), ProtocolError> { + let (val, size) = self.read_varlong_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarLong as isize with size in bytes (value, size) + fn read_isize_varlong_size(&mut self) -> Result<(isize, usize), ProtocolError> { + let (val, size) = self.read_varlong_size()?; + Ok((TryInto::::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size)) + } + /// Read VarLong as i64 with size in bytes (value, size) + /// + /// *Use [read_varlong_size](DataReader::read_varlong_size) instead* + fn read_i64_varlong_size(&mut self) -> Result<(i64, usize), ProtocolError> { + self.read_varlong_size() + } + + /// Read VarInt as i32 with size in bytes (value, size) fn read_varint_size(&mut self) -> Result<(i32, usize), ProtocolError> { let mut value: u32 = 0; let mut position: u32 = 0; @@ -78,7 +272,7 @@ pub trait DataReader { loop { let byte = self.read_byte()?; - value |= ((byte & 0x7F) as u32) << position; + value |= TryInto::::try_into(byte & 0x7F).map_err(|_| ProtocolError::VarIntError)? << position; size += 1; @@ -91,7 +285,7 @@ pub trait DataReader { Ok((value as i32, size)) } - /// Read VarLong as i64 with size in bytes (varint, size) + /// Read VarLong as i64 with size in bytes (value, size) fn read_varlong_size(&mut self) -> Result<(i64, usize), ProtocolError> { let mut value: u64 = 0; let mut position: u32 = 0; @@ -99,7 +293,7 @@ pub trait DataReader { loop { let byte = self.read_byte()?; - value |= ((byte & 0x7F) as u64) << position; + value |= TryInto::::try_into(byte & 0x7F).map_err(|_| ProtocolError::VarIntError)? << position; size += 1; diff --git a/src/data/writer.rs b/src/data/writer.rs index a2ddbf0..0414a1f 100755 --- a/src/data/writer.rs +++ b/src/data/writer.rs @@ -13,9 +13,8 @@ pub trait DataWriter { } /// Write String fn write_string(&mut self, val: &str) -> Result<(), ProtocolError> { - let bytes = val.as_bytes(); - self.write_varint(bytes.len() as i32)?; - self.write_bytes(bytes) + self.write_usize_varint(val.len())?; + self.write_bytes(val.as_bytes()) } /// Write UUID fn write_uuid(&mut self, val: &Uuid) -> Result<(), ProtocolError> { @@ -54,17 +53,107 @@ pub trait DataWriter { self.write_bytes(&val.to_be_bytes()) } + /// Write VarInt as u8 + fn write_u8_varint(&mut self, val: u8) -> Result<(), ProtocolError> { + self.write_varint(val.try_into().map_err(|_| ProtocolError::VarIntError)?) + } + /// Write VarInt as u16 + fn write_u16_varint(&mut self, val: u16) -> Result<(), ProtocolError> { + self.write_varint(val.try_into().map_err(|_| ProtocolError::VarIntError)?) + } + /// Write VarInt as usize + /// + /// Returns error if the value is greater than i32::MAX + fn write_usize_varint(&mut self, val: usize) -> Result<(), ProtocolError> { + let val = val.try_into().map_err(|_| ProtocolError::VarIntError)?; + if val < 0 { return Err(ProtocolError::VarIntError); } + self.write_varint(val) + } + /// Write VarInt as u32 + /// + /// Returns error if the value is greater than i32::MAX + fn write_u32_varint(&mut self, val: u32) -> Result<(), ProtocolError> { + let val = val.try_into().map_err(|_| ProtocolError::VarIntError)?; + if val < 0 { return Err(ProtocolError::VarIntError); } + self.write_varint(val) + } + /// Write VarInt as i8 + fn write_i8_varint(&mut self, val: i8) -> Result<(), ProtocolError> { + self.write_varint(val.try_into().map_err(|_| ProtocolError::VarIntError)?) + } + /// Write VarInt as i16 + fn write_i16_varint(&mut self, val: i16) -> Result<(), ProtocolError> { + self.write_varint(val.try_into().map_err(|_| ProtocolError::VarIntError)?) + } + /// Write VarInt as isize + fn write_isize_varint(&mut self, val: isize) -> Result<(), ProtocolError> { + self.write_varint(val.try_into().map_err(|_| ProtocolError::VarIntError)?) + } + /// Write VarInt as i32 + /// + /// *Use [write_varint](DataWriter::write_varint) instead* + fn write_i32_varint(&mut self, val: i32) -> Result<(), ProtocolError> { + self.write_varint(val) + } + + /// Write VarLong as u8 + fn write_u8_varlong(&mut self, val: u8) -> Result<(), ProtocolError> { + self.write_varlong(val.try_into().map_err(|_| ProtocolError::VarIntError)?) + } + /// Write VarLong as u16 + fn write_u16_varlong(&mut self, val: u16) -> Result<(), ProtocolError> { + self.write_varlong(val.try_into().map_err(|_| ProtocolError::VarIntError)?) + } + /// Write VarLong as u32 + fn write_u32_varlong(&mut self, val: u32) -> Result<(), ProtocolError> { + self.write_varlong(val.try_into().map_err(|_| ProtocolError::VarIntError)?) + } + /// Write VarLong as u64 + /// + /// Returns error if the value is greater than i64::MAX + fn write_u64_varlong(&mut self, val: u64) -> Result<(), ProtocolError> { + let val = val.try_into().map_err(|_| ProtocolError::VarIntError)?; + if val < 0 { return Err(ProtocolError::VarIntError); } + self.write_varlong(val) + } + /// Write VarLong as usize + /// + /// Returns error if the value is greater than i64::MAX + fn write_usize_varlong(&mut self, val: u64) -> Result<(), ProtocolError> { + let val = val.try_into().map_err(|_| ProtocolError::VarIntError)?; + if val < 0 { return Err(ProtocolError::VarIntError); } + self.write_varlong(val) + } + /// Write VarLong as i8 + fn write_i8_varlong(&mut self, val: i8) -> Result<(), ProtocolError> { + self.write_varlong(val.try_into().map_err(|_| ProtocolError::VarIntError)?) + } + /// Write VarLong as i16 + fn write_i16_varlong(&mut self, val: i16) -> Result<(), ProtocolError> { + self.write_varlong(val.try_into().map_err(|_| ProtocolError::VarIntError)?) + } + /// Write VarLong as i32 + fn write_i32_varlong(&mut self, val: i32) -> Result<(), ProtocolError> { + self.write_varlong(val.try_into().map_err(|_| ProtocolError::VarIntError)?) + } + /// Write VarLong as i64 + /// + /// *Use [write_varlong](DataWriter::write_varlong) instead* + fn write_i64_varlong(&mut self, val: i64) -> Result<(), ProtocolError> { + self.write_varlong(val) + } + /// Write VarInt as i32 fn write_varint(&mut self, val: i32) -> Result<(), ProtocolError> { let mut value = val as u32; loop { if value & !0x7F == 0 { - self.write_byte(value as u8)?; + self.write_byte(TryInto::::try_into(value).map_err(|_| ProtocolError::VarIntError)?)?; break; } - self.write_byte(((value & 0x7F) | 0x80) as u8)?; + self.write_byte(TryInto::::try_into((value & 0x7F) | 0x80).map_err(|_| ProtocolError::VarIntError)?)?; value >>= 7; } @@ -77,11 +166,11 @@ pub trait DataWriter { loop { if value & !0x7F == 0 { - self.write_byte(value as u8)?; + self.write_byte(TryInto::::try_into(value).map_err(|_| ProtocolError::VarIntError)?)?; break; } - self.write_byte(((value & 0x7F) | 0x80) as u8)?; + self.write_byte(TryInto::::try_into((value & 0x7F) | 0x80).map_err(|_| ProtocolError::VarIntError)?)?; value >>= 7; } diff --git a/src/lib.rs b/src/lib.rs index 423e201..d2d8a5c 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -209,12 +209,12 @@ pub fn read_packet( ) -> Result { let mut data: Vec; - let packet_length = stream.read_varint_size()?; + let packet_length = stream.read_usize_varint_size()?; if compression.is_some() { - let data_length = stream.read_varint_size()?; + let data_length = stream.read_usize_varint_size()?; - data = stream.read_bytes(packet_length.0 as usize - data_length.1 as usize)?; + data = stream.read_bytes(packet_length.0 - data_length.1)?; if data_length.0 != 0 { data = decompress_zlib(&data)?; diff --git a/src/packet.rs b/src/packet.rs index b3d6c93..12ce34c 100755 --- a/src/packet.rs +++ b/src/packet.rs @@ -21,12 +21,12 @@ impl Packet { pub fn from_data(data: &[u8]) -> Result { let mut cursor = Cursor::new(data); - let (packet_id, packet_id_size) = cursor.read_varint_size()?; + let (packet_id, packet_id_size) = cursor.read_u8_varint_size()?; let packet_data = DataReader::read_bytes(&mut cursor, data.len() - packet_id_size as usize)?; Ok(Packet { - id: packet_id as u8, + id: packet_id, cursor: Cursor::new(packet_data), }) } diff --git a/src/tests.rs b/src/tests.rs index c12d297..3395166 100755 --- a/src/tests.rs +++ b/src/tests.rs @@ -27,17 +27,17 @@ fn test_varints() -> Result<(), ProtocolError> { let mut packet = Packet::empty(0x00); - packet.write_varint(0)?; - packet.write_varint(1)?; - packet.write_varint(2)?; - packet.write_varint(127)?; - packet.write_varint(128)?; - packet.write_varint(255)?; - packet.write_varint(25565)?; - packet.write_varint(2097151)?; - packet.write_varint(2147483647)?; - packet.write_varint(-1)?; - packet.write_varint(-2147483648)?; + packet.write_u8_varint(0)?; + packet.write_u8_varint(1)?; + packet.write_u8_varint(2)?; + packet.write_u8_varint(127)?; + packet.write_u8_varint(128)?; + packet.write_u8_varint(255)?; + packet.write_u16_varint(25565)?; + packet.write_u32_varint(2097151)?; + packet.write_u32_varint(2147483647)?; + packet.write_i8_varint(-1)?; + packet.write_i32_varint(-2147483648)?; packet.get_mut().set_position(0); @@ -55,17 +55,17 @@ fn test_varints() -> Result<(), ProtocolError> { packet.get_mut().set_position(0); - assert_eq!(packet.read_varint()?, 0); - assert_eq!(packet.read_varint()?, 1); - assert_eq!(packet.read_varint()?, 2); - assert_eq!(packet.read_varint()?, 127); - assert_eq!(packet.read_varint()?, 128); - assert_eq!(packet.read_varint()?, 255); - assert_eq!(packet.read_varint()?, 25565); - assert_eq!(packet.read_varint()?, 2097151); - assert_eq!(packet.read_varint()?, 2147483647); - assert_eq!(packet.read_varint()?, -1); - assert_eq!(packet.read_varint()?, -2147483648); + assert_eq!(packet.read_u8_varint()?, 0); + assert_eq!(packet.read_u8_varint()?, 1); + assert_eq!(packet.read_u8_varint()?, 2); + assert_eq!(packet.read_u8_varint()?, 127); + assert_eq!(packet.read_u8_varint()?, 128); + assert_eq!(packet.read_u8_varint()?, 255); + assert_eq!(packet.read_u16_varint()?, 25565); + assert_eq!(packet.read_u32_varint()?, 2097151); + assert_eq!(packet.read_u32_varint()?, 2147483647); + assert_eq!(packet.read_i32_varint()?, -1); + assert_eq!(packet.read_i32_varint()?, -2147483648); Ok(()) } @@ -91,20 +91,20 @@ fn test_varlongs() -> Result<(), ProtocolError> { | -9223372036854775808 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01 | */ - + let mut packet = Packet::empty(0x00); - packet.write_varlong(0)?; - packet.write_varlong(1)?; - packet.write_varlong(2)?; - packet.write_varlong(127)?; - packet.write_varlong(128)?; - packet.write_varlong(255)?; - packet.write_varlong(2147483647)?; - packet.write_varlong(9223372036854775807)?; - packet.write_varlong(-1)?; - packet.write_varlong(-2147483648)?; - packet.write_varlong(-9223372036854775808)?; + packet.write_u8_varlong(0)?; + packet.write_u8_varlong(1)?; + packet.write_u8_varlong(2)?; + packet.write_u8_varlong(127)?; + packet.write_u8_varlong(128)?; + packet.write_u8_varlong(255)?; + packet.write_u32_varlong(2147483647)?; + packet.write_u64_varlong(9223372036854775807)?; + packet.write_i8_varlong(-1)?; + packet.write_i32_varlong(-2147483648)?; + packet.write_i64_varlong(-9223372036854775808)?; packet.get_mut().set_position(0); @@ -122,17 +122,17 @@ fn test_varlongs() -> Result<(), ProtocolError> { packet.get_mut().set_position(0); - assert_eq!(packet.read_varlong()?, 0); - assert_eq!(packet.read_varlong()?, 1); - assert_eq!(packet.read_varlong()?, 2); - assert_eq!(packet.read_varlong()?, 127); - assert_eq!(packet.read_varlong()?, 128); - assert_eq!(packet.read_varlong()?, 255); - assert_eq!(packet.read_varlong()?, 2147483647); - assert_eq!(packet.read_varlong()?, 9223372036854775807); - assert_eq!(packet.read_varlong()?, -1); - assert_eq!(packet.read_varlong()?, -2147483648); - assert_eq!(packet.read_varlong()?, -9223372036854775808); + assert_eq!(packet.read_u8_varlong()?, 0); + assert_eq!(packet.read_u8_varlong()?, 1); + assert_eq!(packet.read_u8_varlong()?, 2); + assert_eq!(packet.read_u8_varlong()?, 127); + assert_eq!(packet.read_u8_varlong()?, 128); + assert_eq!(packet.read_u8_varlong()?, 255); + assert_eq!(packet.read_u32_varlong()?, 2147483647); + assert_eq!(packet.read_u64_varlong()?, 9223372036854775807); + assert_eq!(packet.read_i8_varlong()?, -1); + assert_eq!(packet.read_i32_varlong()?, -2147483648); + assert_eq!(packet.read_i64_varlong()?, -9223372036854775808); Ok(()) }