mcproto-codec 0.1.4-alpha.2

VarInt, encryption and compression coder & decoder for Minecraft protocols.
Documentation
use std::io::{Read, Write};
use crate::CodecError;

pub trait VarIntWrite: Write {
    #[inline]
    fn write_varint(&mut self, value: i32) -> Result<(), CodecError> {
        let mut value = value as u32;
        for i in 0..5 {
            let byte = (value & 0x7F) as u8;
            value >>= 7;
            let has_next = value != 0 && i < 4;
            let byte = if has_next { byte | 0x80 } else { byte };

            self.write_all(&[byte])?;

            if !has_next {
                return Ok(());
            }
        }
        Err(CodecError::VarIntOverflow)
    }
}

pub trait VarIntRead: Read {
    #[inline]
    fn read_varint(&mut self) -> Result<i32, CodecError> {
        let mut result = 0u32;
        let mut shift = 0;

        for _ in 0..5 {
            let mut buf = [0u8; 1];
            self.read_exact(&mut buf)?;
            let byte = buf[0];

            let value = (byte & 0x7F) as u32;
            result |= value << shift;

            if (byte & 0x80) == 0 {
                return Ok(result as i32);
            }

            shift += 7;
        }
        Err(CodecError::VarIntOverflow)
    }
}

impl<R: Read> VarIntRead for R {}
impl<W: Write> VarIntWrite for W {}