From 3ed5bfd5ac9f12f323bcdb36f8fb840855d02634 Mon Sep 17 00:00:00 2001 From: Lizzy Fleckenstein Date: Fri, 10 Feb 2023 13:50:58 +0100 Subject: Implement UTF-8 decode and move packets to different crate --- src/lib.rs | 247 ++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 138 insertions(+), 109 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index c3e5cee..0019d1c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,42 +2,24 @@ #![feature(associated_type_bounds)] #![feature(iterator_try_collect)] -pub use enumset; pub use flate2; +pub use mt_ser_derive::{mt_derive, MtDeserialize, MtSerialize}; pub use paste; -#[cfg(feature = "random")] -pub use generate_random; - -#[cfg(feature = "random")] -pub use rand; - -#[cfg(feature = "serde")] -pub use serde; - use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; -use enumset::{EnumSet, EnumSetType, EnumSetTypeWithRepr}; -use mt_data_derive::mt_derive; -pub use mt_data_derive::{MtDeserialize, MtSerialize}; +use enumset::{EnumSet, EnumSetTypeWithRepr}; use paste::paste as paste_macro; use std::{ collections::{HashMap, HashSet}, convert::Infallible, - fmt, io::{self, Read, Write}, num::TryFromIntError, ops::Deref, }; use thiserror::Error; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; - -#[cfg(feature = "random")] -use generate_random::GenerateRandom; - -#[cfg(any(feature = "client", feature = "server"))] -use crate as mt_data; +#[cfg(test)] +mod tests; #[derive(Error, Debug)] pub enum SerializeError { @@ -87,6 +69,49 @@ pub trait OrDefault { fn or_default(self) -> Self; } +pub struct WrapRead<'a, R: Read>(pub &'a mut R); +impl<'a, R: Read> Read for WrapRead<'a, R> { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + + fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result { + self.0.read_vectored(bufs) + } + + /* + + fn is_read_vectored(&self) -> bool { + self.0.is_read_vectored() + } + + */ + + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + self.0.read_to_end(buf) + } + + fn read_to_string(&mut self, buf: &mut String) -> io::Result { + self.0.read_to_string(buf) + } + + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + self.0.read_exact(buf) + } + + /* + + fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> { + self.0.read_buf(buf) + } + + fn read_buf_exact(&mut self, cursor: io::BorrowedCursor<'_>) -> io::Result<()> { + self.0.read_buf_exact(cursor) + } + + */ +} + impl OrDefault for Result { fn or_default(self) -> Self { match self { @@ -96,24 +121,49 @@ impl OrDefault for Result { } } -pub trait MtCfg: - Sized + MtSerialize + MtDeserialize + TryFrom> -{ +pub trait MtLen { + fn option(&self) -> Option; + type Range: Iterator + 'static; + fn range(&self) -> Self::Range; + + type Take: Read; + fn take(&self, reader: R) -> Self::Take; +} + +pub trait MtCfg { + type Len: MtLen; fn utf16() -> bool { false } - fn var_len() -> bool; + fn write_len(len: usize, writer: &mut impl Write) -> Result<(), SerializeError>; + fn read_len(reader: &mut impl Read) -> Result; +} - fn write_len(len: usize, writer: &mut impl Write) -> Result<(), SerializeError> { - Self::try_from(len) - .map_err(Into::into)? - .mt_serialize::(writer) +pub trait MtSerialize { + fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError>; +} + +pub trait MtDeserialize: Sized { + fn mt_deserialize(reader: &mut impl Read) -> Result; +} + +impl MtLen for usize { + fn option(&self) -> Option { + Some(*self) } - fn read_len(reader: &mut impl Read) -> Result; + type Range = std::ops::Range; + fn range(&self) -> Self::Range { + 0..*self + } + + type Take = io::Take; + fn take(&self, reader: R) -> Self::Take { + reader.take(*self as u64) + } } trait MtCfgLen: @@ -126,105 +176,70 @@ trait MtCfgLen: } impl MtCfg for T { - type Range = std::ops::Range; + type Len = usize; - fn var_len() -> bool { - false + fn write_len(len: usize, writer: &mut impl Write) -> Result<(), SerializeError> { + Self::try_from(len) + .map_err(Into::into)? + .mt_serialize::(writer) } - fn read_len(reader: &mut impl Read) -> Result { - let len = Self::mt_deserialize::(reader)? + fn read_len(reader: &mut impl Read) -> Result { + Ok(Self::mt_deserialize::(reader)? .try_into() - .map_err(Into::into)?; - - Ok(0..len) + .map_err(Into::into)?) } } -pub type DefCfg = u16; - -pub trait MtSerialize: Sized { - fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError>; -} - -pub trait MtDeserialize: Sized { - fn mt_deserialize(reader: &mut impl Read) -> Result; -} - impl MtCfgLen for u8 {} impl MtCfgLen for u16 {} impl MtCfgLen for u32 {} impl MtCfgLen for u64 {} -#[derive(Debug)] -pub struct NoLen; +pub type DefCfg = u16; -impl MtSerialize for NoLen { - fn mt_serialize(&self, _writer: &mut impl Write) -> Result<(), SerializeError> { - Ok(()) - } -} +impl MtCfg for () { + type Len = (); -impl MtDeserialize for NoLen { - fn mt_deserialize(_reader: &mut impl Read) -> Result { - Ok(Self) + fn write_len(_len: usize, _writer: &mut impl Write) -> Result<(), SerializeError> { + Ok(()) } -} -impl TryFrom for NoLen { - type Error = Infallible; - - fn try_from(_x: usize) -> Result { - Ok(Self) + fn read_len(_writer: &mut impl Read) -> Result { + Ok(()) } } -impl MtCfg for NoLen { - fn var_len() -> bool { - true +impl MtLen for () { + fn option(&self) -> Option { + None } type Range = std::ops::RangeFrom; - - fn read_len(_reader: &mut impl Read) -> Result { - Ok(0..) - } -} - -pub struct Utf16(pub B); - -impl MtSerialize for Utf16 { - fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { - self.0.mt_serialize::(writer) + fn range(&self) -> Self::Range { + 0.. } -} -impl MtDeserialize for Utf16 { - fn mt_deserialize(reader: &mut impl Read) -> Result { - Ok(Self(B::mt_deserialize::(reader)?)) + type Take = R; + fn take(&self, reader: R) -> Self::Take { + reader } } -impl TryFrom for Utf16 { - type Error = >::Error; - - fn try_from(x: usize) -> Result { - Ok(Self(x.try_into()?)) - } -} +pub struct Utf16(pub B); impl MtCfg for Utf16 { - type Range = B::Range; + type Len = B::Len; fn utf16() -> bool { true } - fn var_len() -> bool { - B::var_len() + fn write_len(len: usize, writer: &mut impl Write) -> Result<(), SerializeError> { + B::write_len(len, writer) } - fn read_len(reader: &mut impl Read) -> Result { + fn read_len(reader: &mut impl Read) -> Result { B::read_len(reader) } } @@ -320,7 +335,7 @@ impl MtSerialize for &T { } } -fn mt_serialize_seq( +pub fn mt_serialize_seq( writer: &mut impl Write, iter: impl ExactSizeIterator + IntoIterator, ) -> Result<(), SerializeError> { @@ -330,20 +345,30 @@ fn mt_serialize_seq( .try_for_each(|item| item.mt_serialize::(writer)) } -fn mt_deserialize_seq<'a, C: MtCfg, T: MtDeserialize>( +pub fn mt_deserialize_seq<'a, C: MtCfg, T: MtDeserialize>( + reader: &'a mut impl Read, +) -> Result> + 'a, DeserializeError> { + let len = C::read_len(reader)?; + mt_deserialize_sized_seq(&len, reader) +} + +pub fn mt_deserialize_sized_seq<'a, L: MtLen, T: MtDeserialize>( + len: &L, reader: &'a mut impl Read, ) -> Result> + 'a, DeserializeError> { - Ok(C::read_len(reader)? - .into_iter() - .map_while(|_| match T::mt_deserialize::(reader) { - Err(DeserializeError::UnexpectedEof) if C::var_len() => None, + let variable = len.option().is_none(); + + Ok(len + .range() + .map_while(move |_| match T::mt_deserialize::(reader) { + Err(DeserializeError::UnexpectedEof) if variable => None, x => Some(x), })) } impl MtSerialize for [T; N] { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { - mt_serialize_seq::(writer, self.iter()) + mt_serialize_seq::<(), _>(writer, self.iter()) } } @@ -406,6 +431,7 @@ impl MtDeserialize for HashSe } } +// TODO: support more tuples impl MtSerialize for (A, B) { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { self.0.mt_serialize::(writer)?; @@ -476,8 +502,17 @@ impl MtDeserialize for String { Some(e) => Err(e), } } else { - // TODO: UTF-8 decode - Ok("".into()) + let len = C::read_len(reader)?; + + // use capacity if available + let mut st = match len.option() { + Some(x) => String::with_capacity(x), + None => String::new(), + }; + + len.take(WrapRead(reader)).read_to_string(&mut st)?; + + Ok(st) } } } @@ -493,9 +528,3 @@ impl MtDeserialize for Box { Ok(Self::new(T::mt_deserialize::(reader)?)) } } - -mod to_clt; -mod to_srv; - -pub use to_clt::*; -pub use to_srv::*; -- cgit v1.2.3