use std::{io, io::Write, marker::PhantomData};
use serde::{ser, Serialize};
use bytes::Bytes;
use byteorder::{BigEndian, ByteOrder, LittleEndian, WriteBytesExt};
use crate::{
dds::{
adapters::{no_key, with_key},
key::Keyed,
},
RepresentationIdentifier,
};
struct CountingWrite<W: io::Write> {
writer: W,
bytes_written: usize,
}
impl<W> CountingWrite<W>
where
W: io::Write,
{
pub fn new(w: W) -> Self {
Self {
writer: w,
bytes_written: 0,
}
}
pub fn count(&self) -> usize {
self.bytes_written
}
}
impl<W> io::Write for CountingWrite<W>
where
W: io::Write,
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match self.writer.write(buf) {
Ok(c) => {
self.bytes_written += c;
Ok(c)
}
e => e,
}
}
fn flush(&mut self) -> io::Result<()> {
self.writer.flush()
}
}
pub struct CDRSerializerAdapter<D, BO = LittleEndian>
where
BO: ByteOrder,
{
phantom: PhantomData<D>,
ghost: PhantomData<BO>,
}
impl<D, BO> no_key::SerializerAdapter<D> for CDRSerializerAdapter<D, BO>
where
D: Serialize,
BO: ByteOrder,
{
type Error = Error;
fn output_encoding() -> RepresentationIdentifier {
RepresentationIdentifier::CDR_LE
}
fn to_bytes(value: &D) -> Result<Bytes> {
let size_estimate = std::mem::size_of_val(value) * 2; let mut buffer: Vec<u8> = Vec::with_capacity(size_estimate);
to_writer::<D, BO, &mut Vec<u8>>(&mut buffer, value)?;
Ok(Bytes::from(buffer))
}
}
impl<D, BO> with_key::SerializerAdapter<D> for CDRSerializerAdapter<D, BO>
where
D: Keyed + Serialize,
<D as Keyed>::K: Serialize,
BO: ByteOrder,
{
fn key_to_bytes(value: &D::K) -> Result<Bytes> {
let size_estimate = std::mem::size_of_val(value) * 2; let mut buffer: Vec<u8> = Vec::with_capacity(size_estimate);
to_writer::<D::K, BO, &mut Vec<u8>>(&mut buffer, value)?;
Ok(Bytes::from(buffer))
}
}
pub struct CdrSerializer<W, BO>
where
W: io::Write,
{
writer: CountingWrite<W>, phantom: PhantomData<BO>, }
impl<W, BO> CdrSerializer<W, BO>
where
BO: ByteOrder,
W: io::Write,
{
pub fn new(w: W) -> Self {
Self {
writer: CountingWrite::new(w),
phantom: PhantomData,
}
}
fn calculate_padding_need_and_write_padding(&mut self, alignment: usize) -> Result<()> {
let modulo = self.writer.count() % alignment;
if modulo != 0 {
let padding_need: usize = alignment - modulo;
for _x in 0..padding_need {
self.writer.write_u8(0)?;
}
}
Ok(())
}
} pub fn to_writer<T, BO, W>(writer: W, value: &T) -> Result<()>
where
T: Serialize,
BO: ByteOrder,
W: io::Write,
{
value.serialize(&mut CdrSerializer::<W, BO>::new(writer))
}
pub fn to_writer_endian<T, W>(
writer: W,
value: &T,
encoding: RepresentationIdentifier,
) -> Result<()>
where
T: Serialize,
W: io::Write,
{
match encoding {
RepresentationIdentifier::CDR_LE => {
value.serialize(&mut CdrSerializer::<W, LittleEndian>::new(writer))
}
_ => value.serialize(&mut CdrSerializer::<W, BigEndian>::new(writer)),
}
}
#[cfg(test)]
pub(crate) fn to_little_endian_binary<T>(value: &T) -> Result<Vec<u8>>
where
T: Serialize,
{
to_bytes::<T, LittleEndian>(value)
}
#[cfg(test)]
fn to_big_endian_binary<T>(value: &T) -> Result<Vec<u8>>
where
T: Serialize,
{
to_bytes::<T, BigEndian>(value)
}
pub(crate) fn to_bytes<T, BO>(value: &T) -> Result<Vec<u8>>
where
T: Serialize,
BO: ByteOrder,
{
let mut buffer: Vec<u8> = Vec::with_capacity(std::mem::size_of_val(value) * 2);
to_writer::<T, BO, &mut Vec<u8>>(&mut buffer, value)?;
Ok(buffer)
}
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("CDR serialization requires sequence length to be specified at the start.")]
SequenceLengthUnknown,
#[error("Serde says:{0}")]
Serde(String),
#[error("std::io::Error {0}")]
Io(#[from] std::io::Error),
}
impl ser::Error for Error {
fn custom<T: std::fmt::Display>(msg: T) -> Self {
Self::Serde(msg.to_string())
}
}
impl<'a, W, BO> ser::Serializer for &'a mut CdrSerializer<W, BO>
where
BO: ByteOrder,
W: io::Write,
{
type Ok = ();
type Error = Error;
type SerializeSeq = Self;
type SerializeTuple = Self;
type SerializeTupleStruct = Self;
type SerializeTupleVariant = Self;
type SerializeMap = Self;
type SerializeStruct = Self;
type SerializeStructVariant = Self;
fn serialize_bool(self, v: bool) -> Result<()> {
if v {
self.writer.write_u8(1u8)?;
} else {
self.writer.write_u8(0u8)?;
}
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<()> {
self.writer.write_u8(v)?;
Ok(())
}
fn serialize_u16(self, v: u16) -> Result<()> {
self.calculate_padding_need_and_write_padding(2)?;
self.writer.write_u16::<BO>(v)?;
Ok(())
}
fn serialize_u32(self, v: u32) -> Result<()> {
self.calculate_padding_need_and_write_padding(4)?;
self.writer.write_u32::<BO>(v)?;
Ok(())
}
fn serialize_u64(self, v: u64) -> Result<()> {
self.calculate_padding_need_and_write_padding(8)?;
self.writer.write_u64::<BO>(v)?;
Ok(())
}
fn serialize_u128(self, v: u128) -> Result<()> {
self.calculate_padding_need_and_write_padding(16)?;
self.writer.write_u128::<BO>(v)?;
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<()> {
self.writer.write_i8(v)?;
Ok(())
}
fn serialize_i16(self, v: i16) -> Result<()> {
self.calculate_padding_need_and_write_padding(2)?;
self.writer.write_i16::<BO>(v)?;
Ok(())
}
fn serialize_i32(self, v: i32) -> Result<()> {
self.calculate_padding_need_and_write_padding(4)?;
self.writer.write_i32::<BO>(v)?;
Ok(())
}
fn serialize_i64(self, v: i64) -> Result<()> {
self.calculate_padding_need_and_write_padding(8)?;
self.writer.write_i64::<BO>(v)?;
Ok(())
}
fn serialize_f32(self, v: f32) -> Result<()> {
self.calculate_padding_need_and_write_padding(4)?;
self.writer.write_f32::<BO>(v)?;
Ok(())
}
fn serialize_f64(self, v: f64) -> Result<()> {
self.calculate_padding_need_and_write_padding(8)?;
self.writer.write_f64::<BO>(v)?;
Ok(())
}
fn serialize_char(self, v: char) -> Result<()> {
self.serialize_u32(v as u32)?;
Ok(())
}
fn serialize_str(self, v: &str) -> Result<()> {
let byte_count: u32 = v.as_bytes().len() as u32 + 1;
self.serialize_u32(byte_count)?; self.writer.write_all(v.as_bytes())?;
self.writer.write_u8(0)?; Ok(())
}
fn serialize_bytes(self, v: &[u8]) -> Result<()> {
self.writer.write_all(v)?;
Ok(())
}
fn serialize_none(self) -> Result<()> {
self.serialize_u32(0) }
fn serialize_some<T>(self, t: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.serialize_u32(1)?; t.serialize(self)?;
Ok(())
}
fn serialize_unit(self) -> Result<()> {
Ok(())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
self.serialize_unit()
}
fn serialize_unit_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
) -> Result<()> {
self.serialize_u32(variant_index)
}
fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
value: &T,
) -> Result<()>
where
T: ?Sized + Serialize,
{
self.serialize_u32(variant_index)?;
value.serialize(self)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
match len {
None => Err(Error::SequenceLengthUnknown),
Some(elem_count) => {
self.serialize_u32(elem_count as u32)?;
Ok(self)
}
} } fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
Ok(self)
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct> {
Ok(self)
}
fn serialize_tuple_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant> {
self.serialize_u32(variant_index)?;
Ok(self)
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
match len {
None => Err(Error::SequenceLengthUnknown),
Some(elem_count) => {
self.serialize_u32(elem_count as u32)?;
Ok(self)
}
} }
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
Ok(self)
}
fn serialize_struct_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant> {
self.serialize_u32(variant_index)?;
Ok(self)
}
}
impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeSeq for &'a mut CdrSerializer<W, BO> {
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeTuple for &'a mut CdrSerializer<W, BO> {
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeTupleStruct for &'a mut CdrSerializer<W, BO> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeTupleVariant for &'a mut CdrSerializer<W, BO> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeMap for &'a mut CdrSerializer<W, BO> {
type Ok = ();
type Error = Error;
fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
key.serialize(&mut **self)
}
fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeStruct for &'a mut CdrSerializer<W, BO> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)?;
Ok(())
}
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeStructVariant for &'a mut CdrSerializer<W, BO> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)?;
Ok(())
}
fn end(self) -> Result<()> {
Ok(())
}
}
#[cfg(test)]
mod tests {
use log::info;
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use crate::serialization::{
cdr_deserializer::deserialize_from_little_endian,
cdr_serializer::{to_big_endian_binary, to_little_endian_binary},
};
#[test]
fn cdr_serialize_and_deserialize_sequence_of_structs() {
#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct MyType {
first_value: i16,
second: u8,
}
impl MyType {
pub fn new(first_value: i16, second: u8) -> Self {
Self {
first_value,
second,
}
}
}
let sequence_of_structs: Vec<MyType> =
vec![MyType::new(1, 23), MyType::new(2, 34), MyType::new(-3, 45)];
let serialized = to_little_endian_binary(&sequence_of_structs).unwrap();
let deserialized: Vec<MyType> = deserialize_from_little_endian(&serialized).unwrap();
info!("deserialized {:?}", deserialized);
info!("serialized {:?}", serialized);
assert_eq!(deserialized, sequence_of_structs);
}
#[test]
fn cdr_serialize_enum() {
#[derive(Debug, Eq, PartialEq, Serialize_repr, Deserialize_repr)]
#[repr(u32)]
pub enum MyEnumeration {
First,
Second,
Third,
SevenHundredth = 700,
}
let enum_object_1 = MyEnumeration::First;
let enum_object_2 = MyEnumeration::Second;
let enum_object_3 = MyEnumeration::Third;
let enum_object_7 = MyEnumeration::SevenHundredth;
let serialized_1 = to_little_endian_binary(&enum_object_1).unwrap();
info!("{:?}", serialized_1);
let u32_value_1: u32 = deserialize_from_little_endian(&serialized_1).unwrap();
let deserialized_1: MyEnumeration = deserialize_from_little_endian(&serialized_1).unwrap();
info!("Deserialized 1: {:?}", deserialized_1);
assert_eq!(deserialized_1, enum_object_1);
assert_eq!(u32_value_1, 0);
let serialized_2 = to_little_endian_binary(&enum_object_2).unwrap();
info!("{:?}", serialized_2);
let u32_value_2: u32 = deserialize_from_little_endian(&serialized_2).unwrap();
let deserialized_2: MyEnumeration = deserialize_from_little_endian(&serialized_2).unwrap();
info!("Deserialized 2: {:?}", deserialized_2);
assert_eq!(deserialized_2, enum_object_2);
assert_eq!(u32_value_2, 1);
let serialized_3 = to_little_endian_binary(&enum_object_3).unwrap();
info!("{:?}", serialized_3);
let deserialized_3: MyEnumeration = deserialize_from_little_endian(&serialized_3).unwrap();
let u32_value_3: u32 = deserialize_from_little_endian(&serialized_3).unwrap();
info!("Deserialized 3: {:?}", deserialized_3);
assert_eq!(deserialized_3, enum_object_3);
assert_eq!(u32_value_3, 2);
let serialized_7 = to_little_endian_binary(&enum_object_7).unwrap();
info!("{:?}", serialized_7);
let deserialized_7: MyEnumeration = deserialize_from_little_endian(&serialized_7).unwrap();
let u32_value_7: u32 = deserialize_from_little_endian(&serialized_7).unwrap();
info!("Deserialized 7: {:?}", deserialized_7);
assert_eq!(deserialized_7, enum_object_7);
assert_eq!(u32_value_7, 700);
}
#[test]
fn cdr_serialization_example() {
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
struct Example {
a: u32,
b: [u8; 4],
}
let o = Example {
a: 1,
b: [b'a', b'b', b'c', b'd'],
};
let expected_serialization_le: Vec<u8> = vec![0x01, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64];
let expected_serialization_be: Vec<u8> = vec![0x00, 0x00, 0x00, 0x01, 0x61, 0x62, 0x63, 0x64];
let serialized_le = to_little_endian_binary(&o).unwrap();
let serialized_be = to_big_endian_binary(&o).unwrap();
assert_eq!(serialized_le, expected_serialization_le);
assert_eq!(serialized_be, expected_serialization_be);
}
#[test]
fn cdr_serialization_test() {
#[derive(Serialize)]
struct MyType {
first_value: u8,
second_value: i8,
third_value: i32,
fourth_value: u64,
fifth: bool,
}
let micky_mouse = MyType {
first_value: 1,
second_value: -1,
third_value: 23,
fourth_value: 3434343,
fifth: true,
};
let serialized = to_little_endian_binary(&micky_mouse).unwrap();
let expected: Vec<u8> = vec![
0x01, 0xff, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x67, 0x67, 0x34, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01,
];
assert_eq!(expected, serialized);
}
#[test]
fn cdr_serialization_char() {
#[derive(Serialize)]
struct MyType {
first_value: u8,
second: u8,
third: u8,
}
let micky_mouse = MyType {
first_value: b'a',
second: b'b',
third: b'\xE4', };
let serialized = to_little_endian_binary(&micky_mouse).unwrap();
let expected: Vec<u8> = vec![0x61, 0x62, 0xe4];
assert_eq!(expected, serialized);
}
#[test]
fn cdr_serialization_string() {
#[derive(Serialize)]
struct MyType<'a> {
first_value: &'a str,
}
let micky_mouse = MyType {
first_value: "BLUE",
};
let serialized = to_little_endian_binary(&micky_mouse).unwrap();
let expected: Vec<u8> = vec![0x05, 0x00, 0x00, 0x00, 0x42, 0x4c, 0x55, 0x45, 0x00];
assert_eq!(expected, serialized);
}
#[test]
fn cdr_serialization_little() {
let number: u16 = 60000;
let le = to_little_endian_binary(&number).unwrap();
let be = to_big_endian_binary(&number).unwrap();
assert_ne!(le, be);
}
#[test]
fn cdr_serialize_seq() {
#[derive(Serialize)]
struct MyType {
first_value: Vec<i32>,
}
let micky_mouse = MyType {
first_value: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 123123],
};
let serialized = to_little_endian_binary(&micky_mouse).unwrap();
let expected: Vec<u8> = vec![
0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xf3,
0xe0, 0x01, 0x00,
];
assert_eq!(expected, serialized);
}
}