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/primitive | |
| parent | finish parsing of primitive types (diff) | |
refactor everything
Diffstat (limited to 'src/protocol/primitive')
| -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 |
11 files changed, 0 insertions, 1103 deletions
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)); - } -} |
