#![allow(
clippy::unreadable_literal,
clippy::upper_case_acronyms,
dead_code,
non_camel_case_types,
non_snake_case,
non_upper_case_globals,
overflowing_literals,
unused_variables,
unused_assignments
)]
use std::convert::From;
use std::convert::TryInto;
use ethereum_types::H256;
use keccak_hash::keccak;
use crate::bcossdk::kisserror::{KissErrKind, KissError};
#[derive(Default, Clone, Debug)]
pub struct ChannelPack {
pub length: usize,
pub packtype: u16,
pub seq: H256,
pub result: u32,
pub data: Vec<u8>,
}
impl ChannelPack {
pub fn detail(&self) -> String {
format!(
"len:{},type:0x{:X},seq:{:?},result:{},data:{}",
self.length,
self.packtype,
self.seq,
self.result,
String::from_utf8(self.data.clone()).unwrap().as_str()
)
}
pub fn make_seq(&self) -> H256 {
let v: u32 = rand::random();
let vhash = keccak(v.to_be_bytes());
return vhash;
}
pub fn pack(&self) -> Vec<u8> {
let mut buffer: Vec<u8> = Vec::new();
buffer.append(&mut Vec::from((self.length as u32).to_be_bytes()));
buffer.append(&mut Vec::from(self.packtype.to_be_bytes()));
buffer.append(&mut Vec::from(self.seq.to_fixed_bytes()));
buffer.append(&mut Vec::from(self.result.to_be_bytes()));
buffer.append(&mut self.data.clone());
buffer
}
pub fn unpack(data: &Vec<u8>) -> Result<ChannelPack, KissError> {
if data.len() < 42 {
return kisserr!(
KissErrKind::EFormat,
"channelpack data length too short: {}",
data.len()
);
}
let mut pack = ChannelPack::default();
pack.length = i32::from_be_bytes(data.as_slice()[..4].try_into().unwrap()) as usize;
if data.len() < pack.length {
return kisserr!(KissErrKind::EFormat, "buffer size less than pack.length");
}
let mut start = 4;
pack.packtype = u16::from_be_bytes(data.as_slice()[start..(start + 2)].try_into().unwrap());
start = start + 2;
pack.seq = H256::from_slice(&data[start..start + 32]);
start += 32;
pack.result = u32::from_be_bytes(data.as_slice()[start..start + 4].try_into().unwrap());
pack.data = Vec::from(&data[42..pack.length]);
Ok(pack)
}
}
pub fn make_channel_pack(data: &str) -> Option<ChannelPack> {
let mut pack = ChannelPack::default();
pack.data = Vec::from(data);
pack.seq = pack.make_seq();
pack.packtype = 0x12;
pack.result = 0;
pack.length = 42 + pack.data.len();
Option::from(pack)
}
pub fn test_channelpack() {
let mut pack = ChannelPack::default();
let data = "1234567890";
pack.data = Vec::from(data);
pack.seq = pack.make_seq();
pack.packtype = 0x12;
pack.result = 0;
pack.length = 42 + pack.data.len();
let bin = pack.pack();
println!("{:?}", &bin);
let hexv = hex::encode(bin.as_slice());
println!("{:?}", &hexv);
println!("totallen = {}", hexv.len());
let unpackres = ChannelPack::unpack(&bin).unwrap();
if unpackres.seq != pack.seq {
println!("ne");
} else {
println!("seq eq");
}
println!("unpack: {:?}", unpackres);
println!("data content {}", String::from_utf8(pack.data).unwrap());
}