diff options
| author | Max Audron <audron@cocaine.farm> | 2020-04-29 00:00:44 +0200 |
|---|---|---|
| committer | Max Audron <audron@cocaine.farm> | 2020-04-29 00:00:44 +0200 |
| commit | fc64e11cdd35051a2ea87237f548ae0497a2f7f9 (patch) | |
| tree | c57937731898b0ffd66d1d95bb0f181cae568c37 /src/protocol | |
| parent | finish parsing of primitive types (diff) | |
refactor everything
Diffstat (limited to 'src/protocol')
| -rw-r--r-- | src/protocol/error/mod.rs | 37 | ||||
| -rw-r--r-- | src/protocol/frame/mod.rs | 402 | ||||
| -rw-r--r-- | src/protocol/message/handshake.rs | 352 | ||||
| -rw-r--r-- | src/protocol/message/handshake/types.rs | 66 | ||||
| -rw-r--r-- | src/protocol/message/login.rs | 1 | ||||
| -rw-r--r-- | src/protocol/message/mod.rs | 5 | ||||
| -rw-r--r-- | src/protocol/mod.rs | 9 | ||||
| -rw-r--r-- | src/protocol/primitive/bufferinfo.rs | 74 | ||||
| -rw-r--r-- | src/protocol/primitive/datetime.rs | 93 | ||||
| -rw-r--r-- | src/protocol/primitive/message.rs | 184 | ||||
| -rw-r--r-- | src/protocol/primitive/mod.rs | 74 | ||||
| -rw-r--r-- | src/protocol/primitive/signedint.rs | 62 | ||||
| -rw-r--r-- | src/protocol/primitive/string.rs | 91 | ||||
| -rw-r--r-- | src/protocol/primitive/stringlist.rs | 45 | ||||
| -rw-r--r-- | src/protocol/primitive/unsignedint.rs | 81 | ||||
| -rw-r--r-- | src/protocol/primitive/variant.rs | 290 | ||||
| -rw-r--r-- | src/protocol/primitive/variantlist.rs | 46 | ||||
| -rw-r--r-- | src/protocol/primitive/variantmap.rs | 63 |
18 files changed, 0 insertions, 1975 deletions
diff --git a/src/protocol/error/mod.rs b/src/protocol/error/mod.rs deleted file mode 100644 index 72a9e59..0000000 --- a/src/protocol/error/mod.rs +++ /dev/null @@ -1,37 +0,0 @@ - #[derive(Debug, Fail)] -pub enum ProtocolError { - #[fail(display = "message has wrong type")] - WrongMsgType, - #[fail(display = "bool value is neither 0 nor 1")] - BoolOutOfRange, - #[fail(display = "QVariant is not known")] - UnknownVariant, - #[fail(display = "wrong variant has been given")] - WrongVariant, - #[fail(display = "io error")] - IOError(std::io::Error), - #[fail(display = "could not convert from int")] - TryFromIntError(std::num::TryFromIntError), - #[fail(display = "utf8 error")] - Utf8Error(std::string::FromUtf8Error), - } - -// impl std::error::Error for ErrorKind {} -// -// impl std::convert::From<std::io::Error> for ErrorKind { -// fn from(error: std::io::Error) -> Self { -// ErrorKind::IOError(error) -// } -// } -// -// impl std::convert::From<std::num::TryFromIntError> for ErrorKind { -// fn from(error: std::num::TryFromIntError) -> Self { -// ErrorKind::TryFromIntError(error) -// } -// } -// -// impl std::convert::From<std::string::FromUtf8Error> for ErrorKind { -// fn from(error: std::string::FromUtf8Error) -> Self { -// ErrorKind::Utf8Error(error) -// } -// } diff --git a/src/protocol/frame/mod.rs b/src/protocol/frame/mod.rs deleted file mode 100644 index 8c5a8d3..0000000 --- a/src/protocol/frame/mod.rs +++ /dev/null @@ -1,402 +0,0 @@ -use std::convert::TryInto; -use std::error::Error as StdError; -use std::fmt; -use std::io::{self, Cursor}; - -use bytes::{Buf, BufMut, BytesMut}; - -use tokio::io::{AsyncRead, AsyncWrite}; - -use tokio_util::codec::{Decoder, Encoder, Framed, FramedRead, FramedWrite}; - -use flate2::Compress; -use flate2::Compression; -use flate2::Decompress; -use flate2::FlushCompress; -use flate2::FlushDecompress; - -#[derive(Debug, Clone, Copy)] -pub struct Builder { - // Maximum frame length - compression: bool, - compression_level: Compression, - - // Maximum frame length - max_frame_len: usize, -} - -// An error when the number of bytes read is more than max frame length. -pub struct QuasselCodecError { - _priv: (), -} - -#[derive(Debug)] -pub struct QuasselCodec { - builder: Builder, - state: DecodeState, - comp: Compress, - decomp: Decompress, -} - -#[derive(Debug, Clone, Copy)] -enum DecodeState { - Head, - Data(usize), -} - -impl QuasselCodec { - // Creates a new quassel codec with default values - pub fn new() -> Self { - Self { - builder: Builder::new(), - state: DecodeState::Head, - comp: Compress::new(Compression::default(), true), - decomp: Decompress::new(true), - } - } - - /// Creates a new quassel codec builder with default configuration - /// values. - pub fn builder() -> Builder { - Builder::new() - } - - pub fn max_frame_length(&self) -> usize { - self.builder.max_frame_len - } - - pub fn compression(&self) -> bool { - self.builder.compression - } - - pub fn compression_level(&self) -> Compression { - self.builder.compression_level - } - - pub fn set_compression(&mut self, val: bool) { - self.builder.compression(val); - } - - pub fn set_compression_level(&mut self, val: Compression) { - self.builder.compression_level(val); - } - - fn decode_head(&mut self, src: &mut BytesMut) -> io::Result<Option<usize>> { - let head_len = 4; - - if src.len() < head_len { - // Not enough data - return Ok(None); - } - - let field_len = { - let mut src = Cursor::new(&mut *src); - - let field_len = src.get_uint(head_len); - - if field_len > self.builder.max_frame_len as u64 { - return Err(io::Error::new( - io::ErrorKind::InvalidData, - QuasselCodecError { _priv: () }, - )); - } - - // The check above ensures there is no overflow - field_len as usize - }; - - // Strip header - let _ = src.split_to(head_len); - - // Ensure that the buffer has enough space to read the incoming - // payload - src.reserve(field_len); - - Ok(Some(field_len)) - } - - fn decode_data(&self, n: usize, src: &mut BytesMut) -> io::Result<Option<BytesMut>> { - // At this point, the buffer has already had the required capacity - // reserved. All there is to do is read. - if src.len() < n { - return Ok(None); - } - - Ok(Some(src.split_to(n))) - } -} - -impl Decoder for QuasselCodec { - type Item = BytesMut; - type Error = io::Error; - - fn decode(&mut self, src: &mut BytesMut) -> Result<Option<BytesMut>, io::Error> { - // Create Unified Buffer for compressed and not compressed datastream - let mut buf: &mut BytesMut = &mut BytesMut::new(); - - if self.builder.compression == true { - // Buffer to shove uncompressed stream into - let mut msg = Vec::with_capacity(self.builder.max_frame_len); - - let before_in = self.decomp.total_in(); - let before_out = self.decomp.total_out(); - - self.decomp - .decompress_vec(&src, &mut msg, FlushDecompress::None)?; - // Clear the src buffer, decompress() only peeks at content. - // without this we will endlessly loop over the same frame. - src.clear(); - - let after_in = self.decomp.total_in(); - let after_out = self.decomp.total_out(); - - let len = (after_out - before_out).try_into().unwrap(); - - // Reserve length of uncompressed stream - // and put bytes into there - buf.reserve(len); - buf.put(&msg[..]); - } else { - buf = src; - } - - let n = match self.state { - DecodeState::Head => match self.decode_head(buf)? { - Some(n) => { - self.state = DecodeState::Data(n); - n - } - None => return Ok(None), - }, - DecodeState::Data(n) => n, - }; - - match self.decode_data(n, buf)? { - Some(data) => { - // Update the decode state - self.state = DecodeState::Head; - - // Make sure the buffer has enough space to read the next head - buf.reserve(4); - - Ok(Some(data)) - } - None => Ok(None), - } - } -} - -impl Encoder for QuasselCodec { - type Item = Vec<u8>; - type Error = io::Error; - - fn encode(&mut self, data: Vec<u8>, dst: &mut BytesMut) -> Result<(), io::Error> { - let buf = &mut BytesMut::new(); - - let n = (&data).len(); - - if n > self.builder.max_frame_len { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - QuasselCodecError { _priv: () }, - )); - } - - // Reserve capacity in the destination buffer to fit the frame and - // length field (plus adjustment). - buf.reserve(4 + n); - - buf.put_uint(n as u64, 4); - - // Write the frame to the buffer - buf.extend_from_slice(&data[..]); - - if self.builder.compression { - let mut cbuf: Vec<u8> = vec![0; 4 + n]; - let before_in = self.comp.total_in(); - let before_out = self.comp.total_out(); - self.comp.compress(buf, &mut cbuf, FlushCompress::Full)?; - let after_in = self.comp.total_in(); - let after_out = self.comp.total_out(); - - cbuf.truncate((after_out - before_out).try_into().unwrap()); - *dst = BytesMut::from(&cbuf[..]); - } else { - *dst = buf.clone(); - } - - Ok(()) - } -} - -impl Default for QuasselCodec { - fn default() -> Self { - Self::new() - } -} - -// ===== impl Builder ===== - -impl Builder { - /// Creates a new length delimited codec builder with default configuration - /// values. - /// - /// # Examples - /// - /// ``` - /// # use tokio::io::AsyncRead; - /// use libquassel::protocol::frame::QuasselCodec; - /// - /// # fn bind_read<T: AsyncRead>(io: T) { - /// QuasselCodec::builder() - /// .new_read(io); - /// # } - /// # pub fn main() {} - /// ``` - pub fn new() -> Builder { - Builder { - compression: false, - compression_level: Compression::default(), - max_frame_len: 64 * 1024 * 1024, - } - } - - pub fn compression(&mut self, val: bool) -> &mut Self { - self.compression = val; - self - } - - pub fn compression_level(&mut self, val: Compression) -> &mut Self { - self.compression_level = val; - self - } - - /// Sets the max frame length - /// - /// This configuration option applies to both encoding and decoding. The - /// default value is 8MB. - /// - /// When decoding, the length field read from the byte stream is checked - /// against this setting **before** any adjustments are applied. When - /// encoding, the length of the submitted payload is checked against this - /// setting. - /// - /// When frames exceed the max length, an `io::Error` with the custom value - /// of the `QuasselCodecError` type will be returned. - /// - /// # Examples - /// - /// ``` - /// # use tokio::io::AsyncRead; - /// use libquassel::protocol::frame::QuasselCodec; - /// - /// # fn bind_read<T: AsyncRead>(io: T) { - /// QuasselCodec::builder() - /// .max_frame_length(8 * 1024) - /// .new_read(io); - /// # } - /// # pub fn main() {} - /// ``` - pub fn max_frame_length(&mut self, val: usize) -> &mut Self { - self.max_frame_len = val; - self - } - - /// Create a configured length delimited `QuasselCodec` - /// - /// # Examples - /// - /// ``` - /// use libquassel::protocol::frame::QuasselCodec; - /// # pub fn main() { - /// QuasselCodec::builder() - /// .new_codec(); - /// # } - /// ``` - pub fn new_codec(&self) -> QuasselCodec { - QuasselCodec { - builder: *self, - state: DecodeState::Head, - comp: Compress::new(self.compression_level, true), - decomp: Decompress::new(true), - } - } - - /// Create a configured length delimited `FramedRead` - /// - /// # Examples - /// - /// ``` - /// # use tokio::io::AsyncRead; - /// use libquassel::protocol::frame::QuasselCodec; - /// - /// # fn bind_read<T: AsyncRead>(io: T) { - /// QuasselCodec::builder() - /// .new_read(io); - /// # } - /// # pub fn main() {} - /// ``` - pub fn new_read<T>(&self, upstream: T) -> FramedRead<T, QuasselCodec> - where - T: AsyncRead, - { - FramedRead::new(upstream, self.new_codec()) - } - - /// Create a configured length delimited `FramedWrite` - /// - /// # Examples - /// - /// ``` - /// # use tokio::io::AsyncWrite; - /// # use libquassel::protocol::frame::QuasselCodec; - /// # fn write_frame<T: AsyncWrite>(io: T) { - /// QuasselCodec::builder() - /// .new_write(io); - /// # } - /// # pub fn main() {} - /// ``` - pub fn new_write<T>(&self, inner: T) -> FramedWrite<T, QuasselCodec> - where - T: AsyncWrite, - { - FramedWrite::new(inner, self.new_codec()) - } - - /// Create a configured length delimited `Framed` - /// - /// # Examples - /// - /// ``` - /// # use tokio::io::{AsyncRead, AsyncWrite}; - /// # use libquassel::protocol::frame::QuasselCodec; - /// # fn write_frame<T: AsyncRead + AsyncWrite>(io: T) { - /// # let _ = - /// QuasselCodec::builder() - /// .new_framed(io); - /// # } - /// # pub fn main() {} - /// ``` - pub fn new_framed<T>(&self, inner: T) -> Framed<T, QuasselCodec> - where - T: AsyncRead + AsyncWrite, - { - Framed::new(inner, self.new_codec()) - } -} - -// ===== impl LengthDelimitedCodecError ===== - -impl fmt::Debug for QuasselCodecError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("QuasselCodecError").finish() - } -} - -impl fmt::Display for QuasselCodecError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("frame size too big") - } -} - -impl StdError for QuasselCodecError {} diff --git a/src/protocol/message/handshake.rs b/src/protocol/message/handshake.rs deleted file mode 100644 index 357d1a4..0000000 --- a/src/protocol/message/handshake.rs +++ /dev/null @@ -1,352 +0,0 @@ -use failure::Error; -use std::result::Result; - -use crate::protocol::error::ProtocolError; -use crate::protocol::primitive::{String, StringList, Variant, VariantList}; -use crate::util::get_msg_type; - -mod types; -pub use types::{HandshakeDeserialize, HandshakeSerialize, VariantMap}; - -use crate::match_variant; - -#[derive(Debug)] -pub struct ConnAck { - flags: u8, - extra: i16, - version: i8, -} - -impl crate::protocol::primitive::deserialize::Deserialize for ConnAck { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (flen, flags) = u8::parse(b)?; - let (elen, extra) = i16::parse(&b[flen..])?; - let (vlen, version) = i8::parse(&b[(flen + elen)..])?; - - return Ok(( - flen + elen + vlen, - Self { - flags, - extra, - version, - }, - )); - } -} - -#[derive(Debug)] -pub struct ClientInit { - pub client_version: String, // Version of the client - pub client_date: String, // Build date of the client - pub client_features: u32, - pub feature_list: StringList, // List of supported extended features -} - -impl HandshakeSerialize for ClientInit { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let mut values: VariantMap = VariantMap::with_capacity(5); - values.insert( - "MsgType".to_string(), - Variant::String("ClientInit".to_string()), - ); - values.insert( - "ClientVersion".to_string(), - Variant::String(self.client_version.clone()), - ); - values.insert( - "ClientDate".to_string(), - Variant::String(self.client_date.clone()), - ); - values.insert("Features".to_string(), Variant::u32(self.client_features)); - values.insert( - "FeatureList".to_string(), - Variant::StringList(self.feature_list.clone()), - ); - return HandshakeSerialize::serialize(&values); - } -} - -impl HandshakeDeserialize for ClientInit { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - - let msgtype = get_msg_type(&values["MsgType"])?; - - if msgtype == "ClientInit" { - return Ok(( - len, - Self { - client_version: match_variant!(values, Variant::String, "ClientVersion"), - client_date: match_variant!(values, Variant::String, "ClientDate"), - feature_list: match_variant!(values, Variant::StringList, "FeatureList"), - client_features: match_variant!(values, Variant::u32, "Features"), - }, - )); - } else { - bail!(ProtocolError::WrongMsgType); - } - } -} - -#[derive(Debug)] -pub struct ClientInitReject { - pub error_string: String, -} - -impl HandshakeSerialize for ClientInitReject { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let mut values: VariantMap = VariantMap::with_capacity(2); - values.insert( - "MsgType".to_string(), - Variant::String("ClientInitReject".to_string()), - ); - values.insert( - "ErrorString".to_string(), - Variant::String(self.error_string.clone()), - ); - return HandshakeSerialize::serialize(&values); - } -} - -impl HandshakeDeserialize for ClientInitReject { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - - let msgtype = get_msg_type(&values["MsgType"])?; - - if msgtype == "ClientInitReject" { - return Ok(( - len, - Self { - error_string: match_variant!(values, Variant::String, "ErrorString"), - }, - )); - } else { - bail!(ProtocolError::WrongMsgType); - } - } -} - -#[derive(Debug)] -pub struct ClientInitAck { - pub core_features: u32, // Flags of supported legacy features - pub core_configured: bool, // If the core has already been configured - pub storage_backends: VariantList, // List of VariantMaps of info on available backends - pub authenticators: VariantList, // List of VariantMaps of info on available authenticators - pub feature_list: StringList, // List of supported extended features -} - -impl HandshakeSerialize for ClientInitAck { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let mut values: VariantMap = VariantMap::with_capacity(6); - values.insert( - "MsgType".to_string(), - Variant::String("ClientInitAck".to_string()), - ); - values.insert("CoreFeatures".to_string(), Variant::u32(self.core_features)); - values.insert( - "Configured".to_string(), - Variant::bool(self.core_configured), - ); - values.insert( - "StorageBackends".to_string(), - Variant::VariantList(self.storage_backends.clone()), - ); - values.insert( - "Authenticators".to_string(), - Variant::VariantList(self.authenticators.clone()), - ); - values.insert( - "FeatureList".to_string(), - Variant::StringList(self.feature_list.clone()), - ); - return HandshakeSerialize::serialize(&values); - } -} - -impl HandshakeDeserialize for ClientInitAck { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - - let msgtype = get_msg_type(&values["MsgType"])?; - - if msgtype == "ClientInitAck" { - return Ok(( - len, - Self { - core_features: 0x00008000, - core_configured: match_variant!(values, Variant::bool, "Configured"), - storage_backends: match_variant!( - values, - Variant::VariantList, - "StorageBackends" - ), - authenticators: match_variant!(values, Variant::VariantList, "Authenticators"), - feature_list: match_variant!(values, Variant::StringList, "FeatureList"), - }, - )); - } else { - bail!(ProtocolError::WrongMsgType); - } - } -} - -#[derive(Debug)] -pub struct ClientLogin { - pub user: String, - pub password: String, -} - -impl HandshakeSerialize for ClientLogin { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let mut values: VariantMap = VariantMap::new(); - values.insert( - "MsgType".to_string(), - Variant::String("ClientLogin".to_string()), - ); - values.insert("User".to_string(), Variant::String(self.user.clone())); - values.insert( - "Password".to_string(), - Variant::String(self.password.clone()), - ); - return HandshakeSerialize::serialize(&values); - } -} - -impl HandshakeDeserialize for ClientLogin { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - - let msgtype = get_msg_type(&values["MsgType"])?; - - if msgtype == "ClientLogin" { - return Ok(( - len, - Self { - user: match_variant!(values, Variant::String, "User"), - password: match_variant!(values, Variant::String, "Password"), - }, - )); - } else { - bail!(ProtocolError::WrongMsgType); - } - } -} - -#[derive(Debug)] -pub struct ClientLoginAck; - -impl HandshakeSerialize for ClientLoginAck { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let mut values: VariantMap = VariantMap::with_capacity(1); - values.insert( - "MsgType".to_string(), - Variant::String("ClientLoginAck".to_string()), - ); - return HandshakeSerialize::serialize(&values); - } -} - -impl HandshakeDeserialize for ClientLoginAck { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - - let msgtype = get_msg_type(&values["MsgType"])?; - - if msgtype == "ClientLogin" { - return Ok((len, Self {})); - } else { - bail!(ProtocolError::WrongMsgType); - } - } -} - -#[derive(Debug)] -pub struct ClientLoginReject { - error: String, -} - -impl HandshakeSerialize for ClientLoginReject { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let mut values: VariantMap = VariantMap::with_capacity(1); - values.insert( - "MsgType".to_string(), - Variant::String("ClientLoginReject".to_string()), - ); - values.insert( - "ErrorString".to_string(), - Variant::String(self.error.clone()), - ); - return HandshakeSerialize::serialize(&values); - } -} - -impl HandshakeDeserialize for ClientLoginReject { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - - let msgtype = get_msg_type(&values["MsgType"])?; - - if msgtype == "ClientLogin" { - return Ok(( - len, - Self { - error: match_variant!(values, Variant::String, "ErrorString"), - }, - )); - } else { - bail!(ProtocolError::WrongMsgType); - } - } -} - -#[derive(Debug)] -pub struct SessionInit { - identities: VariantList, - buffers: VariantList, - network_ids: VariantList, -} - -impl HandshakeSerialize for SessionInit { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let mut values: VariantMap = VariantMap::with_capacity(1); - values.insert( - "MsgType".to_string(), - Variant::String("SessionInit".to_string()), - ); - values.insert( - "Identities".to_string(), - Variant::VariantList(self.identities.clone()), - ); - values.insert( - "BufferInfos".to_string(), - Variant::VariantList(self.buffers.clone()), - ); - values.insert( - "NetworkIds".to_string(), - Variant::VariantList(self.network_ids.clone()), - ); - return HandshakeSerialize::serialize(&values); - } -} - -impl HandshakeDeserialize for SessionInit { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - - let msgtype = get_msg_type(&values["MsgType"])?; - - if msgtype == "ClientLogin" { - return Ok(( - len, - Self { - identities: match_variant!(values, Variant::VariantList, "Identities"), - buffers: match_variant!(values, Variant::VariantList, "BufferInfos"), - network_ids: match_variant!(values, Variant::VariantList, "NetworkIds"), - }, - )); - } else { - bail!(ProtocolError::WrongMsgType); - } - } -} diff --git a/src/protocol/message/handshake/types.rs b/src/protocol/message/handshake/types.rs deleted file mode 100644 index 99864b9..0000000 --- a/src/protocol/message/handshake/types.rs +++ /dev/null @@ -1,66 +0,0 @@ -use std::collections::HashMap; -use std::convert::TryInto; -use std::result::Result; -use std::vec::Vec; - -use failure::Error; - -use crate::protocol::error::ProtocolError; -use crate::protocol::primitive::deserialize::Deserialize; -use crate::protocol::primitive::serialize::Serialize; -use crate::protocol::primitive::{String, Variant}; -use crate::util; - -pub trait HandshakeSerialize { - fn serialize(&self) -> Result<Vec<u8>, Error>; -} - -pub trait HandshakeDeserialize { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> - where - Self: std::marker::Sized; -} - -pub type VariantMap = HashMap<String, Variant>; - -impl HandshakeSerialize for VariantMap { - fn serialize<'a>(&'a self) -> Result<Vec<u8>, Error> { - let mut res: Vec<u8> = Vec::new(); - - for (k, v) in self { - let key = Variant::String(k.clone()); - res.extend(key.serialize()?); - res.extend(v.serialize()?); - } - - let len: i32 = (self.len() * 2).try_into().unwrap(); - util::insert_bytes(0, &mut res, &mut (len).to_be_bytes()); - - return Ok(res); - } -} - -impl HandshakeDeserialize for VariantMap { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (_, len) = i32::parse(&b[0..4])?; - - let mut pos: usize = 4; - let mut map = VariantMap::new(); - - for _ in 0..(len / 2) { - let (nlen, name) = Variant::parse(&b[pos..])?; - pos += nlen; - - let (vlen, value) = Variant::parse(&b[pos..])?; - pos += vlen; - - match name { - Variant::String(x) => map.insert(x, value), - Variant::StringUTF8(x) => map.insert(x, value), - _ => bail!(ProtocolError::WrongVariant), - }; - } - - return Ok((pos, map)); - } -} diff --git a/src/protocol/message/login.rs b/src/protocol/message/login.rs deleted file mode 100644 index 8b13789..0000000 --- a/src/protocol/message/login.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/protocol/message/mod.rs b/src/protocol/message/mod.rs deleted file mode 100644 index f1d4750..0000000 --- a/src/protocol/message/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod handshake; -pub use handshake::*; - -pub mod login; -pub use login::*; diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs deleted file mode 100644 index 3630fab..0000000 --- a/src/protocol/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub mod message; -pub mod primitive; - -#[allow(dead_code)] -pub mod error; - -#[allow(unused_variables, dead_code)] -#[cfg(feature = "framing")] -pub mod frame; diff --git a/src/protocol/primitive/bufferinfo.rs b/src/protocol/primitive/bufferinfo.rs deleted file mode 100644 index 4c69286..0000000 --- a/src/protocol/primitive/bufferinfo.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::vec::Vec; - -use failure::Error; - -use crate::protocol::primitive::deserialize::{Deserialize, DeserializeUTF8}; -use crate::protocol::primitive::serialize::{Serialize, SerializeUTF8}; -use crate::protocol::primitive::String; - -extern crate bytes; - -#[derive(Clone, Debug, std::cmp::PartialEq)] -pub struct BufferInfo { - pub id: i32, // a unique, sequential id for the buffer - pub network_id: i32, // NetworkId of the network the buffer belongs to - pub buffer_type: BufferType, - pub name: String, // BufferName as displayed to the user -} - -impl Serialize for BufferInfo { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let mut values: Vec<u8> = Vec::new(); - - values.append(&mut i32::serialize(&self.id)?); - values.append(&mut i32::serialize(&self.network_id)?); - values.append(&mut i16::serialize(&(self.buffer_type as i16))?); - values.append(&mut vec![0, 0, 0, 0]); - values.append(&mut String::serialize_utf8(&self.name)?); - - Ok(values) - } -} - -impl Deserialize for BufferInfo { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (_, id) = i32::parse(&b[0..4])?; - let (_, network_id) = i32::parse(&b[4..8])?; - let (_, buffer_type) = i16::parse(&b[8..10])?; - - // There are 4 additional undocumted Bytes in the BufferInfo - // so we start at byte 14 - let (size, name) = String::parse_utf8(&b[14..])?; - - return Ok(( - 14 + size, - Self { - id, - network_id, - buffer_type: BufferType::from(buffer_type), - name, - }, - )); - } -} - -#[repr(i16)] -#[derive(Copy, Clone, Debug, std::cmp::PartialEq)] -pub enum BufferType { - Status = 0x01, - Channel = 0x02, - Query = 0x04, - Group = 0x08, -} - -impl From<i16> for BufferType { - fn from(value: i16) -> Self { - match value { - 0x01 => return Self::Status, - 0x02 => return Self::Channel, - 0x04 => return Self::Query, - 0x08 => return Self::Group, - _ => unimplemented!(), - } - } -} diff --git a/src/protocol/primitive/datetime.rs b/src/protocol/primitive/datetime.rs deleted file mode 100644 index 688a022..0000000 --- a/src/protocol/primitive/datetime.rs +++ /dev/null @@ -1,93 +0,0 @@ -use crate::protocol::primitive::deserialize::Deserialize; -use crate::protocol::primitive::serialize::Serialize; - -#[derive(Clone, Debug, std::cmp::PartialEq)] -pub struct DateTime { - julian_day: i32, // Day in Julian calendar, unknown if signed or unsigned - millis_of_day: i32, // Milliseconds since start of day - zone: u8, // Timezone of DateTime, 0x00 is local, 0x01 is UTC -} - -impl Serialize for DateTime { - fn serialize(&self) -> Result<Vec<std::primitive::u8>, failure::Error> { - let mut values: Vec<u8> = Vec::new(); - - values.append(&mut i32::serialize(&self.julian_day)?); - values.append(&mut i32::serialize(&self.millis_of_day)?); - values.append(&mut u8::serialize(&(self.zone))?); - - Ok(values) - } -} - -impl Deserialize for DateTime { - fn parse(b: &[std::primitive::u8]) -> Result<(std::primitive::usize, Self), failure::Error> - where - Self: Sized, - { - let (_, julian_day) = i32::parse(&b[0..4])?; - let (_, millis_of_day) = i32::parse(&b[4..8])?; - let (_, zone) = u8::parse(&b[8..9])?; - - return Ok(( - 9, - DateTime { - julian_day, - millis_of_day, - zone, - }, - )); - } -} - -#[derive(Clone, Debug, std::cmp::PartialEq)] -pub struct Date { - julian_day: i32, // Day in Julian calendar, unknown if signed or unsigned -} - -impl Serialize for Date { - fn serialize(&self) -> Result<Vec<std::primitive::u8>, failure::Error> { - let mut values: Vec<u8> = Vec::new(); - - values.append(&mut i32::serialize(&self.julian_day)?); - - Ok(values) - } -} - -impl Deserialize for Date { - fn parse(b: &[std::primitive::u8]) -> Result<(std::primitive::usize, Self), failure::Error> - where - Self: Sized, - { - let (_, julian_day) = i32::parse(&b[0..4])?; - - return Ok((9, Date { julian_day })); - } -} - -#[derive(Clone, Debug, std::cmp::PartialEq)] -pub struct Time { - millis_of_day: i32, // Milliseconds since start of day -} - -impl Serialize for Time { - fn serialize(&self) -> Result<Vec<std::primitive::u8>, failure::Error> { - let mut values: Vec<u8> = Vec::new(); - - values.append(&mut i32::serialize(&self.millis_of_day)?); - - Ok(values) - } -} - -impl Deserialize for Time { - fn parse(b: &[std::primitive::u8]) -> Result<(std::primitive::usize, Self), failure::Error> - where - Self: Sized, - { - let (_, millis_of_day) = i32::parse(&b[0..4])?; - - return Ok((4, Time { millis_of_day })); - } -} diff --git a/src/protocol/primitive/message.rs b/src/protocol/primitive/message.rs deleted file mode 100644 index 4ae895d..0000000 --- a/src/protocol/primitive/message.rs +++ /dev/null @@ -1,184 +0,0 @@ -use std::vec::Vec; - -use failure::Error; - -use crate::protocol::primitive::deserialize::{Deserialize, DeserializeUTF8}; -use crate::protocol::primitive::serialize::{Serialize, SerializeUTF8}; - -use crate::protocol::primitive::BufferInfo; -use crate::protocol::primitive::String; - -extern crate bytes; - -#[derive(Clone, Debug, std::cmp::PartialEq)] -pub struct Message { - pub msg_id: i32, // The unique, sequential id for the message - pub timestamp: i64, // The timestamp of the message in UNIX time (32-bit, seconds, 64-bit if LONGMESSAGE feature enabled) - pub msg_type: MessageType, - pub flags: i8, - pub buffer: BufferInfo, // The buffer the message belongs to, usually everything but BufferId is set to NULL - pub sender: String, // The sender as nick!ident@host - pub sender_prefixes: Option<String>, // The prefix modes of the sender - pub real_name: Option<String>, // The realName of the sender - pub avatar_url: Option<String>, // The avatarUrl of the sender, if available - pub content: String, // The message content, already stripped from CTCP formatting, but containing mIRC format codes -} - -impl Serialize for Message { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let mut values: Vec<u8> = Vec::new(); - - values.append(&mut i32::serialize(&self.msg_id)?); - - // TODO LONGMESSAGE feature - if false { - values.append(&mut i64::serialize(&self.timestamp)?); - } else { - values.append(&mut i32::serialize(&(self.timestamp as i32))?); - } - - values.append(&mut i32::serialize(&(self.msg_type as i32))?); - values.append(&mut i8::serialize(&(self.flags as i8))?); - values.append(&mut BufferInfo::serialize(&self.buffer)?); - values.append(&mut String::serialize_utf8(&self.sender)?); - - // TODO SenderPrefixes feature - if false { - if let Some(x) = &self.sender_prefixes { - values.append(&mut String::serialize_utf8(&x)?); - } - } - - // TODO RichMessages feature - if false { - if let Some(x) = &self.real_name { - values.append(&mut String::serialize_utf8(&x)?); - } - if let Some(x) = &self.avatar_url { - values.append(&mut String::serialize_utf8(&x)?); - } - } - - values.append(&mut String::serialize_utf8(&self.content)?); - - return Ok(values); - } -} - -impl Deserialize for Message { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let mut pos = 0; - let (parsed, msg_id) = i32::parse(&b[pos..])?; - pos += parsed; - - // TODO LONGMESSAGES feature - let timestamp; - if false { - let (parsed, temp_timestamp) = i64::parse(&b[pos..])?; - pos += parsed; - timestamp = temp_timestamp; - } else { - let (parsed, temp_timestamp) = i32::parse(&b[pos..])?; - pos += parsed; - timestamp = temp_timestamp as i64; - } - - let (parsed, msg_type) = i32::parse(&b[pos..])?; - pos += parsed; - let (parsed, flags) = i8::parse(&b[pos..])?; - pos += parsed; - let (parsed, buffer) = BufferInfo::parse(&b[pos..])?; - pos += parsed; - let (parsed, sender) = String::parse_utf8(&b[pos..])?; - pos += parsed; - - // TODO SenderPrefixes feature - let mut sender_prefixes = None; - if false { - let (parsed, temp) = String::parse_utf8(&b[pos..])?; - sender_prefixes = Some(temp); - pos += parsed; - } - - // TODO SenderPrefixes feature - let mut real_name = None; - let mut avatar_url = None; - if false { - let (parsed, temp) = String::parse_utf8(&b[pos..])?; - real_name = Some(temp); - pos += parsed; - - let (parsed, temp) = String::parse_utf8(&b[pos..])?; - avatar_url = Some(temp); - pos += parsed; - } - - let (parsed, content) = String::parse_utf8(&b[pos..])?; - pos += parsed; - - return Ok(( - pos, - Self { - msg_id, - timestamp, - msg_type: MessageType::from(msg_type), - flags, - buffer, - sender, - sender_prefixes, - real_name, - avatar_url, - content, - }, - )); - } -} - -#[repr(i32)] -#[derive(Copy, Clone, Debug, std::cmp::PartialEq)] -pub enum MessageType { - Plain = 0x00000001, - Notice = 0x00000002, - Action = 0x00000004, - Nick = 0x00000008, - Mode = 0x00000010, - Join = 0x00000020, - Part = 0x00000040, - Quit = 0x00000080, - Kick = 0x00000100, - Kill = 0x00000200, - Server = 0x00000400, - Info = 0x00000800, - Error = 0x00001000, - DayChange = 0x00002000, - Topic = 0x00004000, - NetsplitJoin = 0x00008000, - NetsplitQuit = 0x00010000, - Invite = 0x00020000, -} - -impl From<i32> for MessageType { - fn from(val: i32) -> Self { - match val { - 0x00000001 => MessageType::Plain, - 0x00000002 => MessageType::Notice, - 0x00000004 => MessageType::Action, - 0x00000008 => MessageType::Nick, - 0x00000010 => MessageType::Mode, - 0x00000020 => MessageType::Join, - 0x00000040 => MessageType::Part, - 0x00000080 => MessageType::Quit, - 0x00000100 => MessageType::Kick, - 0x00000200 => MessageType::Kill, - 0x00000400 => MessageType::Server, - 0x00000800 => MessageType::Info, - 0x00001000 => MessageType::Error, - 0x00002000 => MessageType::DayChange, - 0x00004000 => MessageType::Topic, - 0x00008000 => MessageType::NetsplitJoin, - 0x00010000 => MessageType::NetsplitQuit, - 0x00020000 => MessageType::Invite, - _ => unimplemented!(), - } - } -} diff --git a/src/protocol/primitive/mod.rs b/src/protocol/primitive/mod.rs deleted file mode 100644 index 5656d71..0000000 --- a/src/protocol/primitive/mod.rs +++ /dev/null @@ -1,74 +0,0 @@ -pub mod bufferinfo; -pub mod datetime; -pub mod message; -pub mod signedint; -pub mod string; -pub mod stringlist; -pub mod unsignedint; -pub mod variant; -pub mod variantlist; -pub mod variantmap; - -pub use bufferinfo::*; -pub use datetime::*; -pub use message::*; -pub use signedint::*; -pub use string::*; -pub use stringlist::*; -pub use unsignedint::*; -pub use variant::*; -pub use variantlist::*; -pub use variantmap::*; - -// Static Type Definitions -pub const VOID: u32 = 0x00000000; -pub const BOOL: u32 = 0x00000001; -pub const QCHAR: u32 = 0x00000007; - -pub const QVARIANT: u32 = 0x00000090; -pub const QVARIANTMAP: u32 = 0x00000008; -pub const QVARIANTLIST: u32 = 0x00000009; - -pub const QSTRING: u32 = 0x0000000a; -pub const QSTRINGLIST: u32 = 0x0000000b; -pub const QBYTEARRAY: u32 = 0x0000000c; - -pub const QDATE: u32 = 0x0000000e; -pub const QTIME: u32 = 0x0000000f; -pub const QDATETIME: u32 = 0x00000010; -pub const USERTYPE: u32 = 0x0000007f; - -// Basic types -pub const LONG: u32 = 0x00000081; // int64_t -pub const INT: u32 = 0x00000002; // int32_t -pub const SHORT: u32 = 0x00000082; // int16_t -pub const CHAR: u32 = 0x00000083; // int8_t - -pub const ULONG: u32 = 0x00000084; // uint64_t -pub const UINT: u32 = 0x00000003; // uint32_t -pub const USHORT: u32 = 0x00000085; // uint16_t -pub const UCHAR: u32 = 0x00000086; // uint8_t - -pub mod serialize { - use failure::Error; - pub trait Serialize { - fn serialize(&self) -> Result<Vec<u8>, Error>; - } - pub trait SerializeUTF8 { - fn serialize_utf8(&self) -> Result<Vec<u8>, Error>; - } -} - -pub mod deserialize { - use failure::Error; - pub trait Deserialize { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> - where - Self: std::marker::Sized; - } - pub trait DeserializeUTF8 { - fn parse_utf8(b: &[u8]) -> Result<(usize, Self), Error> - where - Self: std::marker::Sized; - } -} diff --git a/src/protocol/primitive/signedint.rs b/src/protocol/primitive/signedint.rs deleted file mode 100644 index 67ffb9d..0000000 --- a/src/protocol/primitive/signedint.rs +++ /dev/null @@ -1,62 +0,0 @@ -extern crate byteorder; -use byteorder::{BigEndian, ReadBytesExt}; -use std::io::Cursor; - -use std::convert::TryInto; -use std::result::Result; -use std::vec::Vec; - -use failure::Error; - -use crate::protocol::primitive::{deserialize, serialize}; - -impl serialize::Serialize for i64 { - fn serialize(&self) -> Result<Vec<u8>, Error> { - Ok(Vec::from(self.to_be_bytes())) - } -} - -impl deserialize::Deserialize for i64 { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let mut rdr = Cursor::new(&b[0..8]); - return Ok((8, rdr.read_i64::<BigEndian>()?)); - } -} - -impl serialize::Serialize for i32 { - fn serialize(&self) -> Result<Vec<u8>, Error> { - Ok(Vec::from(self.to_be_bytes())) - } -} - -impl deserialize::Deserialize for i32 { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let mut rdr = Cursor::new(&b[0..4]); - return Ok((4, rdr.read_i32::<BigEndian>()?)); - } -} - -impl serialize::Serialize for i16 { - fn serialize(&self) -> Result<Vec<u8>, Error> { - Ok(Vec::from(self.to_be_bytes())) - } -} - -impl deserialize::Deserialize for i16 { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let mut rdr = Cursor::new(&b[0..2]); - return Ok((2, rdr.read_i16::<BigEndian>()?)); - } -} - -impl serialize::Serialize for i8 { - fn serialize(&self) -> Result<Vec<u8>, Error> { - Ok(Vec::from(self.to_be_bytes())) - } -} - -impl deserialize::Deserialize for i8 { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - return Ok((1, b[0].try_into()?)); - } -} diff --git a/src/protocol/primitive/string.rs b/src/protocol/primitive/string.rs deleted file mode 100644 index 470f018..0000000 --- a/src/protocol/primitive/string.rs +++ /dev/null @@ -1,91 +0,0 @@ -extern crate byteorder; - -use std::result::Result; -use std::vec::Vec; - -use failure::Error; - -use log::trace; - -use crate::protocol::primitive::{deserialize, serialize}; -use crate::util; - -pub type String = std::string::String; -impl serialize::Serialize for String { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let mut res: Vec<u8> = Vec::new(); - - let utf16: Vec<u16> = self.encode_utf16().collect(); - for i in utf16 { - res.extend(i.to_be_bytes().iter()); - } - - util::prepend_byte_len(&mut res); - return Ok(res); - } -} - -impl serialize::SerializeUTF8 for String { - fn serialize_utf8(&self) -> Result<Vec<u8>, Error> { - let mut res: Vec<u8> = Vec::new(); - res.extend(self.clone().into_bytes()); - res.extend(vec![0x00]); - util::prepend_byte_len(&mut res); - return Ok(res); - } -} - -impl deserialize::Deserialize for String { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - // Parse Length - let (_, len) = i32::parse(&b[0..4])?; - trace!(target: "protocol::primitive::String", "Parsing with length: {:?}, from bytes: {:x?}", len, &b[0..4]); - - if len == -1 { - return Ok((4, "".to_string())); - } - - // length as usize - let ulen = len as usize; - let mut pos: usize = 4; - let mut chars: Vec<u16> = Vec::new(); - loop { - // if position is behind the length plus our 4 bytes of the length we already parsed - if pos >= (ulen + 4) { - break; - } - let (slen, uchar) = u16::parse(&b[pos..(pos + 2)])?; - chars.push(uchar); - pos += slen; - } - - let res: String = String::from_utf16(&chars).unwrap(); - return Ok((pos, res)); - } -} - -impl deserialize::DeserializeUTF8 for String { - fn parse_utf8(b: &[u8]) -> Result<(usize, Self), Error> { - use crate::protocol::primitive::deserialize::Deserialize; - let (_, len) = i32::parse(&b[0..4])?; - - trace!(target: "protocol::primitive::String", "Parsing with length: {:?}, from bytes: {:x?}", len, &b[0..4]); - - if len <= 0 { - return Ok((4, "".to_string())); - } - - let ulen = len as usize; - - let mut res: String = String::from_utf8(b[4..(ulen + 4)].to_vec())?; - - // If the last byte is zero remove it - // Receiving a string as bytearray will sometimes have - // the string null terminated - if res.chars().last().unwrap() == '\u{0}' { - let _ = res.pop(); - } - - return Ok((ulen + 4, res)); - } -} diff --git a/src/protocol/primitive/stringlist.rs b/src/protocol/primitive/stringlist.rs deleted file mode 100644 index d2902f2..0000000 --- a/src/protocol/primitive/stringlist.rs +++ /dev/null @@ -1,45 +0,0 @@ -extern crate byteorder; - -use std::convert::TryInto; -use std::result::Result; -use std::vec::Vec; - -use failure::Error; - -use log::trace; - -use crate::protocol::primitive::{deserialize, serialize}; - -pub type StringList = Vec<String>; -impl serialize::Serialize for StringList { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let len: i32 = self.len().try_into()?; - let mut res: Vec<u8> = Vec::new(); - - res.extend(len.to_be_bytes().iter()); - for x in self { - res.extend(x.serialize()?); - } - - return Ok(res); - } -} - -impl deserialize::Deserialize for StringList { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (_, len) = i32::parse(&b[0..4])?; - trace!(target: "protocol::primitive::StringList", "Parsing with length: {:?}, from bytes: {:x?}", len, &b[0..4]); - let mut res: StringList = StringList::new(); - - let mut pos = 4; - if len > 0 { - for _ in 0..len { - let (lpos, val) = String::parse(&b[pos..])?; - pos += lpos; - res.push(val); - } - } - - return Ok((pos, res)); - } -} diff --git a/src/protocol/primitive/unsignedint.rs b/src/protocol/primitive/unsignedint.rs deleted file mode 100644 index 5b42e3c..0000000 --- a/src/protocol/primitive/unsignedint.rs +++ /dev/null @@ -1,81 +0,0 @@ -extern crate byteorder; -use byteorder::{BigEndian, ReadBytesExt}; -use std::io::Cursor; - -use std::result::Result; -use std::vec::Vec; - -use failure::Error; - -use crate::protocol::error::ProtocolError; -use crate::protocol::primitive::{deserialize, serialize}; - -impl serialize::Serialize for bool { - fn serialize(&self) -> Result<Vec<u8>, Error> { - Ok({ - let i = *self as i8; - Vec::from(i.to_be_bytes()) - }) - } -} -impl deserialize::Deserialize for bool { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - if b[0] == 0 { - return Ok((1, false)); - } else if b[0] == 1 { - return Ok((1, true)); - } else { - bail!(ProtocolError::BoolOutOfRange); - }; - } -} -impl serialize::Serialize for u64 { - fn serialize(&self) -> Result<Vec<u8>, Error> { - Ok(Vec::from(self.to_be_bytes())) - } -} - -impl deserialize::Deserialize for u64 { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let mut rdr = Cursor::new(&b[0..8]); - return Ok((8, rdr.read_u64::<BigEndian>()?)); - } -} - -impl serialize::Serialize for u32 { - fn serialize(&self) -> Result<Vec<u8>, Error> { - Ok(Vec::from(self.to_be_bytes())) - } -} - -impl deserialize::Deserialize for u32 { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let mut rdr = Cursor::new(&b[0..4]); - return Ok((4, rdr.read_u32::<BigEndian>()?)); - } -} - -impl serialize::Serialize for u16 { - fn serialize(&self) -> Result<Vec<u8>, Error> { - Ok(Vec::from(self.to_be_bytes())) - } -} - -impl deserialize::Deserialize for u16 { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let mut rdr = Cursor::new(&b[0..2]); - return Ok((2, rdr.read_u16::<BigEndian>()?)); - } -} - -impl serialize::Serialize for u8 { - fn serialize(&self) -> Result<Vec<u8>, Error> { - Ok(Vec::from(self.to_be_bytes())) - } -} - -impl deserialize::Deserialize for u8 { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - return Ok((1, b[0])); - } -} diff --git a/src/protocol/primitive/variant.rs b/src/protocol/primitive/variant.rs deleted file mode 100644 index 84150a8..0000000 --- a/src/protocol/primitive/variant.rs +++ /dev/null @@ -1,290 +0,0 @@ -use std::vec::Vec; - -use failure::Error; - -use log::{error, trace}; - -use crate::protocol::error::ProtocolError; -use crate::protocol::primitive; -use crate::protocol::primitive::deserialize::{Deserialize, DeserializeUTF8}; -use crate::protocol::primitive::serialize::{Serialize, SerializeUTF8}; -use crate::protocol::primitive::{String, StringList}; - -extern crate bytes; -use bytes::BytesMut; - -use crate::protocol::primitive::{ - BufferInfo, Date, DateTime, Message, Time, VariantList, VariantMap, -}; - -#[allow(non_camel_case_types, dead_code)] -#[derive(Clone, Debug, std::cmp::PartialEq)] -pub enum Variant { - Unknown, - UserType(String, BytesMut), - BufferInfo(BufferInfo), - Message(Message), - Time(Time), - Date(Date), - DateTime(DateTime), - VariantMap(VariantMap), - VariantList(VariantList), - String(String), - StringUTF8(String), - ByteArray(String), - StringList(StringList), - bool(bool), - u64(u64), - u32(u32), - u16(u16), - u8(u8), - i64(i64), - i32(i32), - i16(i16), - i8(i8), -} - -impl Serialize for Variant { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let unknown: u8 = 0x00; - let mut res: Vec<u8> = Vec::new(); - - match self { - Variant::Unknown => { - bail!(ProtocolError::UnknownVariant); - } - Variant::VariantMap(v) => { - res.extend(primitive::QVARIANTMAP.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.serialize()?.iter()); - } - Variant::VariantList(v) => { - res.extend(primitive::QVARIANTLIST.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.serialize()?.iter()); - } - Variant::String(v) => { - res.extend(primitive::QSTRING.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.serialize()?.iter()); - } - Variant::StringUTF8(v) => { - res.extend(primitive::QBYTEARRAY.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.serialize_utf8()?.iter()); - } - Variant::ByteArray(v) => { - res.extend(primitive::QBYTEARRAY.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.serialize_utf8()?.iter()); - res.extend(vec![0x00]); - } - Variant::StringList(v) => { - res.extend(primitive::QSTRINGLIST.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.serialize()?.iter()); - } - Variant::bool(v) => { - res.extend(primitive::BOOL.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - let i = *v as i8; - res.extend(i.to_be_bytes().iter()); - } - Variant::u64(v) => { - res.extend(primitive::ULONG.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.to_be_bytes().iter()); - } - Variant::u32(v) => { - res.extend(primitive::UINT.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.to_be_bytes().iter()); - } - Variant::u16(v) => { - res.extend(primitive::USHORT.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.to_be_bytes().iter()); - } - Variant::u8(v) => { - res.extend(primitive::UCHAR.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.to_be_bytes().iter()); - } - Variant::i64(v) => { - res.extend(primitive::LONG.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.to_be_bytes().iter()); - } - Variant::i32(v) => { - res.extend(primitive::INT.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.to_be_bytes().iter()); - } - Variant::i16(v) => { - res.extend(primitive::SHORT.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.to_be_bytes().iter()); - } - Variant::i8(v) => { - res.extend(primitive::CHAR.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.extend(v.to_be_bytes().iter()); - } - Variant::UserType(_, _) => unimplemented!(), - Variant::BufferInfo(_) => unimplemented!(), - Variant::Message(_) => unimplemented!(), - Variant::DateTime(v) => { - res.extend(primitive::QDATETIME.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.append(&mut v.serialize()?); - } - Variant::Time(v) => { - res.extend(primitive::QTIME.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.append(&mut v.serialize()?); - } - Variant::Date(v) => { - res.extend(primitive::QDATE.to_be_bytes().iter()); - res.extend(unknown.to_be_bytes().iter()); - res.append(&mut v.serialize()?); - } - } - - return Ok(res); - } -} - -impl Deserialize for Variant { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (_, qtype) = i32::parse(&b[0..4])?; - let qtype = qtype as u32; - - #[allow(unused_variables)] - let unknown: u8 = b[4]; - - let len = 5; - match qtype { - primitive::QVARIANTMAP => { - trace!(target: "protocol::primitive::Variant", "Parsing Variant: VariantMap"); - let (vlen, value) = VariantMap::parse(&b[len..])?; - return Ok((len + vlen, Variant::VariantMap(value))); - } - primitive::QVARIANTLIST => { - trace!(target: "protocol::primitive::Variant", "Parsing Variant: VariantList"); - let (vlen, value) = VariantList::parse(&b[len..])?; - return Ok((len + vlen, Variant::VariantList(value))); - } - primitive::QSTRING => { - trace!(target: "protocol::primitive::Variant", "Parsing Variant: String"); - let (vlen, value) = String::parse(&b[len..])?; - return Ok((len + vlen, Variant::String(value.clone()))); - } - primitive::QBYTEARRAY => { - trace!(target: "protocol::primitive::Variant", "Parsing Variant: ByteArray"); - let (vlen, value) = String::parse_utf8(&b[len..])?; - return Ok((len + vlen, Variant::StringUTF8(value.clone()))); - } - primitive::QSTRINGLIST => { - trace!(target: "protocol::primitive::Variant", "Parsing Variant: StringList"); - let (vlen, value) = StringList::parse(&b[len..])?; - return Ok((len + vlen, Variant::StringList(value.clone()))); - } - primitive::QDATETIME => { - trace!(target: "protocol::primitive::Variant", "Parsing Variant: Date"); - let (vlen, value) = Date::parse(&b[len..])?; - return Ok((len + vlen, Variant::Date(value.clone()))); - } - primitive::QDATE => { - trace!(target: "protocol::primitive::Variant", "Parsing Variant: Date"); - let (vlen, value) = Date::parse(&b[len..])?; - return Ok((len + vlen, Variant::Date(value.clone()))); - } - primitive::QTIME => { - trace!(target: "protocol::primitive::Variant", "Parsing Variant: Time"); - let (vlen, value) = Time::parse(&b[len..])?; - return Ok((len + vlen, Variant::Time(value.clone()))); - } - primitive::BOOL => { - let (vlen, value) = bool::parse(&b[len..])?; - return Ok((len + vlen, Variant::bool(value))); - } - primitive::ULONG => { - let (vlen, value) = u64::parse(&b[len..])?; - return Ok((len + vlen, Variant::u64(value))); - } - primitive::UINT => { - let (vlen, value) = u32::parse(&b[len..])?; - return Ok((len + vlen, Variant::u32(value))); - } - primitive::USHORT => { - let (vlen, value) = u16::parse(&b[len..])?; - return Ok((len + vlen, Variant::u16(value))); - } - primitive::UCHAR => { - let (vlen, value) = u8::parse(&b[len..])?; - return Ok((len + vlen, Variant::u8(value))); - } - primitive::LONG => { - let (vlen, value) = i64::parse(&b[len..])?; - return Ok((len + vlen, Variant::i64(value))); - } - primitive::INT => { - let (vlen, value) = i32::parse(&b[len..])?; - return Ok((len + vlen, Variant::i32(value))); - } - primitive::SHORT => { - let (vlen, value) = i16::parse(&b[len..])?; - return Ok((len + vlen, Variant::i16(value))); - } - primitive::CHAR => { - let (vlen, value) = i8::parse(&b[len..])?; - return Ok((len + vlen, Variant::i8(value))); - } - primitive::USERTYPE => { - trace!(target: "protocol::primitive::Variant", "Parsing UserType"); - // Parse UserType name - let (user_type_len, user_type) = String::parse_utf8(&b[len..])?; - - trace!(target: "protocol::primitive::Variant", "Parsing UserType: {:?}", user_type); - - // Match Possible User Types to basic structures - match user_type.as_str() { - // As VariantMap - "IrcUser" | "IrcChannel" | "Identity" | "NetworkInfo" | "Network::Server" => { - trace!(target: "protocol::primitive::Variant", "UserType is VariantMap"); - let (vlen, value) = VariantMap::parse(&b[(len + user_type_len)..])?; - return Ok((len + user_type_len + vlen, Variant::VariantMap(value))); - } - // As i32 - "BufferId" | "IdentityId" | "NetworkId" | "MsgId" => { - trace!(target: "protocol::primitive::Variant", "UserType is i32"); - - let (vlen, value) = i32::parse(&b[(len + user_type_len)..])?; - return Ok((len + user_type_len + vlen, Variant::i32(value))); - } - // As i64 - "PeerPtr" => { - trace!(target: "protocol::primitive::Variant", "UserType is i64"); - let (vlen, value) = i64::parse(&b[(len + user_type_len)..])?; - return Ok((len + user_type_len + vlen, Variant::i64(value))); - } - "BufferInfo" => { - trace!(target: "protocol::primitive::Variant", "UserType is BufferInfo"); - let (vlen, value) = BufferInfo::parse(&b[(len + user_type_len)..])?; - return Ok((len + user_type_len + vlen, Variant::BufferInfo(value))); - } - "Message" => { - trace!(target: "protocol::primitive::Variant", "UserType is Message"); - let (vlen, value) = Message::parse(&b[(len + user_type_len)..])?; - return Ok((len + user_type_len + vlen, Variant::Message(value))); - } - _ => unimplemented!(), - } - } - err => { - error!(target: "parser", "UnknownVariant: {:x?}", err); - bail!(ProtocolError::UnknownVariant); - } - } - } -} diff --git a/src/protocol/primitive/variantlist.rs b/src/protocol/primitive/variantlist.rs deleted file mode 100644 index 2481b32..0000000 --- a/src/protocol/primitive/variantlist.rs +++ /dev/null @@ -1,46 +0,0 @@ -use std::convert::TryInto; -use std::vec::Vec; - -use failure::Error; - -use log::trace; - -use crate::protocol::primitive::{deserialize::Deserialize, serialize::Serialize}; - -extern crate bytes; - -use crate::protocol::primitive::Variant; - -pub type VariantList = Vec<Variant>; - -impl Serialize for VariantList { - fn serialize(&self) -> Result<Vec<u8>, Error> { - let len: i32 = self.len().try_into()?; - let mut res: Vec<u8> = Vec::new(); - - res.extend(len.to_be_bytes().iter()); - for v in self { - res.extend(v.serialize()?.iter()); - } - - return Ok(res); - } -} - -impl Deserialize for VariantList { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (_, len) = i32::parse(&b[0..4])?; - trace!(target: "protocol::primitive::VariantList", "Parsing VariantList with {:?} elements", len); - - let mut res: VariantList = VariantList::new(); - let mut pos: usize = 4; - for i in 0..len { - trace!(target: "protocol::primitive::VariantList", "Parsing VariantList element: {:?}", i); - let (vlen, val) = Variant::parse(&b[pos..])?; - res.push(val); - pos += vlen; - } - - return Ok((pos, res)); - } -} diff --git a/src/protocol/primitive/variantmap.rs b/src/protocol/primitive/variantmap.rs deleted file mode 100644 index 22ca0f1..0000000 --- a/src/protocol/primitive/variantmap.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::collections::HashMap; -use std::{convert::TryInto, vec::Vec}; - -use failure::Error; - -use log::trace; - -use crate::protocol::error::ProtocolError; -use crate::protocol::primitive::deserialize::Deserialize; -use crate::protocol::primitive::serialize::Serialize; -use crate::protocol::primitive::String; - -use crate::protocol::primitive::Variant; -use crate::util; - -extern crate bytes; - -pub type VariantMap = HashMap<String, Variant>; - -impl Serialize for VariantMap { - fn serialize<'a>(&'a self) -> Result<Vec<u8>, Error> { - let mut res: Vec<u8> = Vec::new(); - - for (k, v) in self { - res.extend(k.serialize()?); - res.extend(v.serialize()?); - } - - let len: i32 = self.len().try_into()?; - util::insert_bytes(0, &mut res, &mut len.to_be_bytes()); - - return Ok(res); - } -} - -impl Deserialize for VariantMap { - fn parse(b: &[u8]) -> Result<(usize, Self), Error> { - let (_, len) = i32::parse(&b[0..4])?; - trace!(target: "protocol::primitive::VariantMap", "Parsing VariantMap with {:?} elements", len); - - let mut pos: usize = 4; - let mut map = VariantMap::new(); - for _ in 0..len { - trace!(target: "protocol::primitive::VariantMap", "Parsing entry name"); - // let (nlen, name) = Variant::parse(&b[pos..])?; - let (nlen, name) = String::parse(&b[pos..])?; - pos += nlen; - - trace!(target: "protocol::primitive::VariantMap", "Parsing entry: {:?} with len {:?}", name, &b[(pos)..(pos + 4)]); - let (vlen, value) = Variant::parse(&b[(pos)..])?; - pos += vlen; - - // match name { - // Variant::String(x) => map.insert(x, value), - // Variant::StringUTF8(x) => map.insert(x, value), - // _ => bail!(ProtocolError::WrongVariant), - // }; - map.insert(name, value); - } - - return Ok((pos, map)); - } -} |
