use crate::error::{Result, LateJavaCoreError};
use std::io::{Read, Write};
pub struct Buffer {
data: Vec<u8>,
position: usize,
}
impl Buffer {
pub fn new() -> Self {
Self {
data: Vec::new(),
position: 0,
}
}
pub fn from_data(data: Vec<u8>) -> Self {
Self {
data,
position: 0,
}
}
pub fn read_byte(&mut self) -> Result<u8> {
if self.position >= self.data.len() {
return Err(LateJavaCoreError::Minecraft("Buffer underflow".to_string()));
}
let byte = self.data[self.position];
self.position += 1;
Ok(byte)
}
pub fn read_bytes(&mut self, count: usize) -> Result<Vec<u8>> {
if self.position + count > self.data.len() {
return Err(LateJavaCoreError::Minecraft("Buffer underflow".to_string()));
}
let bytes = self.data[self.position..self.position + count].to_vec();
self.position += count;
Ok(bytes)
}
pub fn read_short(&mut self) -> Result<i16> {
let bytes = self.read_bytes(2)?;
Ok(i16::from_be_bytes([bytes[0], bytes[1]]))
}
pub fn read_int(&mut self) -> Result<i32> {
let bytes = self.read_bytes(4)?;
Ok(i32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
}
pub fn read_long(&mut self) -> Result<i64> {
let bytes = self.read_bytes(8)?;
Ok(i64::from_be_bytes([
bytes[0], bytes[1], bytes[2], bytes[3],
bytes[4], bytes[5], bytes[6], bytes[7]
]))
}
pub fn read_string(&mut self) -> Result<String> {
let length = self.read_varint()? as usize;
let bytes = self.read_bytes(length)?;
String::from_utf8(bytes)
.map_err(|_| LateJavaCoreError::Minecraft("Invalid UTF-8 string".to_string()))
}
pub fn read_varint(&mut self) -> Result<i32> {
let mut value = 0i32;
let mut position = 0;
loop {
let byte = self.read_byte()?;
value |= ((byte & 0x7F) as i32) << position;
if (byte & 0x80) == 0 {
break;
}
position += 7;
if position >= 32 {
return Err(LateJavaCoreError::Minecraft("VarInt too long".to_string()));
}
}
Ok(value)
}
pub fn write_byte(&mut self, byte: u8) {
self.data.push(byte);
}
pub fn write_bytes(&mut self, bytes: &[u8]) {
self.data.extend_from_slice(bytes);
}
pub fn write_short(&mut self, value: i16) {
self.write_bytes(&value.to_be_bytes());
}
pub fn write_int(&mut self, value: i32) {
self.write_bytes(&value.to_be_bytes());
}
pub fn write_long(&mut self, value: i64) {
self.write_bytes(&value.to_be_bytes());
}
pub fn write_string(&mut self, value: &str) -> Result<()> {
let bytes = value.as_bytes();
self.write_varint(bytes.len() as i32)?;
self.write_bytes(bytes);
Ok(())
}
pub fn write_varint(&mut self, mut value: i32) -> Result<()> {
loop {
let mut byte = (value & 0x7F) as u8;
value >>= 7;
if value != 0 {
byte |= 0x80;
}
self.write_byte(byte);
if value == 0 {
break;
}
}
Ok(())
}
pub fn data(&self) -> &[u8] {
&self.data
}
pub fn position(&self) -> usize {
self.position
}
pub fn set_position(&mut self, position: usize) {
self.position = position;
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn clear(&mut self) {
self.data.clear();
self.position = 0;
}
}
impl Default for Buffer {
fn default() -> Self {
Self::new()
}
}