diff options
| author | mat <git@matdoes.dev> | 2025-09-20 20:35:16 -1200 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2025-09-20 20:35:16 -1200 |
| commit | 585b51e91a5335eae37bc5af7c0111bb2092b156 (patch) | |
| tree | c1559014df9db20dd625d9fe972d4e9f88317008 /azalea-buf/src | |
| parent | db793448ff8e656ad80859835edc3b89cb547dd2 (diff) | |
| download | azalea-drasl-585b51e91a5335eae37bc5af7c0111bb2092b156.tar.xz | |
more accurate mining and impl PartialEq for packets
Diffstat (limited to 'azalea-buf/src')
| -rw-r--r-- | azalea-buf/src/read.rs | 143 | ||||
| -rw-r--r-- | azalea-buf/src/write.rs | 47 |
2 files changed, 100 insertions, 90 deletions
diff --git a/azalea-buf/src/read.rs b/azalea-buf/src/read.rs index 143190b5..771b917c 100644 --- a/azalea-buf/src/read.rs +++ b/azalea-buf/src/read.rs @@ -7,6 +7,7 @@ use std::{ }; use byteorder::{BE, ReadBytesExt}; +use indexmap::IndexMap; use thiserror::Error; use tracing::warn; @@ -188,67 +189,85 @@ impl AzaleaRead for UnsizedByteArray { } } -impl<T: AzaleaRead> AzaleaRead for Vec<T> { - default fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { - let length = u32::azalea_read_var(buf)? as usize; - // we limit the capacity to not get exploited into allocating a bunch - let mut contents = Vec::with_capacity(usize::min(length, 65536)); - for _ in 0..length { - contents.push(T::azalea_read(buf)?); +macro_rules! impl_for_map_type { + ($ty: ident) => { + impl<K: AzaleaRead + Send + Eq + Hash, V: AzaleaRead + Send> AzaleaRead for $ty<K, V> { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + let length = i32::azalea_read_var(buf)? as usize; + let mut contents = Self::with_capacity(usize::min(length, 65536)); + for _ in 0..length { + contents.insert(K::azalea_read(buf)?, V::azalea_read(buf)?); + } + Ok(contents) + } } - Ok(contents) - } -} -impl<T: AzaleaRead> AzaleaRead for Box<[T]> { - default fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { - Vec::<T>::azalea_read(buf).map(Vec::into_boxed_slice) - } -} -impl<T: AzaleaRead> AzaleaReadLimited for Vec<T> { - fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result<Self, BufReadError> { - let length = u32::azalea_read_var(buf)? as usize; - if length > limit { - return Err(BufReadError::VecLengthTooLong { - length: length as u32, - max_length: limit as u32, - }); + impl<K: AzaleaRead + Send + Eq + Hash, V: AzaleaReadVar + Send> AzaleaReadVar + for $ty<K, V> + { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + let length = i32::azalea_read_var(buf)? as usize; + let mut contents = Self::with_capacity(usize::min(length, 65536)); + for _ in 0..length { + contents.insert(K::azalea_read(buf)?, V::azalea_read_var(buf)?); + } + Ok(contents) + } } - - let mut contents = Vec::with_capacity(usize::min(length, 65536)); - for _ in 0..length { - contents.push(T::azalea_read(buf)?); + }; +} + +impl_for_map_type!(HashMap); +impl_for_map_type!(IndexMap); + +macro_rules! impl_for_list_type { + ($ty: ty) => { + impl<T: AzaleaRead> AzaleaRead for $ty { + default fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + let length = u32::azalea_read_var(buf)? as usize; + // we limit the capacity to not get exploited into allocating a bunch + let mut contents = Vec::with_capacity(usize::min(length, 65536)); + for _ in 0..length { + contents.push(T::azalea_read(buf)?); + } + Ok(contents.into()) + } } - Ok(contents) - } -} -impl<T: AzaleaRead> AzaleaReadLimited for Box<[T]> { - fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result<Self, BufReadError> { - Vec::<T>::azalea_read_limited(buf, limit).map(Vec::into_boxed_slice) - } -} - -impl<K: AzaleaRead + Send + Eq + Hash, V: AzaleaRead + Send> AzaleaRead for HashMap<K, V> { - fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { - let length = i32::azalea_read_var(buf)? as usize; - let mut contents = HashMap::with_capacity(usize::min(length, 65536)); - for _ in 0..length { - contents.insert(K::azalea_read(buf)?, V::azalea_read(buf)?); + impl<T: AzaleaReadVar> AzaleaReadVar for $ty { + fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + let length = i32::azalea_read_var(buf)? as usize; + let mut contents = Vec::with_capacity(usize::min(length, 65536)); + for _ in 0..length { + contents.push(T::azalea_read_var(buf)?); + } + Ok(contents.into()) + } } - Ok(contents) - } -} - -impl<K: AzaleaRead + Send + Eq + Hash, V: AzaleaReadVar + Send> AzaleaReadVar for HashMap<K, V> { - fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { - let length = i32::azalea_read_var(buf)? as usize; - let mut contents = HashMap::with_capacity(usize::min(length, 65536)); - for _ in 0..length { - contents.insert(K::azalea_read(buf)?, V::azalea_read_var(buf)?); + impl<T: AzaleaRead> AzaleaReadLimited for $ty { + fn azalea_read_limited( + buf: &mut Cursor<&[u8]>, + limit: usize, + ) -> Result<Self, BufReadError> { + let length = u32::azalea_read_var(buf)? as usize; + if length > limit { + return Err(BufReadError::VecLengthTooLong { + length: length as u32, + max_length: limit as u32, + }); + } + + let mut contents = Vec::with_capacity(usize::min(length, 65536)); + for _ in 0..length { + contents.push(T::azalea_read(buf)?); + } + Ok(contents.into()) + } } - Ok(contents) - } + }; } +impl_for_list_type!(Vec<T>); +impl_for_list_type!(Box<[T]>); + impl AzaleaRead for Vec<u8> { fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { let length = i32::azalea_read_var(buf)? as usize; @@ -297,22 +316,6 @@ impl AzaleaReadVar for u16 { } } -impl<T: AzaleaReadVar> AzaleaReadVar for Vec<T> { - fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { - let length = i32::azalea_read_var(buf)? as usize; - let mut contents = Vec::with_capacity(usize::min(length, 65536)); - for _ in 0..length { - contents.push(T::azalea_read_var(buf)?); - } - Ok(contents) - } -} -impl<T: AzaleaReadVar> AzaleaReadVar for Box<[T]> { - fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { - Vec::<T>::azalea_read_var(buf).map(Vec::into_boxed_slice) - } -} - impl AzaleaRead for i64 { fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { Ok(buf.read_i64::<BE>()?) diff --git a/azalea-buf/src/write.rs b/azalea-buf/src/write.rs index a925647d..7b9ad496 100644 --- a/azalea-buf/src/write.rs +++ b/azalea-buf/src/write.rs @@ -5,6 +5,7 @@ use std::{ }; use byteorder::{BigEndian, WriteBytesExt}; +use indexmap::IndexMap; use super::{MAX_STRING_LENGTH, UnsizedByteArray}; @@ -80,30 +81,36 @@ impl<T: AzaleaWrite> AzaleaWrite for [T] { } } -impl<K: AzaleaWrite, V: AzaleaWrite> AzaleaWrite for HashMap<K, V> { - fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { - u32::azalea_write_var(&(self.len() as u32), buf)?; - for (key, value) in self { - key.azalea_write(buf)?; - value.azalea_write(buf)?; - } - - Ok(()) - } -} +macro_rules! impl_for_map_type { + ($ty: ident) => { + impl<K: AzaleaWrite, V: AzaleaWrite> AzaleaWrite for $ty<K, V> { + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + u32::azalea_write_var(&(self.len() as u32), buf)?; + for (key, value) in self { + key.azalea_write(buf)?; + value.azalea_write(buf)?; + } -impl<K: AzaleaWrite, V: AzaleaWriteVar> AzaleaWriteVar for HashMap<K, V> { - fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> { - u32::azalea_write_var(&(self.len() as u32), buf)?; - for (key, value) in self { - key.azalea_write(buf)?; - value.azalea_write_var(buf)?; + Ok(()) + } } - - Ok(()) - } + impl<K: AzaleaWrite, V: AzaleaWriteVar> AzaleaWriteVar for $ty<K, V> { + fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> { + u32::azalea_write_var(&(self.len() as u32), buf)?; + for (key, value) in self { + key.azalea_write(buf)?; + value.azalea_write_var(buf)?; + } + + Ok(()) + } + } + }; } +impl_for_map_type!(HashMap); +impl_for_map_type!(IndexMap); + impl AzaleaWrite for Vec<u8> { fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { (self.len() as u32).azalea_write_var(buf)?; |
