diff options
| author | Max Audron <audron@cocaine.farm> | 2021-01-04 18:38:31 +0100 |
|---|---|---|
| committer | Max Audron <audron@cocaine.farm> | 2021-01-04 18:38:31 +0100 |
| commit | 0b7c6cf0b129799110d3ef0118e1f2b5697a2068 (patch) | |
| tree | 9bbb49c7af7feb6fc1aff497e0d577fe31ef11ed /src/primitive | |
| parent | WIP: function api (diff) | |
| parent | add example program: quasselproxy (diff) | |
Merge branch 'client'
Diffstat (limited to '')
| -rw-r--r-- | src/primitive/datetime.rs | 10 | ||||
| -rw-r--r-- | src/primitive/message.rs | 101 | ||||
| -rw-r--r-- | src/primitive/string.rs | 7 | ||||
| -rw-r--r-- | src/primitive/variant.rs | 25 | ||||
| -rw-r--r-- | src/primitive/variantlist.rs | 1 |
5 files changed, 98 insertions, 46 deletions
diff --git a/src/primitive/datetime.rs b/src/primitive/datetime.rs index cbcdd51..fadd6a5 100644 --- a/src/primitive/datetime.rs +++ b/src/primitive/datetime.rs @@ -76,10 +76,18 @@ impl Deserialize for OffsetDateTime { let zone = TimeSpec::from(zone as i8); + // Default to unix epoch when one of these is set to -1 + if julian_day == -1 || millis_of_day == -1 { + return Ok((pos, OffsetDateTime::unix_epoch())); + } + let offset: UtcOffset; match zone { TimeSpec::LocalUnknown | TimeSpec::LocalStandard | TimeSpec::LocalDST => { - offset = UtcOffset::current_local_offset() + offset = UtcOffset::try_current_local_offset().unwrap_or_else(|_| { + log::warn!("could not get local offset defaulting to utc"); + UtcOffset::UTC + }) } TimeSpec::UTC => offset = UtcOffset::UTC, TimeSpec::OffsetFromUTC => { diff --git a/src/primitive/message.rs b/src/primitive/message.rs index 64b132d..56bae22 100644 --- a/src/primitive/message.rs +++ b/src/primitive/message.rs @@ -15,9 +15,20 @@ extern crate bytes; #[derive(Clone, Debug, std::cmp::PartialEq)] pub struct Message { /// The unique, sequential id for the message + /// i32 by default i64 if long-message-id features is enabled + #[cfg(feature = "long-message-id")] + #[cfg_attr(docsrs, doc(cfg(feature = "long-message-id")))] + pub msg_id: i64, + #[cfg(not(feature = "long-message-id"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "long-message-id"))))] pub msg_id: i32, - /// The timestamp of the message in UNIX time (32-bit, seconds, 64-bit if LONGMESSAGE feature enabled) + /// The timestamp of the message in UNIX time (32-bit, seconds, 64-bit if long-time feature enabled) + #[cfg(feature = "long-time")] + #[cfg_attr(docsrs, doc(cfg(feature = "long-time")))] pub timestamp: i64, + #[cfg(not(feature = "long-time"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "long-time"))))] + pub timestamp: i32, /// The message type as it's own type serialized as i32 pub msg_type: MessageType, /// The flags @@ -27,14 +38,17 @@ pub struct Message { /// The sender as nick!ident@host pub sender: String, /// The prefix modes of the sender. - /// Only Some when the SenderPrefix features is enabled - pub sender_prefixes: Option<String>, + #[cfg(feature = "sender-prefixes")] + #[cfg_attr(docsrs, doc(cfg(feature = "sender-prefixes")))] + pub sender_prefixes: String, /// The realName of the sender - /// Only Some when the RichMessage features is enabled - pub real_name: Option<String>, + #[cfg(feature = "rich-messages")] + #[cfg_attr(docsrs, doc(cfg(feature = "rich-messages")))] + pub real_name: String, /// The avatarUrl of the sender, if available - /// Only Some when the RichMessage features is enabled - pub avatar_url: Option<String>, + #[cfg(feature = "rich-messages")] + #[cfg_attr(docsrs, doc(cfg(feature = "rich-messages")))] + pub avatar_url: String, /// The message content, already stripped from CTCP formatting, but containing mIRC format codes pub content: String, } @@ -43,35 +57,28 @@ impl Serialize for Message { fn serialize(&self) -> Result<Vec<u8>, Error> { let mut values: Vec<u8> = Vec::new(); + #[cfg(feature = "long-message-id")] + values.append(&mut i64::serialize(&self.msg_id)?); + #[cfg(not(feature = "long-message-id"))] 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))?); - } + #[cfg(feature = "long-time")] + values.append(&mut i64::serialize(&self.timestamp)?); + #[cfg(not(feature = "long-time"))] + 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)?); - } - } + #[cfg(feature = "sender-prefixes")] + values.append(&mut String::serialize_utf8(&self.sender_prefixes)?); - // 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)?); - } + #[cfg(feature = "rich-messages")] + { + values.append(&mut String::serialize_utf8(&self.real_name)?); + values.append(&mut String::serialize_utf8(&self.avatar_url)?); } values.append(&mut String::serialize_utf8(&self.content)?); @@ -83,19 +90,27 @@ impl Serialize for Message { impl Deserialize for Message { fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let mut pos = 0; + #[cfg(feature = "long-message-id")] + let (parsed, msg_id) = i64::parse(&b[pos..])?; + #[cfg(not(feature = "long-message-id"))] let (parsed, msg_id) = i32::parse(&b[pos..])?; pos += parsed; // TODO LONGMESSAGES feature let timestamp; - if false { + + #[cfg(feature = "long-time")] + { let (parsed, temp_timestamp) = i64::parse(&b[pos..])?; pos += parsed; timestamp = temp_timestamp; - } else { + } + + #[cfg(not(feature = "long-time"))] + { let (parsed, temp_timestamp) = i32::parse(&b[pos..])?; pos += parsed; - timestamp = temp_timestamp as i64; + timestamp = temp_timestamp; } let (parsed, msg_type) = i32::parse(&b[pos..])?; @@ -107,24 +122,27 @@ impl Deserialize for Message { let (parsed, sender) = String::parse_utf8(&b[pos..])?; pos += parsed; - // TODO SenderPrefixes feature - let mut sender_prefixes = None; - if false { + #[cfg(feature = "sender-prefixes")] + let sender_prefixes: String; + #[cfg(feature = "sender-prefixes")] + { let (parsed, temp) = String::parse_utf8(&b[pos..])?; - sender_prefixes = Some(temp); + sender_prefixes = temp; pos += parsed; } - // TODO SenderPrefixes feature - let mut real_name = None; - let mut avatar_url = None; - if false { + #[cfg(feature = "rich-messages")] + let real_name: String; + #[cfg(feature = "rich-messages")] + let avatar_url: String; + #[cfg(feature = "rich-messages")] + { let (parsed, temp) = String::parse_utf8(&b[pos..])?; - real_name = Some(temp); + real_name = temp; pos += parsed; let (parsed, temp) = String::parse_utf8(&b[pos..])?; - avatar_url = Some(temp); + avatar_url = temp; pos += parsed; } @@ -140,8 +158,11 @@ impl Deserialize for Message { flags, buffer, sender, + #[cfg(feature = "sender-prefixes")] sender_prefixes, + #[cfg(feature = "rich-messages")] real_name, + #[cfg(feature = "rich-messages")] avatar_url, content, }, diff --git a/src/primitive/string.rs b/src/primitive/string.rs index 86bcdec..dcd4f7c 100644 --- a/src/primitive/string.rs +++ b/src/primitive/string.rs @@ -7,8 +7,8 @@ use failure::Error; use log::trace; -use crate::{Deserialize, DeserializeUTF8, Serialize, SerializeUTF8}; use crate::util; +use crate::{Deserialize, DeserializeUTF8, Serialize, SerializeUTF8}; /// We Shadow the String type here as we can only use impl on types in our own scope. /// @@ -33,7 +33,6 @@ impl 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); } @@ -64,6 +63,7 @@ impl Deserialize for String { } let res: String = String::from_utf16(&chars).unwrap(); + trace!("parsed string: {}", res); return Ok((pos, res)); } } @@ -81,6 +81,7 @@ impl DeserializeUTF8 for String { let ulen = len as usize; let mut res: String = String::from_utf8(b[4..(ulen + 4)].to_vec())?; + trace!("parsed string: {}", res); // If the last byte is zero remove it // Receiving a string as bytearray will sometimes have @@ -89,6 +90,8 @@ impl DeserializeUTF8 for String { let _ = res.pop(); } + trace!("parsed string after trunc: {}", res); + return Ok((ulen + 4, res)); } } diff --git a/src/primitive/variant.rs b/src/primitive/variant.rs index 9242d90..be2bebe 100644 --- a/src/primitive/variant.rs +++ b/src/primitive/variant.rs @@ -36,6 +36,7 @@ pub enum Variant { VariantList(VariantList), String(String), StringUTF8(String), + ByteArray(String), StringList(StringList), bool(bool), u64(u64), @@ -77,6 +78,11 @@ impl Serialize for Variant { 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()); + } Variant::StringList(v) => { res.extend(primitive::QSTRINGLIST.to_be_bytes().iter()); res.extend(unknown.to_be_bytes().iter()); @@ -201,8 +207,7 @@ impl Deserialize for Variant { return Ok((len + vlen, Variant::StringList(value.clone()))); } primitive::QDATETIME => { - trace!(target: "primitive::Variant", "Parsing Variant: Date"); - // let (vlen, value) = DateTime::parse(&b[len..])?; + trace!(target: "primitive::Variant", "Parsing Variant: DateTime"); let (vlen, value): (usize, DateTime) = Deserialize::parse(&b[len..])?; return Ok((len + vlen, Variant::DateTime(value.clone()))); } @@ -269,12 +274,26 @@ impl Deserialize for Variant { return Ok((len + user_type_len + vlen, Variant::VariantMap(value))); } // As i32 - "BufferId" | "IdentityId" | "NetworkId" | "MsgId" => { + "BufferId" | "IdentityId" | "NetworkId" => { trace!(target: "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))); } + #[cfg(not(feature = "long-message-id"))] + "MsgId" => { + trace!(target: "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))); + } + #[cfg(feature = "long-message-id")] + "MsgId" => { + trace!(target: "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))); + } // As i64 "PeerPtr" => { trace!(target: "primitive::Variant", "UserType is i64"); diff --git a/src/primitive/variantlist.rs b/src/primitive/variantlist.rs index 452b927..a802864 100644 --- a/src/primitive/variantlist.rs +++ b/src/primitive/variantlist.rs @@ -40,6 +40,7 @@ impl Deserialize for VariantList { for i in 0..len { trace!(target: "primitive::VariantList", "Parsing VariantList element: {:?}", i); let (vlen, val) = Variant::parse(&b[pos..])?; + trace!("parsed variant: {:?}", val); res.push(val); pos += vlen; } |
