use crate::{
encryption::EncryptionInfo,
id::{DId, InstanceID, LId, Port},
};
use cerpton::utf::utf8_to_string;
pub const INFO_SPLIT: &str = "\\|\\";
const INFO_SPLIT_AREA: &str = " \\|\\ ";
pub const CONTENTS_LENGTH: usize = 4096;
pub const MSG_INIT: &str = "\\z ";
pub const SN_MSG_INIT: &str = "\\\\z ";
pub const MSG_END: &str = " \\q";
pub type Contents = [u8; CONTENTS_LENGTH];
pub fn contents_to_string(contents: Contents) -> String {
utf8_to_string(contents.to_vec())
}
pub fn string_to_contents(string: String) -> Contents {
let bytes: &[u8] = string.as_bytes().try_into().unwrap();
let mut ret = [0; 4096];
for i in 0..4096 {
if i >= bytes.len() {
break;
}
ret[i] = bytes[i];
}
return ret;
}
#[inline]
pub fn split_from_info(string: &String) -> Vec<&str> {
string.split(INFO_SPLIT_AREA).collect::<Vec<&str>>()
}
#[inline]
pub fn valid_message_string(string: &String, encrypted: bool) -> bool {
let split = split_from_info(&string);
if split.len() != 3 {
println!("full length is not 3");
return false;
}
let receive_info = split[0].split(" ").collect::<Vec<&str>>();
if receive_info.len() != 4 {
println!("ri len not 4");
return false;
}
for i in 0..receive_info.len() {
let parse = receive_info[i].parse::<u64>();
if parse.is_err() {
println!("cannot parse ri");
return false;
} else {
if i == 0 || i == 1 {
if parse.unwrap() == 0 {
return false;
}
}
}
}
if encrypted {
return true;
}
let transmit_info = split[1].split(" ").collect::<Vec<&str>>();
if transmit_info.len() != 6 {
return false;
}
for i in 0..transmit_info.len() {
let parse = transmit_info[i].parse::<u64>();
if parse.is_err() {
return false;
} else {
if i == 0 || i == 2 {
if parse.unwrap() == 0 {
return false;
}
}
}
}
true
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct ReceiveInfo {
pub rid: LId,
pub rdid: DId,
pub instance_id: DId,
pub port: u16,
}
impl ReceiveInfo {
pub fn empty() -> Self {
return ReceiveInfo {
rid: 0,
rdid: 0,
instance_id: 0,
port: 0,
};
}
pub fn get_from_message_string(message: String) -> Self {
let msg_split = split_from_info(&message);
if msg_split.len() != 3 && msg_split.len() != 2 {
return ReceiveInfo::empty();
}
let info_split = msg_split[0].split(' ').collect::<Vec<&str>>();
if info_split.len() != 4 {
return ReceiveInfo::empty();
}
let rid = info_split[0].parse::<u64>();
let rdid = info_split[1].parse::<u32>();
let instance = info_split[2].parse::<u32>();
let port = info_split[3].parse::<u16>();
if rid.is_err() || rdid.is_err() || instance.is_err() || port.is_err() {
return ReceiveInfo::empty();
}
return ReceiveInfo {
rid: rid.unwrap(),
rdid: rdid.unwrap(),
instance_id: instance.unwrap(),
port: port.unwrap(),
};
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct TransmitInfo {
pub tid: LId,
pub tdid: DId,
pub code: u16,
}
impl TransmitInfo {
pub fn empty() -> Self {
return TransmitInfo {
tid: 0,
tdid: 0,
code: 0,
};
}
pub fn into_ri(&self, instance: InstanceID, port: Port) -> ReceiveInfo {
ReceiveInfo {
rid: self.tid,
rdid: self.tdid,
instance_id: instance,
port,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Message {
pub ri: ReceiveInfo,
pub ti: TransmitInfo,
pub contents: [u8; 4096],
pub day: i32,
pub week: i32,
pub month: i32,
}
impl Message {
pub fn empty() -> Self {
return Message {
ri: ReceiveInfo::empty(),
ti: TransmitInfo::empty(),
contents: [0; 4096],
day: -1,
week: -1,
month: -1,
};
}
pub fn as_string(&self) -> String {
format!(
"{} {} {} {} {} {} {} {} {} {} {} {} {}",
self.ri.rid,
self.ri.rdid,
self.ri.instance_id,
self.ri.port,
INFO_SPLIT,
self.ti.tid,
self.ti.code,
self.ti.tdid,
self.day,
self.week,
self.month,
INFO_SPLIT,
contents_to_string(self.contents)
)
}
pub fn get_ri_from_encoded(string: &String) -> ReceiveInfo {
let split_message = split_from_info(string);
if split_message.len() != 3 {
return ReceiveInfo::empty();
}
let split_ri = split_message[0].split(" ").collect::<Vec<&str>>();
if split_ri.len() != 4 {
return ReceiveInfo::empty();
}
ReceiveInfo {
rid: split_ri[0].parse().unwrap_or(0),
rdid: split_ri[1].parse().unwrap_or(0),
instance_id: split_ri[2].parse().unwrap_or(0),
port: split_ri[3].parse().unwrap_or(0),
}
}
#[inline]
pub fn ri_as_string(&self) -> String {
format!(
"{} {} {} {}",
self.ri.rid, self.ri.rdid, self.ri.instance_id, self.ri.port
)
}
#[inline]
pub fn ti_as_string(&self) -> String {
format!(
"{} {} {} {} {} {}",
self.ti.tid, self.ti.code, self.ti.tdid, self.day, self.week, self.month
)
}
pub fn encode(&self, encryption: EncryptionInfo) -> String {
let mut ret = String::new();
let ri = self.ri_as_string();
let ti = self.ti_as_string();
let contents = contents_to_string(self.contents);
ret.push_str(&ri);
ret.push_str(INFO_SPLIT_AREA);
ret.push_str(&(encryption.encode_function)(encryption.info, ti));
ret.push_str(INFO_SPLIT_AREA);
ret.push_str(&(encryption.encode_function)(encryption.info, contents));
ret
}
pub fn decode(string: &String, encryption: EncryptionInfo) -> Self {
let split = split_from_info(string);
let ri = split[0];
let ti = (encryption.decode_function)(encryption.info, split[1].to_string());
println!("og ti: {}, now ti: {}", split[1], ti);
let contents = (encryption.decode_function)(encryption.info, split[2].to_string());
let ret = Message::from_string(&format!(
"{}{}{}{}{}",
ri, INFO_SPLIT_AREA, ti, INFO_SPLIT_AREA, contents
));
ret
}
pub fn from_string(string: &String) -> Self {
let valid = valid_message_string(string, false);
if valid == false {
println!("invalid: {}", string);
return Message::empty();
}
let mut ret_message = Message::empty();
let split = split_from_info(string);
let ri = split[0].split(" ").collect::<Vec<&str>>();
let ti = split[1].split(" ").collect::<Vec<&str>>();
let contents = split[2];
for i in 0..ri.len() {
let parse = ri[i].parse::<u64>();
if parse.is_err() {
println!("error");
return Message::empty();
}
match i {
0 => ret_message.ri.rid = parse.unwrap(),
1 => ret_message.ri.rdid = parse.unwrap() as u32,
2 => ret_message.ri.instance_id = parse.unwrap() as u32,
3 => ret_message.ri.port = parse.unwrap() as u16,
_ => break,
};
}
for i in 0..ti.len() {
let parse = ti[i].parse::<u64>();
if parse.is_err() {
println!("error1");
return Message::empty();
}
match i {
0 => ret_message.ti.tid = parse.unwrap(),
1 => ret_message.ti.code = parse.unwrap() as u16,
2 => ret_message.ti.tdid = parse.unwrap() as u32,
3 => ret_message.day = parse.unwrap() as i32,
4 => ret_message.week = parse.unwrap() as i32,
5 => ret_message.month = parse.unwrap() as i32,
_ => break,
};
}
ret_message.contents = string_to_contents(contents.to_owned());
ret_message
}
}