diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2026-01-13 10:51:45 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-13 10:51:45 -0600 |
| commit | b21ac946cafaacc9ee2478ea48ed9e72554f79ed (patch) | |
| tree | 4d05744b9801e94f5da6563d8fabddfb20d1c7b7 /azalea-buf/src/impls/primitives.rs | |
| parent | d5fa5e32b37754b3b5c136e58821e48cd3b7c2ff (diff) | |
| download | azalea-drasl-b21ac946cafaacc9ee2478ea48ed9e72554f79ed.tar.xz | |
Merge AzaleaRead and AzaleaWrite (#305)
Diffstat (limited to 'azalea-buf/src/impls/primitives.rs')
| -rw-r--r-- | azalea-buf/src/impls/primitives.rs | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/azalea-buf/src/impls/primitives.rs b/azalea-buf/src/impls/primitives.rs new file mode 100644 index 00000000..023086bb --- /dev/null +++ b/azalea-buf/src/impls/primitives.rs @@ -0,0 +1,213 @@ +use std::io::{self, Cursor, Read, Write}; + +use byteorder::{BE, ReadBytesExt, WriteBytesExt}; +use tracing::warn; + +use crate::{AzBuf, AzBufVar, BufReadError}; + +impl AzBuf for () { + fn azalea_read(_buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + Ok(()) + } + fn azalea_write(&self, _buf: &mut impl Write) -> io::Result<()> { + Ok(()) + } +} + +impl AzBuf for i32 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + Ok(buf.read_i32::<BE>()?) + } + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + buf.write_i32::<BE>(*self) + } +} + +impl AzBufVar for i32 { + /// Read a single varint from the reader and return the value + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + // fast varint impl based on https://github.com/luojia65/mc-varint/blob/master/src/lib.rs#L67 + let mut buffer = [0]; + let mut ans = 0; + for i in 0..5 { + buf.read_exact(&mut buffer)?; + ans |= ((buffer[0] & 0b0111_1111) as i32) << (7 * i); + if buffer[0] & 0b1000_0000 == 0 { + break; + } + } + Ok(ans) + } + + fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> { + let mut buffer = [0]; + let mut value = *self; + if value == 0 { + buf.write_all(&buffer)?; + } + while value != 0 { + buffer[0] = (value & 0b0111_1111) as u8; + value = (value >> 7) & (i32::MAX >> 6); + if value != 0 { + buffer[0] |= 0b1000_0000; + } + buf.write_all(&buffer)?; + } + Ok(()) + } +} + +impl AzBufVar for i64 { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + let mut buffer = [0]; + let mut ans = 0; + for i in 0..10 { + buf.read_exact(&mut buffer) + .map_err(|_| BufReadError::InvalidVarLong)?; + ans |= ((buffer[0] & 0b0111_1111) as i64) << (7 * i); + if buffer[0] & 0b1000_0000 == 0 { + break; + } + } + Ok(ans) + } + + fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> { + let mut buffer = [0]; + let mut value = *self; + if value == 0 { + buf.write_all(&buffer).unwrap(); + } + while value != 0 { + buffer[0] = (value & 0b0111_1111) as u8; + value = (value >> 7) & (i64::MAX >> 6); + if value != 0 { + buffer[0] |= 0b1000_0000; + } + buf.write_all(&buffer)?; + } + Ok(()) + } +} + +impl AzBufVar for u64 { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + i64::azalea_read_var(buf).map(|i| i as u64) + } + fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> { + i64::azalea_write_var(&(*self as i64), buf) + } +} + +impl AzBuf for u32 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + Ok(i32::azalea_read(buf)? as u32) + } + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + i32::azalea_write(&(*self as i32), buf) + } +} + +impl AzBufVar for u32 { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + Ok(i32::azalea_read_var(buf)? as u32) + } + fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> { + i32::azalea_write_var(&(*self as i32), buf) + } +} + +impl AzBuf for u16 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + i16::azalea_read(buf).map(|i| i as u16) + } + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + i16::azalea_write(&(*self as i16), buf) + } +} + +impl AzBuf for i16 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + Ok(buf.read_i16::<BE>()?) + } + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + buf.write_i16::<BE>(*self) + } +} + +impl AzBufVar for u16 { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + Ok(i32::azalea_read_var(buf)? as u16) + } + fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> { + i32::azalea_write_var(&(*self as i32), buf) + } +} + +impl AzBuf for i64 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + Ok(buf.read_i64::<BE>()?) + } + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + buf.write_i64::<BE>(*self) + } +} + +impl AzBuf for u64 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + i64::azalea_read(buf).map(|i| i as u64) + } + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + buf.write_u64::<BE>(*self) + } +} + +impl AzBuf for bool { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + let byte = u8::azalea_read(buf)?; + if byte > 1 { + warn!("Boolean value was not 0 or 1, but {byte}"); + } + Ok(byte != 0) + } + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + let byte = u8::from(*self); + byte.azalea_write(buf) + } +} + +impl AzBuf for u8 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + Ok(buf.read_u8()?) + } + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + buf.write_u8(*self) + } +} + +impl AzBuf for i8 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + u8::azalea_read(buf).map(|i| i as i8) + } + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + (*self as u8).azalea_write(buf) + } +} + +impl AzBuf for f32 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + Ok(buf.read_f32::<BE>()?) + } + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + buf.write_f32::<BE>(*self) + } +} + +impl AzBuf for f64 { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + Ok(buf.read_f64::<BE>()?) + } + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + buf.write_f64::<BE>(*self) + } +} |
