use serde::{Serialize, Serializer};
use serde;
use super::common_types::*;
#[derive(Deserialize, Debug, PartialEq)]
pub struct Submessage {
pub variant: SubmessageVariant
}
#[derive(Debug, PartialEq, Clone)]
pub enum SubmessageVariant {
InfoDestination(GuidPrefix),
InfoReply {
unicast_locator_list: LocatorList
},
InfoSource {
protocol_version: ProtocolVersion,
vendor_id: VendorId,
guid_prefix: GuidPrefix
},
InfoTimestamp(Timestamp),
AckNack {
reader_id: EntityId,
writer_id: EntityId,
reader_sn_state: SequenceNumberSet,
count: Count
},
Data {
reader_id: EntityId,
writer_id: EntityId,
writer_sn: SequenceNumber,
serialized_payload: ArcBuffer
},
DataFrag {
reader_id: EntityId,
writer_id: EntityId,
writer_sn: SequenceNumber,
fragment_start_num: FragmentNumber,
fragments_in_submessage: u16,
data_size: u32,
fragment_size: u16,
serialized_payload: ArcBuffer
},
Gap {
reader_id: EntityId,
writer_id: EntityId,
gap_start: SequenceNumber,
gap_list: SequenceNumberSet
},
Heartbeat {
reader_id: EntityId,
writer_id: EntityId,
first_sn: SequenceNumber,
last_sn: SequenceNumber,
count: Count
},
HeartbeatFrag {
reader_id: EntityId,
writer_id: EntityId,
writer_sn: SequenceNumber,
last_fragment_number: FragmentNumber,
count: Count
},
NackFrag {
reader_id: EntityId,
writer_id: EntityId,
writer_sn: SequenceNumber,
fragment_number_state: FragmentNumberSet,
count: Count
},
Pad
}
impl serde::Deserialize for SubmessageVariant {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: serde::Deserializer {
let kind: SubmessageId = try!(serde::Deserialize::deserialize(deserializer));
let _flags : u8 = try!(serde::Deserialize::deserialize(deserializer));
let _message_len: u32 = try!(serde::Deserialize::deserialize(deserializer));
match kind {
SubmessageId::INFO_TS => {
Ok(SubmessageVariant::InfoTimestamp(try!(serde::Deserialize::deserialize(deserializer))))
},
SubmessageId::INFO_SRC => {
Ok(SubmessageVariant::InfoSource {
protocol_version: try!(serde::Deserialize::deserialize(deserializer)),
vendor_id: try!(serde::Deserialize::deserialize(deserializer)),
guid_prefix: try!(serde::Deserialize::deserialize(deserializer))
})
},
SubmessageId::INFO_REPLY => {
Ok(SubmessageVariant::InfoReply {
unicast_locator_list: try!(serde::Deserialize::deserialize(deserializer))
})
},
SubmessageId::INFO_DST => {
Ok(SubmessageVariant::InfoDestination(try!(serde::Deserialize::deserialize(deserializer))))
},
SubmessageId::INFO_REPLY_IP4 => {
Err(serde::Error::custom("we don't do ipv4 specialization yet"))
},
SubmessageId::ACKNACK => {
Ok(SubmessageVariant::AckNack {
reader_id: try!(serde::Deserialize::deserialize(deserializer)),
writer_id: try!(serde::Deserialize::deserialize(deserializer)),
reader_sn_state: try!(serde::Deserialize::deserialize(deserializer)),
count: try!(serde::Deserialize::deserialize(deserializer)),
})
},
SubmessageId::DATA => {
Ok(SubmessageVariant::Data {
reader_id: try!(serde::Deserialize::deserialize(deserializer)),
writer_id: try!(serde::Deserialize::deserialize(deserializer)),
writer_sn: try!(serde::Deserialize::deserialize(deserializer)),
serialized_payload: try!(serde::Deserialize::deserialize(deserializer)),
})
},
SubmessageId::DATA_FRAG => {
Ok(SubmessageVariant::DataFrag {
reader_id: try!(serde::Deserialize::deserialize(deserializer)),
writer_id: try!(serde::Deserialize::deserialize(deserializer)),
writer_sn: try!(serde::Deserialize::deserialize(deserializer)),
fragment_start_num: try!(serde::Deserialize::deserialize(deserializer)),
fragments_in_submessage: try!(serde::Deserialize::deserialize(deserializer)),
data_size: try!(serde::Deserialize::deserialize(deserializer)),
fragment_size: try!(serde::Deserialize::deserialize(deserializer)),
serialized_payload: try!(serde::Deserialize::deserialize(deserializer)),
})
},
SubmessageId::HEARTBEAT => {
Ok(SubmessageVariant::Heartbeat {
reader_id: try!(serde::Deserialize::deserialize(deserializer)),
writer_id: try!(serde::Deserialize::deserialize(deserializer)),
first_sn: try!(serde::Deserialize::deserialize(deserializer)),
last_sn: try!(serde::Deserialize::deserialize(deserializer)),
count: try!(serde::Deserialize::deserialize(deserializer)),
})
},
SubmessageId::HEARTBEAT_FRAG => {
Ok(SubmessageVariant::HeartbeatFrag {
reader_id: try!(serde::Deserialize::deserialize(deserializer)),
writer_id: try!(serde::Deserialize::deserialize(deserializer)),
writer_sn: try!(serde::Deserialize::deserialize(deserializer)),
last_fragment_number: try!(serde::Deserialize::deserialize(deserializer)),
count: try!(serde::Deserialize::deserialize(deserializer)),
})
},
SubmessageId::GAP => {
Ok(SubmessageVariant::Gap {
reader_id: try!(serde::Deserialize::deserialize(deserializer)),
writer_id: try!(serde::Deserialize::deserialize(deserializer)),
gap_start: try!(serde::Deserialize::deserialize(deserializer)),
gap_list: try!(serde::Deserialize::deserialize(deserializer)),
})
},
SubmessageId::NACK_FRAG => {
Ok(SubmessageVariant::NackFrag {
reader_id: try!(serde::Deserialize::deserialize(deserializer)),
writer_id: try!(serde::Deserialize::deserialize(deserializer)),
writer_sn: try!(serde::Deserialize::deserialize(deserializer)),
fragment_number_state: try!(serde::Deserialize::deserialize(deserializer)),
count: try!(serde::Deserialize::deserialize(deserializer)),
})
},
SubmessageId::PAD => {
Ok(SubmessageVariant::Pad)
}
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, PartialEq)]
enum SubmessageId {
PAD,
ACKNACK,
HEARTBEAT,
GAP,
INFO_TS,
INFO_SRC,
INFO_REPLY_IP4,
INFO_DST,
INFO_REPLY,
NACK_FRAG,
HEARTBEAT_FRAG,
DATA,
DATA_FRAG,
}
impl Serialize for SubmessageId {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
let val = match *self {
SubmessageId::PAD => 0x01,
SubmessageId::ACKNACK => 0x06,
SubmessageId::HEARTBEAT => 0x07,
SubmessageId::GAP => 0x08,
SubmessageId::INFO_TS => 0x09,
SubmessageId::INFO_SRC => 0x0c,
SubmessageId::INFO_REPLY_IP4 => 0x0d,
SubmessageId::INFO_DST => 0x0e,
SubmessageId::INFO_REPLY => 0x0f,
SubmessageId::NACK_FRAG => 0x12,
SubmessageId::HEARTBEAT_FRAG => 0x13,
SubmessageId::DATA => 0x15,
SubmessageId::DATA_FRAG => 0x16,
};
serializer.serialize_u8(val)
}
}
impl serde::Deserialize for SubmessageId {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: serde::Deserializer {
let byte: u8 = try!(serde::Deserialize::deserialize(deserializer));
match byte {
0x01 => Ok(SubmessageId::PAD),
0x06 => Ok(SubmessageId::ACKNACK),
0x07 => Ok(SubmessageId::HEARTBEAT),
0x08 => Ok(SubmessageId::GAP),
0x09 => Ok(SubmessageId::INFO_TS),
0x0c => Ok(SubmessageId::INFO_SRC),
0x0d => Ok(SubmessageId::INFO_REPLY_IP4),
0x0e => Ok(SubmessageId::INFO_DST),
0x0f => Ok(SubmessageId::INFO_REPLY),
0x12 => Ok(SubmessageId::NACK_FRAG),
0x13 => Ok(SubmessageId::HEARTBEAT_FRAG),
0x15 => Ok(SubmessageId::DATA),
0x16 => Ok(SubmessageId::DATA_FRAG),
_ => Err(serde::Error::custom(format!("unknown type {:?}", byte))),
}
}
}
bitflags! {
pub flags SubmessageFlags: u8 {
const LITTLE_ENDIAN = 0x01,
const ACK_NACK_FINAL_FLAG = 0x02,
const DATA_INLINE_QOS = 0x02,
const DATA_DATA = 0x04,
const DATA_KEY = 0x08,
const DATA_FRAG_INLINE_QOS = 0x02,
}
}
impl Serialize for Submessage {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
match self.variant {
SubmessageVariant::InfoTimestamp(ref ts) => {
try!(SubmessageId::INFO_TS.serialize(serializer));
try!(serializer.serialize_u8(0x00));
try!(serializer.serialize_u32(0xFF));
try!(ts.serialize(serializer));
Ok(())
},
SubmessageVariant::InfoSource { protocol_version, vendor_id, guid_prefix } => {
try!(SubmessageId::INFO_SRC.serialize(serializer));
try!(serializer.serialize_u8(0x00));
try!(serializer.serialize_u32(0xFF));
try!(protocol_version.serialize(serializer));
try!(vendor_id.serialize(serializer));
try!(guid_prefix.serialize(serializer));
Ok(())
},
SubmessageVariant::InfoReply { ref unicast_locator_list } => {
try!(SubmessageId::INFO_REPLY.serialize(serializer));
try!(serializer.serialize_u8(0x00));
try!(serializer.serialize_u32(0xFF));
let mut state = try!(serializer.serialize_seq(Some(unicast_locator_list.len())));
for locator in unicast_locator_list {
try!(serializer.serialize_seq_elt(&mut state, locator));
}
Ok(())
}
SubmessageVariant::InfoDestination(guid_prefix) => {
try!(SubmessageId::INFO_DST.serialize(serializer));
try!(serializer.serialize_u8(0x00));
try!(serializer.serialize_u32(0xFF));
try!(guid_prefix.serialize(serializer));
Ok(())
},
SubmessageVariant::AckNack{ reader_id, writer_id, reader_sn_state, count }=> {
try!(SubmessageId::ACKNACK.serialize(serializer));
try!(serializer.serialize_u8(0x00));
try!(serializer.serialize_u32(0xFF));
try!(reader_id.serialize(serializer));
try!(writer_id.serialize(serializer));
try!(reader_sn_state.serialize(serializer));
try!(count.serialize(serializer));
Ok(())
},
SubmessageVariant::Data { reader_id, writer_id, writer_sn , ref serialized_payload } => {
try!(SubmessageId::DATA.serialize(serializer));
try!(serializer.serialize_u8(0x00));
try!(serializer.serialize_u32(0xFF));
try!(reader_id.serialize(serializer));
try!(writer_id.serialize(serializer));
try!(writer_sn.serialize(serializer));
try!(serialized_payload.serialize(serializer));
Ok(())
},
SubmessageVariant::DataFrag { reader_id, writer_id, writer_sn , ref serialized_payload, fragment_start_num, fragments_in_submessage, data_size, fragment_size } => {
try!(SubmessageId::DATA_FRAG.serialize(serializer));
try!(serializer.serialize_u8(0x00));
try!(serializer.serialize_u32(0xFF));
try!(reader_id.serialize(serializer));
try!(writer_id.serialize(serializer));
try!(writer_sn.serialize(serializer));
try!(fragment_start_num.serialize(serializer));
try!(fragments_in_submessage.serialize(serializer));
try!(data_size.serialize(serializer));
try!(fragment_size.serialize(serializer));
try!(serialized_payload.serialize(serializer));
Ok(())
},
SubmessageVariant::Gap { reader_id, writer_id, gap_start, gap_list } => {
try!(SubmessageId::GAP.serialize(serializer));
try!(serializer.serialize_u8(0x00));
try!(serializer.serialize_u32(0xFF));
try!(reader_id.serialize(serializer));
try!(writer_id.serialize(serializer));
try!(gap_start.serialize(serializer));
try!(gap_list.serialize(serializer));
Ok(())
}
SubmessageVariant::Heartbeat { reader_id, writer_id, first_sn, last_sn, count } => {
try!(serializer.serialize_u8(0x07));
try!(serializer.serialize_u8(0x00));
try!(serializer.serialize_u32(0xFF));
try!(reader_id.serialize(serializer));
try!(writer_id.serialize(serializer));
try!(first_sn.serialize(serializer));
try!(last_sn.serialize(serializer));
try!(count.serialize(serializer));
Ok(())
}
SubmessageVariant::HeartbeatFrag{ reader_id, writer_id, writer_sn, last_fragment_number, count } => {
try!(SubmessageId::HEARTBEAT_FRAG.serialize(serializer));
try!(serializer.serialize_u8(0x00));
try!(serializer.serialize_u32(0xFF));
try!(reader_id.serialize(serializer));
try!(writer_id.serialize(serializer));
try!(writer_sn.serialize(serializer));
try!(last_fragment_number.serialize(serializer));
try!(count.serialize(serializer));
Ok(())
},
SubmessageVariant::NackFrag{ reader_id, writer_id, writer_sn, fragment_number_state, count } => {
try!(SubmessageId::NACK_FRAG.serialize(serializer));
try!(serializer.serialize_u8(0x00));
try!(serializer.serialize_u32(0xFF));
try!(reader_id.serialize(serializer));
try!(writer_id.serialize(serializer));
try!(writer_sn.serialize(serializer));
try!(fragment_number_state.serialize(serializer));
try!(count.serialize(serializer));
Ok(())
},
SubmessageVariant::Pad => {
try!(SubmessageId::PAD.serialize(serializer));
try!(serializer.serialize_u8(0x00));
try!(serializer.serialize_u32(0xFF));
Ok(())
}
}
}
}