aboutsummaryrefslogtreecommitdiff
path: root/azalea-protocol/src/mc_buf
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-04-26 15:33:41 +0000
committermat <github@matdoes.dev>2022-04-26 15:33:41 +0000
commite5fcfa119309877ab515b921f8ada5f1b1ec4c30 (patch)
treec5084a2f7840979feaf7483e7b598cbc888c509f /azalea-protocol/src/mc_buf
parentf9528a9f9a9e73b1d657af7c78d743067307d843 (diff)
downloadazalea-drasl-e5fcfa119309877ab515b921f8ada5f1b1ec4c30.tar.xz
default implementation for read and write Vec<T>
Diffstat (limited to 'azalea-protocol/src/mc_buf')
-rwxr-xr-xazalea-protocol/src/mc_buf/mod.rs11
-rwxr-xr-xazalea-protocol/src/mc_buf/read.rs38
-rwxr-xr-xazalea-protocol/src/mc_buf/write.rs20
3 files changed, 24 insertions, 45 deletions
diff --git a/azalea-protocol/src/mc_buf/mod.rs b/azalea-protocol/src/mc_buf/mod.rs
index 3ba6ac3e..3ab6e761 100755
--- a/azalea-protocol/src/mc_buf/mod.rs
+++ b/azalea-protocol/src/mc_buf/mod.rs
@@ -4,18 +4,18 @@ mod read;
mod write;
pub use read::{McBufReadable, McBufVarintReadable, Readable};
-pub use write::{McBufVarintWritable, McBufWritable, Writable};
use std::ops::Deref;
+pub use write::{McBufVarintWritable, McBufWritable, Writable};
// const DEFAULT_NBT_QUOTA: u32 = 2097152;
const MAX_STRING_LENGTH: u16 = 32767;
// const MAX_COMPONENT_STRING_LENGTH: u32 = 262144;
-
+/// A Vec<u8> that isn't prefixed by a VarInt with the size.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ByteArray(Vec<u8>);
+pub struct UnsizedByteArray(Vec<u8>);
-impl Deref for ByteArray {
+impl Deref for UnsizedByteArray {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
@@ -23,13 +23,12 @@ impl Deref for ByteArray {
}
}
-impl From<Vec<u8>> for ByteArray {
+impl From<Vec<u8>> for UnsizedByteArray {
fn from(vec: Vec<u8>) -> Self {
Self(vec)
}
}
-
#[cfg(test)]
mod tests {
use super::*;
diff --git a/azalea-protocol/src/mc_buf/read.rs b/azalea-protocol/src/mc_buf/read.rs
index 1e7db1dd..4c126b7e 100755
--- a/azalea-protocol/src/mc_buf/read.rs
+++ b/azalea-protocol/src/mc_buf/read.rs
@@ -1,4 +1,3 @@
-use crate::mc_buf::ByteArray;
use async_trait::async_trait;
use azalea_chat::component::Component;
use azalea_core::{
@@ -8,7 +7,7 @@ use azalea_core::{
use serde::Deserialize;
use tokio::io::{AsyncRead, AsyncReadExt};
-use super::MAX_STRING_LENGTH;
+use super::{UnsizedByteArray, MAX_STRING_LENGTH};
#[async_trait]
pub trait Readable {
@@ -16,7 +15,7 @@ pub trait Readable {
async fn read_varint(&mut self) -> Result<i32, String>;
fn get_varint_size(&mut self, value: i32) -> u8;
fn get_varlong_size(&mut self, value: i32) -> u8;
- async fn read_byte_array(&mut self) -> Result<ByteArray, String>;
+ async fn read_byte_array(&mut self) -> Result<Vec<u8>, String>;
async fn read_bytes_with_len(&mut self, n: usize) -> Result<Vec<u8>, String>;
async fn read_bytes(&mut self) -> Result<Vec<u8>, String>;
async fn read_utf(&mut self) -> Result<String, String>;
@@ -82,9 +81,9 @@ where
10
}
- async fn read_byte_array(&mut self) -> Result<ByteArray, String> {
+ async fn read_byte_array(&mut self) -> Result<Vec<u8>, String> {
let length = self.read_varint().await? as usize;
- Ok(ByteArray(self.read_bytes_with_len(length).await?))
+ self.read_bytes_with_len(length).await
}
async fn read_bytes_with_len(&mut self, n: usize) -> Result<Vec<u8>, String> {
@@ -244,22 +243,27 @@ impl McBufVarintReadable for i32 {
}
#[async_trait]
-impl McBufReadable for Vec<u8> {
+impl McBufReadable for UnsizedByteArray {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
- buf.read_bytes().await
+ Ok(UnsizedByteArray(buf.read_bytes().await?))
}
}
#[async_trait]
-impl McBufReadable for ByteArray {
+impl<T: McBufReadable + Send> McBufReadable for Vec<T> {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
- buf.read_byte_array().await
+ let length = buf.read_varint().await? as usize;
+ let mut contents = Vec::with_capacity(length);
+ for _ in 0..length {
+ contents.push(T::read_into(buf).await?);
+ }
+ Ok(contents)
}
}
@@ -417,22 +421,6 @@ impl McBufReadable for Option<GameType> {
}
}
-// Vec<ResourceLocation>
-#[async_trait]
-impl McBufReadable for Vec<ResourceLocation> {
- async fn read_into<R>(buf: &mut R) -> Result<Self, String>
- where
- R: AsyncRead + std::marker::Unpin + std::marker::Send,
- {
- let mut vec = Vec::new();
- let length = buf.read_varint().await?;
- for _ in 0..length {
- vec.push(buf.read_resource_location().await?);
- }
- Ok(vec)
- }
-}
-
// azalea_nbt::Tag
#[async_trait]
impl McBufReadable for azalea_nbt::Tag {
diff --git a/azalea-protocol/src/mc_buf/write.rs b/azalea-protocol/src/mc_buf/write.rs
index f1362402..e8845f25 100755
--- a/azalea-protocol/src/mc_buf/write.rs
+++ b/azalea-protocol/src/mc_buf/write.rs
@@ -1,5 +1,4 @@
-use super::MAX_STRING_LENGTH;
-use crate::mc_buf::ByteArray;
+use super::{UnsizedByteArray, MAX_STRING_LENGTH};
use async_trait::async_trait;
use azalea_chat::component::Component;
use azalea_core::{
@@ -187,15 +186,17 @@ impl McBufVarintWritable for i32 {
}
}
-impl McBufWritable for Vec<u8> {
+impl McBufWritable for UnsizedByteArray {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
buf.write_bytes(self)
}
}
-impl McBufWritable for ByteArray {
+// TODO: use specialization when that gets stabilized into rust
+// to optimize for Vec<u8> byte arrays
+impl<T: McBufWritable> McBufWritable for Vec<T> {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
- buf.write_byte_array(&self)
+ buf.write_list(self, |buf, i| T::write_into(i, buf))
}
}
@@ -304,15 +305,6 @@ impl McBufWritable for Option<GameType> {
}
}
-// Vec<ResourceLocation>
-impl McBufWritable for Vec<ResourceLocation> {
- fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
- buf.write_list(self, |buf, resource_location| {
- buf.write_resource_location(resource_location)
- })
- }
-}
-
// azalea_nbt::Tag
impl McBufWritable for azalea_nbt::Tag {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {