use crate::messages::submessages::submessage_elements::parameter_list::ParameterList;
use crate::messages::submessages::submessage_elements::serialized_payload::SerializedPayload;
use crate::messages::submessages::submessages::*;
use crate::structure::guid::EntityId;
use crate::structure::sequence_number::SequenceNumber;
use speedy::{Readable, Writable, Context, Writer, Error};
use enumflags2::BitFlags;
use std::io;
#[derive(Debug, PartialEq, Clone)]
pub struct Data {
pub reader_id: EntityId,
pub writer_id: EntityId,
pub writer_sn: SequenceNumber,
pub inline_qos: Option<ParameterList>,
pub serialized_payload: Option<SerializedPayload>,
}
impl Data {
pub fn deserialize_data(buffer: &[u8], flags: BitFlags<DATA_Flags>) -> io::Result<Data> {
let mut cursor = io::Cursor::new(buffer);
let endianness = endianness_flag(flags.bits());
let map_speedy_err = |p: Error| io::Error::new(io::ErrorKind::Other, p);
let _extra_flags =
u16::read_from_stream_with_ctx(endianness, &mut cursor).map_err(map_speedy_err)?;
let octets_to_inline_qos =
u16::read_from_stream_with_ctx(endianness, &mut cursor).map_err(map_speedy_err)?;
let reader_id =
EntityId::read_from_stream_with_ctx(endianness, &mut cursor).map_err(map_speedy_err)?;
let writer_id =
EntityId::read_from_stream_with_ctx(endianness, &mut cursor).map_err(map_speedy_err)?;
let sequence_number =
SequenceNumber::read_from_stream_with_ctx(endianness, &mut cursor).map_err(map_speedy_err)?;
let expect_qos = flags.contains(DATA_Flags::InlineQos);
let expect_data = flags.contains(DATA_Flags::Data) || flags.contains(DATA_Flags::Key);
let rtps_v23_data_header_size: u16 = 16;
let extra_octets = octets_to_inline_qos - rtps_v23_data_header_size;
cursor.set_position(cursor.position() + extra_octets as u64);
let parameter_list = if expect_qos {
Some(
ParameterList::read_from_stream_with_ctx(endianness, &mut cursor)
.map_err(map_speedy_err)?,
)
} else {
None
};
let payload = if expect_data {
Some(SerializedPayload::from_bytes(
&buffer[cursor.position() as usize..],
)?)
} else {
None
};
Ok(Data {
reader_id,
writer_id,
writer_sn: sequence_number,
inline_qos: parameter_list,
serialized_payload: payload,
})
}
}
impl<C: Context> Writable<C> for Data {
fn write_to<'a, T: ?Sized + Writer<C>>(&'a self, writer: &mut T) -> Result<(), C::Error> {
writer.write_u16(0)?;
writer.write_u16(16)?;
writer.write_value(&self.reader_id)?;
writer.write_value(&self.writer_id)?;
writer.write_value(&self.writer_sn)?;
if let Some(inline_qos) = self.inline_qos.as_ref() {
writer.write_value(inline_qos)?;
}
if let Some(serialized_payload) = self.serialized_payload.as_ref() {
writer.write_value(serialized_payload)?;
}
Ok(())
}
}