rewrite varints + varlongs
This commit is contained in:
parent
f8196d036c
commit
4b7af49ad0
10 changed files with 294 additions and 327 deletions
|
@ -1,7 +1,6 @@
|
|||
//! `DataReader` and `DataWriter` traits for reading and writing primitive types in the Minecraft protocol
|
||||
|
||||
pub mod reader;
|
||||
pub mod varint;
|
||||
pub mod writer;
|
||||
|
||||
pub use reader::*;
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
use crate::{
|
||||
data::varint::read_varint,
|
||||
ProtocolError,
|
||||
};
|
||||
use crate::ProtocolError;
|
||||
use std::io::Read;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -16,12 +13,16 @@ pub trait DataReader {
|
|||
}
|
||||
/// Read String
|
||||
fn read_string(&mut self) -> Result<String, ProtocolError> {
|
||||
let size = self.read_usize_varint()?;
|
||||
let size = self.read_varint()? as usize;
|
||||
match String::from_utf8(self.read_bytes(size)?) {
|
||||
Ok(i) => Ok(i),
|
||||
Err(_) => Err(ProtocolError::StringParseError),
|
||||
}
|
||||
}
|
||||
/// Read Signed byte as i8
|
||||
fn read_signed_byte(&mut self) -> Result<i8, ProtocolError> {
|
||||
Ok(self.read_byte()? as i8)
|
||||
}
|
||||
/// Read Unsigned Short as u16
|
||||
fn read_unsigned_short(&mut self) -> Result<u16, ProtocolError> {
|
||||
self.read_bytes(2)
|
||||
|
@ -69,104 +70,56 @@ pub trait DataReader {
|
|||
.map(|o| Uuid::from_bytes(o))
|
||||
}
|
||||
|
||||
/// Read VarInt as usize with size in bytes (varint, size)
|
||||
fn read_usize_varint_size(&mut self) -> Result<(usize, usize), ProtocolError> {
|
||||
read_varint!(usize, self)
|
||||
/// Read VarInt as i32 with size in bytes (varint, size)
|
||||
fn read_varint_size(&mut self) -> Result<(i32, usize), ProtocolError> {
|
||||
let mut value: u32 = 0;
|
||||
let mut position: u32 = 0;
|
||||
let mut size = 0;
|
||||
|
||||
loop {
|
||||
let byte = self.read_byte()?;
|
||||
value |= ((byte & 0x7F) as u32) << position;
|
||||
|
||||
size += 1;
|
||||
|
||||
if (byte & 0x80) == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
position += 7;
|
||||
}
|
||||
|
||||
Ok((value as i32, size))
|
||||
}
|
||||
/// Read VarInt as u8 with size in bytes (varint, size)
|
||||
fn read_u8_varint_size(&mut self) -> Result<(u8, usize), ProtocolError> {
|
||||
read_varint!(u8, self)
|
||||
}
|
||||
/// Read VarInt as u16 with size in bytes (varint, size)
|
||||
fn read_u16_varint_size(&mut self) -> Result<(u16, usize), ProtocolError> {
|
||||
read_varint!(u16, self)
|
||||
}
|
||||
/// Read VarInt as u32 with size in bytes (varint, size)
|
||||
fn read_u32_varint_size(&mut self) -> Result<(u32, usize), ProtocolError> {
|
||||
read_varint!(u32, self)
|
||||
}
|
||||
/// Read VarInt as u64 with size in bytes (varint, size)
|
||||
fn read_u64_varint_size(&mut self) -> Result<(u64, usize), ProtocolError> {
|
||||
read_varint!(u64, self)
|
||||
}
|
||||
/// Read VarInt as u128 with size in bytes (varint, size)
|
||||
fn read_u128_varint_size(&mut self) -> Result<(u128, usize), ProtocolError> {
|
||||
read_varint!(u128, self)
|
||||
/// Read VarLong as i64 with size in bytes (varint, size)
|
||||
fn read_varlong_size(&mut self) -> Result<(i64, usize), ProtocolError> {
|
||||
let mut value: u64 = 0;
|
||||
let mut position: u32 = 0;
|
||||
let mut size = 0;
|
||||
|
||||
loop {
|
||||
let byte = self.read_byte()?;
|
||||
value |= ((byte & 0x7F) as u64) << position;
|
||||
|
||||
size += 1;
|
||||
|
||||
if (byte & 0x80) == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
position += 7;
|
||||
}
|
||||
|
||||
Ok((value as i64, size))
|
||||
}
|
||||
|
||||
/// Read VarInt as usize
|
||||
fn read_usize_varint(&mut self) -> Result<usize, ProtocolError> {
|
||||
self.read_usize_varint_size().map(|o| o.0)
|
||||
/// Read VarInt as i32
|
||||
fn read_varint(&mut self) -> Result<i32, ProtocolError> {
|
||||
self.read_varint_size().map(|o| o.0)
|
||||
}
|
||||
/// Read VarInt as u8
|
||||
fn read_u8_varint(&mut self) -> Result<u8, ProtocolError> {
|
||||
self.read_u8_varint_size().map(|o| o.0)
|
||||
}
|
||||
/// Read VarInt as u16
|
||||
fn read_u16_varint(&mut self) -> Result<u16, ProtocolError> {
|
||||
self.read_u16_varint_size().map(|o| o.0)
|
||||
}
|
||||
/// Read VarInt as u32
|
||||
fn read_u32_varint(&mut self) -> Result<u32, ProtocolError> {
|
||||
self.read_u32_varint_size().map(|o| o.0)
|
||||
}
|
||||
/// Read VarInt as u64
|
||||
fn read_u64_varint(&mut self) -> Result<u64, ProtocolError> {
|
||||
self.read_u64_varint_size().map(|o| o.0)
|
||||
}
|
||||
/// Read VarInt as u128
|
||||
fn read_u128_varint(&mut self) -> Result<u128, ProtocolError> {
|
||||
self.read_u128_varint_size().map(|o| o.0)
|
||||
}
|
||||
|
||||
/// Read VarInt as usize with zigzag
|
||||
fn read_isize_varint(&mut self) -> Result<isize, ProtocolError> {
|
||||
self.read_usize_varint().map(|o| o as isize)
|
||||
}
|
||||
/// Read VarInt as u8 with zigzag
|
||||
fn read_i8_varint(&mut self) -> Result<i8, ProtocolError> {
|
||||
self.read_u8_varint().map(|o| o as i8)
|
||||
}
|
||||
/// Read VarInt as u16 with zigzag
|
||||
fn read_i16_varint(&mut self) -> Result<i16, ProtocolError> {
|
||||
self.read_u16_varint().map(|o| o as i16)
|
||||
}
|
||||
/// Read VarInt as u32 with zigzag
|
||||
fn read_i32_varint(&mut self) -> Result<i32, ProtocolError> {
|
||||
self.read_u32_varint().map(|o| o as i32)
|
||||
}
|
||||
/// Read VarInt as u64 with zigzag
|
||||
fn read_i64_varint(&mut self) -> Result<i64, ProtocolError> {
|
||||
self.read_u64_varint().map(|o| o as i64)
|
||||
}
|
||||
/// Read VarInt as u128 with zigzag
|
||||
fn read_i128_varint(&mut self) -> Result<i128, ProtocolError> {
|
||||
self.read_u128_varint().map(|o| o as i128)
|
||||
}
|
||||
|
||||
/// Read VarInt as usize with zigzag with size in bytes (varint, size)
|
||||
fn read_isize_varint_size(&mut self) -> Result<(isize, usize), ProtocolError> {
|
||||
self.read_usize_varint_size().map(|o| (o.0 as isize, o.1))
|
||||
}
|
||||
/// Read VarInt as u8 with zigzag with size in bytes (varint, size)
|
||||
fn read_i8_varint_size(&mut self) -> Result<(i8, usize), ProtocolError> {
|
||||
self.read_u8_varint_size().map(|o| (o.0 as i8, o.1))
|
||||
}
|
||||
/// Read VarInt as u16 with zigzag with size in bytes (varint, size)
|
||||
fn read_i16_varint_size(&mut self) -> Result<(i16, usize), ProtocolError> {
|
||||
self.read_u16_varint_size().map(|o| (o.0 as i16, o.1))
|
||||
}
|
||||
/// Read VarInt as u32 with zigzag with size in bytes (varint, size)
|
||||
fn read_i32_varint_size(&mut self) -> Result<(i32, usize), ProtocolError> {
|
||||
self.read_u32_varint_size().map(|o| (o.0 as i32, o.1))
|
||||
}
|
||||
/// Read VarInt as u64 with zigzag with size in bytes (varint, size)
|
||||
fn read_i64_varint_size(&mut self) -> Result<(i64, usize), ProtocolError> {
|
||||
self.read_u64_varint_size().map(|o| (o.0 as i64, o.1))
|
||||
}
|
||||
/// Read VarInt as u128 with zigzag with size in bytes (varint, size)
|
||||
fn read_i128_varint_size(&mut self) -> Result<(i128, usize), ProtocolError> {
|
||||
self.read_u128_varint_size().map(|o| (o.0 as i128, o.1))
|
||||
/// Read VarLong as i64
|
||||
fn read_varlong(&mut self) -> Result<i64, ProtocolError> {
|
||||
self.read_varlong_size().map(|o| o.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
macro_rules! read_varint {
|
||||
($type:ty, $self:expr) => {{
|
||||
let mut shift: $type = 0;
|
||||
let mut decoded: $type = 0;
|
||||
let mut size: usize = 0;
|
||||
|
||||
loop {
|
||||
let next = DataReader::read_byte($self)?;
|
||||
size += 1;
|
||||
|
||||
if shift >= (std::mem::size_of::<$type>() * 8) as $type {
|
||||
return Err(ProtocolError::VarIntError);
|
||||
}
|
||||
|
||||
decoded |= ((next & 0x7F) as $type) << shift;
|
||||
|
||||
if next & 0x80 == 0x80 {
|
||||
shift += 7;
|
||||
} else {
|
||||
return Ok((decoded, size));
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! write_varint {
|
||||
($type:ty, $self:expr, $value:expr) => {{
|
||||
let mut value: $type = $value;
|
||||
|
||||
if value == 0 {
|
||||
DataWriter::write_byte($self, 0)
|
||||
} else {
|
||||
while value >= 0x80 {
|
||||
DataWriter::write_byte($self, ((value & 0x7F) as u8) | 0x80)?;
|
||||
value >>= 7;
|
||||
}
|
||||
|
||||
DataWriter::write_byte($self, (value & 0x7F) as u8)
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
pub(crate) use read_varint;
|
||||
pub(crate) use write_varint;
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{data::varint::write_varint, ProtocolError};
|
||||
use crate::ProtocolError;
|
||||
use std::io::Write;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -14,13 +14,17 @@ pub trait DataWriter {
|
|||
/// Write String
|
||||
fn write_string(&mut self, val: &str) -> Result<(), ProtocolError> {
|
||||
let bytes = val.as_bytes();
|
||||
self.write_usize_varint(bytes.len())?;
|
||||
self.write_varint(bytes.len() as i32)?;
|
||||
self.write_bytes(bytes)
|
||||
}
|
||||
/// Write UUID
|
||||
fn write_uuid(&mut self, val: &Uuid) -> Result<(), ProtocolError> {
|
||||
self.write_bytes(val.as_bytes())
|
||||
}
|
||||
/// Write Signed byte as i8
|
||||
fn write_signed_byte(&mut self, val: i8) -> Result<(), ProtocolError> {
|
||||
self.write_byte(val as u8)
|
||||
}
|
||||
/// Write Unsigned Short as u16
|
||||
fn write_unsigned_short(&mut self, val: u16) -> Result<(), ProtocolError> {
|
||||
self.write_bytes(&val.to_be_bytes())
|
||||
|
@ -50,62 +54,44 @@ pub trait DataWriter {
|
|||
self.write_bytes(&val.to_be_bytes())
|
||||
}
|
||||
|
||||
/// Write VarInt as usize
|
||||
fn write_usize_varint(&mut self, val: usize) -> Result<(), ProtocolError> {
|
||||
write_varint!(usize, self, val)
|
||||
}
|
||||
/// Write VarInt as u8
|
||||
fn write_u8_varint(&mut self, val: u8) -> Result<(), ProtocolError> {
|
||||
write_varint!(u8, self, val)
|
||||
}
|
||||
/// Write VarInt as u16
|
||||
fn write_u16_varint(&mut self, val: u16) -> Result<(), ProtocolError> {
|
||||
write_varint!(u16, self, val)
|
||||
}
|
||||
/// Write VarInt as u32
|
||||
fn write_u32_varint(&mut self, val: u32) -> Result<(), ProtocolError> {
|
||||
write_varint!(u32, self, val)
|
||||
}
|
||||
/// Write VarInt as u64
|
||||
fn write_u64_varint(&mut self, val: u64) -> Result<(), ProtocolError> {
|
||||
write_varint!(u64, self, val)
|
||||
}
|
||||
/// Write VarInt as u128
|
||||
fn write_u128_varint(&mut self, val: u128) -> Result<(), ProtocolError> {
|
||||
write_varint!(u128, self, val)
|
||||
}
|
||||
|
||||
/// Write VarInt as isize
|
||||
fn write_isize_varint(&mut self, val: isize) -> Result<(), ProtocolError> {
|
||||
self.write_usize_varint(val as usize)
|
||||
}
|
||||
/// Write VarInt as i8
|
||||
fn write_i8_varint(&mut self, val: i8) -> Result<(), ProtocolError> {
|
||||
self.write_u8_varint(val as u8)
|
||||
}
|
||||
/// Write VarInt as i16
|
||||
fn write_i16_varint(&mut self, val: i16) -> Result<(), ProtocolError> {
|
||||
self.write_u16_varint(val as u16)
|
||||
}
|
||||
/// Write VarInt as i32
|
||||
fn write_i32_varint(&mut self, val: i32) -> Result<(), ProtocolError> {
|
||||
self.write_u32_varint(val as u32)
|
||||
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)?;
|
||||
break;
|
||||
}
|
||||
|
||||
self.write_byte(((value & 0x7F) | 0x80) as u8)?;
|
||||
|
||||
value >>= 7;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
/// Write VarInt as i64
|
||||
fn write_i64_varint(&mut self, val: i64) -> Result<(), ProtocolError> {
|
||||
self.write_u64_varint(val as u64)
|
||||
}
|
||||
/// Write VarInt as i128
|
||||
fn write_i128_varint(&mut self, val: i128) -> Result<(), ProtocolError> {
|
||||
self.write_u128_varint(val as u128)
|
||||
/// Write VarLong as i64
|
||||
fn write_varlong(&mut self, val: i64) -> Result<(), ProtocolError> {
|
||||
let mut value = val as u64;
|
||||
|
||||
loop {
|
||||
if value & !0x7F == 0 {
|
||||
self.write_byte(value as u8)?;
|
||||
break;
|
||||
}
|
||||
|
||||
self.write_byte(((value & 0x7F) | 0x80) as u8)?;
|
||||
|
||||
value >>= 7;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Write> DataWriter for W {
|
||||
fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ProtocolError> {
|
||||
match self.write_all(bytes) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(_) => Err(ProtocolError::WriteError),
|
||||
}
|
||||
self.write_all(bytes).map_err(|_| ProtocolError::WriteError)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue