diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2022-09-02 12:11:14 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-02 12:11:14 -0500 |
| commit | cfb190d00c70f1b09789e23f89a3c67840e0fd87 (patch) | |
| tree | 9bdc021943753d60bf437526c4c294275eae13ac /azalea-buf/src/read.rs | |
| parent | 32458d743f757da3193717fe5554f490703640c0 (diff) | |
| download | azalea-drasl-cfb190d00c70f1b09789e23f89a3c67840e0fd87.tar.xz | |
get rid of Readable & Writable (#21)
Diffstat (limited to 'azalea-buf/src/read.rs')
| -rw-r--r-- | azalea-buf/src/read.rs | 235 |
1 files changed, 60 insertions, 175 deletions
diff --git a/azalea-buf/src/read.rs b/azalea-buf/src/read.rs index a7ebc10c..82fd4f2f 100644 --- a/azalea-buf/src/read.rs +++ b/azalea-buf/src/read.rs @@ -12,14 +12,10 @@ pub enum BufReadError { InvalidVarLong, #[error("Error reading bytes")] CouldNotReadBytes, - #[error("The received encoded string buffer length is less than zero! Weird string!")] - StringLengthLessThanZero, #[error("The received encoded string buffer length is longer than maximum allowed ({length} > {max_length})")] - StringLengthTooLong { length: i32, max_length: u32 }, + StringLengthTooLong { length: u32, max_length: u32 }, #[error("{0}")] Io(#[from] std::io::Error), - #[error("Boolean value is not 0 or 1")] - InvalidBoolean, #[error("Invalid UTF-8")] InvalidUtf8, #[error("Unexpected enum variant {id}")] @@ -33,158 +29,27 @@ pub enum BufReadError { Deserialization(#[from] serde_json::Error), } -// TODO: get rid of Readable and use McBufReadable everywhere - -pub trait Readable { - fn read_int_id_list(&mut self) -> Result<Vec<i32>, BufReadError>; - fn read_varint(&mut self) -> Result<i32, BufReadError>; - fn get_varint_size(&mut self, value: i32) -> u8; - fn get_varlong_size(&mut self, value: i32) -> u8; - fn read_byte_array(&mut self) -> Result<Vec<u8>, BufReadError>; - fn read_bytes_with_len(&mut self, n: usize) -> Result<Vec<u8>, BufReadError>; - fn read_bytes(&mut self) -> Result<Vec<u8>, BufReadError>; - fn read_utf(&mut self) -> Result<String, BufReadError>; - fn read_utf_with_len(&mut self, max_length: u32) -> Result<String, BufReadError>; - fn read_byte(&mut self) -> Result<u8, BufReadError>; - fn read_int(&mut self) -> Result<i32, BufReadError>; - fn read_boolean(&mut self) -> Result<bool, BufReadError>; - fn read_long(&mut self) -> Result<i64, BufReadError>; - fn read_short(&mut self) -> Result<i16, BufReadError>; - fn read_float(&mut self) -> Result<f32, BufReadError>; - fn read_double(&mut self) -> Result<f64, BufReadError>; -} - -impl<R> Readable for R -where - R: Read, -{ - fn read_int_id_list(&mut self) -> Result<Vec<i32>, BufReadError> { - let len = self.read_varint()?; - let mut list = Vec::with_capacity(len as usize); - for _ in 0..len { - list.push(self.read_varint()?); - } - Ok(list) +fn read_utf_with_len(buf: &mut impl Read, max_length: u32) -> Result<String, BufReadError> { + let length = u32::var_read_from(buf)?; + // i don't know why it's multiplied by 4 but it's like that in mojang's code so + if length as u32 > max_length * 4 { + return Err(BufReadError::StringLengthTooLong { + length, + max_length: max_length * 4, + }); } - // fast varints modified from https://github.com/luojia65/mc-varint/blob/master/src/lib.rs#L67 - /// Read a single varint from the reader and return the value - fn read_varint(&mut self) -> Result<i32, BufReadError> { - let mut buffer = [0]; - let mut ans = 0; - for i in 0..5 { - self.read_exact(&mut buffer) - .map_err(|_| BufReadError::InvalidVarInt)?; - ans |= ((buffer[0] & 0b0111_1111) as i32) << (7 * i); - if buffer[0] & 0b1000_0000 == 0 { - break; - } - } - Ok(ans) + // this is probably quite inefficient, idk how to do it better + let mut string = String::new(); + let mut buffer = vec![0; length as usize]; + buf.read_exact(&mut buffer) + .map_err(|_| BufReadError::InvalidUtf8)?; + string.push_str(std::str::from_utf8(&buffer).unwrap()); + if string.len() > length as usize { + return Err(BufReadError::StringLengthTooLong { length, max_length }); } - fn get_varint_size(&mut self, value: i32) -> u8 { - for i in 1..5 { - if (value & -1 << (i * 7)) != 0 { - continue; - } - return i; - } - 5 - } - - fn get_varlong_size(&mut self, value: i32) -> u8 { - for i in 1..10 { - if (value & -1 << (i * 7)) != 0 { - continue; - } - return i; - } - 10 - } - - fn read_byte_array(&mut self) -> Result<Vec<u8>, BufReadError> { - let length = self.read_varint()? as usize; - self.read_bytes_with_len(length) - } - - fn read_bytes_with_len(&mut self, n: usize) -> Result<Vec<u8>, BufReadError> { - let mut buffer = vec![0; n]; - self.read_exact(&mut buffer) - .map_err(|_| BufReadError::CouldNotReadBytes)?; - Ok(buffer) - } - - fn read_bytes(&mut self) -> Result<Vec<u8>, BufReadError> { - // read to end of the buffer - let mut bytes = vec![]; - self.read_to_end(&mut bytes) - .map_err(|_| BufReadError::CouldNotReadBytes)?; - Ok(bytes) - } - - fn read_utf(&mut self) -> Result<String, BufReadError> { - self.read_utf_with_len(MAX_STRING_LENGTH.into()) - } - - fn read_utf_with_len(&mut self, max_length: u32) -> Result<String, BufReadError> { - let length = self.read_varint()?; - // i don't know why it's multiplied by 4 but it's like that in mojang's code so - if length < 0 { - return Err(BufReadError::StringLengthLessThanZero); - } - if length as u32 > max_length * 4 { - return Err(BufReadError::StringLengthTooLong { - length, - max_length: max_length * 4, - }); - } - - // this is probably quite inefficient, idk how to do it better - let mut string = String::new(); - let mut buffer = vec![0; length as usize]; - self.read_exact(&mut buffer) - .map_err(|_| BufReadError::InvalidUtf8)?; - string.push_str(std::str::from_utf8(&buffer).unwrap()); - if string.len() > length as usize { - return Err(BufReadError::StringLengthTooLong { length, max_length }); - } - - Ok(string) - } - - /// Read a single byte from the reader - fn read_byte(&mut self) -> Result<u8, BufReadError> { - Ok(self.read_u8()?) - } - - fn read_int(&mut self) -> Result<i32, BufReadError> { - Ok(self.read_i32::<BE>()?) - } - - fn read_boolean(&mut self) -> Result<bool, BufReadError> { - match self.read_byte()? { - 0 => Ok(false), - 1 => Ok(true), - _ => Err(BufReadError::InvalidBoolean), - } - } - - fn read_long(&mut self) -> Result<i64, BufReadError> { - Ok(self.read_i64::<BE>()?) - } - - fn read_short(&mut self) -> Result<i16, BufReadError> { - Ok(self.read_i16::<BE>()?) - } - - fn read_float(&mut self) -> Result<f32, BufReadError> { - Ok(self.read_f32::<BE>()?) - } - - fn read_double(&mut self) -> Result<f64, BufReadError> { - Ok(self.read_f64::<BE>()?) - } + Ok(string) } // fast varints modified from https://github.com/luojia65/mc-varint/blob/master/src/lib.rs#L67 @@ -223,13 +88,25 @@ where impl McBufReadable for i32 { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - Readable::read_int(buf) + Ok(buf.read_i32::<BE>()?) } } impl McBufVarReadable for i32 { + // fast varints modified from https://github.com/luojia65/mc-varint/blob/master/src/lib.rs#L67 + /// Read a single varint from the reader and return the value fn var_read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_varint() + let mut buffer = [0]; + let mut ans = 0; + for i in 0..5 { + buf.read_exact(&mut buffer) + .map_err(|_| BufReadError::InvalidVarInt)?; + ans |= ((buffer[0] & 0b0111_1111) as i32) << (7 * i); + if buffer[0] & 0b1000_0000 == 0 { + break; + } + } + Ok(ans) } } @@ -257,13 +134,17 @@ impl McBufVarReadable for u64 { impl McBufReadable for UnsizedByteArray { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - Ok(buf.read_bytes()?.into()) + // read to end of the buffer + let mut bytes = vec![]; + buf.read_to_end(&mut bytes) + .map_err(|_| BufReadError::CouldNotReadBytes)?; + Ok(bytes.into()) } } impl<T: McBufReadable + Send> McBufReadable for Vec<T> { default fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - let length = buf.read_varint()? as usize; + let length = u32::var_read_from(buf)? as usize; let mut contents = Vec::with_capacity(length); for _ in 0..length { contents.push(T::read_from(buf)?); @@ -274,7 +155,7 @@ impl<T: McBufReadable + Send> McBufReadable for Vec<T> { impl<K: McBufReadable + Send + Eq + Hash, V: McBufReadable + Send> McBufReadable for HashMap<K, V> { default fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - let length = buf.read_varint()? as usize; + let length = i32::var_read_from(buf)? as usize; let mut contents = HashMap::with_capacity(length); for _ in 0..length { contents.insert(K::read_from(buf)?, V::read_from(buf)?); @@ -287,7 +168,7 @@ impl<K: McBufReadable + Send + Eq + Hash, V: McBufVarReadable + Send> McBufVarRe for HashMap<K, V> { default fn var_read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - let length = buf.read_varint()? as usize; + let length = i32::var_read_from(buf)? as usize; let mut contents = HashMap::with_capacity(length); for _ in 0..length { contents.insert(K::read_from(buf)?, V::var_read_from(buf)?); @@ -298,49 +179,53 @@ impl<K: McBufReadable + Send + Eq + Hash, V: McBufVarReadable + Send> McBufVarRe impl McBufReadable for Vec<u8> { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_byte_array() + let length = i32::var_read_from(buf)? as usize; + let mut buffer = vec![0; length]; + buf.read_exact(&mut buffer) + .map_err(|_| BufReadError::CouldNotReadBytes)?; + Ok(buffer) } } impl McBufReadable for String { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_utf() + read_utf_with_len(buf, MAX_STRING_LENGTH.into()) } } impl McBufReadable for u32 { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - Readable::read_int(buf).map(|i| i as u32) + Ok(i32::read_from(buf)? as u32) } } impl McBufVarReadable for u32 { fn var_read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_varint().map(|i| i as u32) + Ok(i32::var_read_from(buf)? as u32) } } impl McBufReadable for u16 { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_short().map(|i| i as u16) + i32::read_from(buf).map(|i| i as u16) } } impl McBufReadable for i16 { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_short() + Ok(buf.read_i16::<BE>()?) } } impl McBufVarReadable for u16 { fn var_read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_varint().map(|i| i as u16) + Ok(i32::var_read_from(buf)? as u16) } } impl<T: McBufVarReadable> McBufVarReadable for Vec<T> { fn var_read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - let length = buf.read_varint()? as usize; + let length = i32::var_read_from(buf)? as usize; let mut contents = Vec::with_capacity(length); for _ in 0..length { contents.push(T::var_read_from(buf)?); @@ -351,7 +236,7 @@ impl<T: McBufVarReadable> McBufVarReadable for Vec<T> { impl McBufReadable for i64 { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_long() + Ok(buf.read_i64::<BE>()?) } } @@ -363,37 +248,37 @@ impl McBufReadable for u64 { impl McBufReadable for bool { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_boolean() + Ok(u8::read_from(buf)? != 0) } } impl McBufReadable for u8 { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_byte() + Ok(buf.read_u8()?) } } impl McBufReadable for i8 { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_byte().map(|i| i as i8) + u8::read_from(buf).map(|i| i as i8) } } impl McBufReadable for f32 { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_float() + Ok(buf.read_f32::<BE>()?) } } impl McBufReadable for f64 { fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - buf.read_double() + Ok(buf.read_f64::<BE>()?) } } impl<T: McBufReadable> McBufReadable for Option<T> { default fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - let present = buf.read_boolean()?; + let present = bool::read_from(buf)?; Ok(if present { Some(T::read_from(buf)?) } else { @@ -404,7 +289,7 @@ impl<T: McBufReadable> McBufReadable for Option<T> { impl<T: McBufVarReadable> McBufVarReadable for Option<T> { default fn var_read_from(buf: &mut impl Read) -> Result<Self, BufReadError> { - let present = buf.read_boolean()?; + let present = bool::read_from(buf)?; Ok(if present { Some(T::var_read_from(buf)?) } else { |
