const STORAGE_PACKET_HEADER_SIZE: usize = 11;
const STORAGE_PACKET_VERSION: u8 = 1;
#[derive(Debug, Clone, Copy)]
pub enum StroragePacketType {
StrorageInfo = 1,
StrorageItem = 2,
StrorageItemObject = 3,
}
impl From<u8> for StroragePacketType {
fn from(v: u8) -> Self {
match v {
1 => StroragePacketType::StrorageInfo,
2 => StroragePacketType::StrorageItem,
3 => StroragePacketType::StrorageItemObject,
_ => panic!("Unmatched StroragePacketType value {}", v),
}
}
}
#[derive(Debug, Default, Clone, Copy)]
pub enum StrorageCodecType {
#[default]
Bincode = 1,
ProtocolBuffers = 2,
FlatBuffers = 3,
MessagePack = 4,
CapnProto = 5,
}
impl From<u8> for StrorageCodecType {
fn from(v: u8) -> Self {
match v {
1 => StrorageCodecType::Bincode,
2 => StrorageCodecType::ProtocolBuffers,
3 => StrorageCodecType::FlatBuffers,
4 => StrorageCodecType::MessagePack,
5 => StrorageCodecType::CapnProto,
_ => panic!("Unmatched CodecType value {}", v),
}
}
}
pub struct StroragePacket {
pub header: StroragePacketHeader,
pub data: Vec<u8>,
}
#[derive(Debug)]
pub struct StroragePacketHeader {
pub packet_length: u64,
pub packet_type: StroragePacketType,
pub packet_version: u8,
pub codec_type: StrorageCodecType,
}
impl StroragePacketHeader {
pub fn to_vec(&self) -> Vec<u8> {
let mut header: Vec<u8> = Vec::with_capacity(STORAGE_PACKET_HEADER_SIZE);
header.extend_from_slice(&(self.packet_length.to_be_bytes()));
header.push(self.packet_type as u8);
header.push(self.packet_version);
header.push(self.codec_type as u8);
header
}
}
pub fn build_storage_packet(
buf: Vec<u8>,
packet_type: StroragePacketType,
codec_type: StrorageCodecType,
) -> StroragePacket {
let header = build_storage_packet_header(&buf, packet_type, codec_type);
StroragePacket { header, data: buf }
}
pub fn parse_storage_packet(buf: Vec<u8>) -> Result<StroragePacket, String> {
let header = parse_storage_packet_header(&buf)?;
let mut data = buf;
data.drain(0..STORAGE_PACKET_HEADER_SIZE);
Ok(StroragePacket { header, data })
}
pub fn build_storage_packet_header(
buf: &[u8],
packet_type: StroragePacketType,
codec_type: StrorageCodecType,
) -> StroragePacketHeader {
StroragePacketHeader {
packet_type,
packet_version: STORAGE_PACKET_VERSION,
codec_type,
packet_length: (buf.len() + STORAGE_PACKET_HEADER_SIZE) as u64,
}
}
pub fn parse_storage_packet_header(buf: &[u8]) -> Result<StroragePacketHeader, String> {
let buf_len = buf.len();
if buf_len < STORAGE_PACKET_HEADER_SIZE {
return Err(format!(
"Cannot parse packet header, invalid buffer size: {}",
buf_len
));
}
let mut packet_length_arr = [0_u8; 8];
packet_length_arr.copy_from_slice(&buf[0..8]);
let packet_length = u64::from_be_bytes(packet_length_arr);
if buf_len != (packet_length as usize) {
return Err(format!(
"Invalid buffer size, expected: {}, found: {}",
packet_length, buf_len
));
}
let header = StroragePacketHeader {
packet_length,
packet_type: buf[8].into(),
packet_version: buf[9],
codec_type: buf[10].into(),
};
Ok(header)
}