cdr_encoding/
cdr_deserializer.rs

1use std::marker::PhantomData;
2
3#[cfg(test)]
4use byteorder::{BigEndian, LittleEndian};
5use byteorder::{ByteOrder, ReadBytesExt};
6#[allow(unused_imports)]
7use log::{debug, error, info, trace, warn};
8use paste::paste;
9#[cfg(test)]
10use serde::de::DeserializeOwned;
11use serde::de::{
12  self, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, Visitor,
13};
14
15pub use super::error::{Error, Result};
16
17/// Deserializer type for converting CDR data stream to Rust objects.
18///
19/// `CdrDeserializer` is about three machine words of data, so fairly cheap to
20/// create.
21pub struct CdrDeserializer<'i, BO> {
22  phantom: PhantomData<BO>, // This field exists only to provide use for BO. See PhantomData docs.
23  input: &'i [u8],          /* We borrow the input data, therefore we carry lifetime 'i all
24                             * around. */
25  serialized_data_count: usize, // This is to keep track of CDR data alignment requirements.
26}
27
28impl<'de, BO> CdrDeserializer<'de, BO>
29where
30  BO: ByteOrder,
31{
32  pub fn new(input: &'de [u8]) -> CdrDeserializer<'de, BO> {
33    CdrDeserializer::<BO> {
34      phantom: PhantomData,
35      input,
36      serialized_data_count: 0,
37    }
38  }
39
40  /// How many bytes of input stream have been consumed
41  pub fn bytes_consumed(&self) -> usize {
42    self.serialized_data_count
43  }
44
45  /// Read the first bytes in the input.
46  fn next_bytes(&mut self, count: usize) -> Result<&[u8]> {
47    if count <= self.input.len() {
48      let (head, tail) = self.input.split_at(count);
49      self.input = tail;
50      self.serialized_data_count += count;
51      Ok(head)
52    } else {
53      Err(Error::Eof)
54    }
55  }
56
57  /// consume and discard bytes
58  fn remove_bytes_from_input(&mut self, count: usize) -> Result<()> {
59    let _pad = self.next_bytes(count)?;
60    Ok(())
61  }
62
63  fn calculate_padding_count_from_written_bytes_and_remove(
64    &mut self,
65    type_octet_alignment: usize,
66  ) -> Result<()> {
67    let modulo = self.serialized_data_count % type_octet_alignment;
68    if modulo == 0 {
69      Ok(())
70    } else {
71      let padding = type_octet_alignment - modulo;
72      self.remove_bytes_from_input(padding)
73    }
74  }
75}
76
77/// Deserialize an object from `&[u8]` based on a [`serde::Deserialize`]
78/// implementation.
79///
80/// return deserialized object + count of bytes consumed
81pub fn from_bytes<'de, T, BO>(input_bytes: &[u8]) -> Result<(T, usize)>
82where
83  T: serde::Deserialize<'de>,
84  BO: ByteOrder,
85{
86  from_bytes_with::<PhantomData<T>, BO>(input_bytes, PhantomData)
87}
88
89/// Deserialize type based on a [`serde::Deserialize`] implementation.
90///
91/// return deserialized object + count of bytes consumed
92pub fn from_bytes_with<'de, S, BO>(input_bytes: &[u8], decoder: S) -> Result<(S::Value, usize)>
93where
94  S: DeserializeSeed<'de>,
95  BO: ByteOrder,
96{
97  let mut deserializer = CdrDeserializer::<BO>::new(input_bytes);
98  let t = decoder.deserialize(&mut deserializer)?;
99  Ok((t, deserializer.serialized_data_count))
100}
101
102#[cfg(test)]
103pub fn deserialize_from_little_endian<T>(s: &[u8]) -> Result<T>
104where
105  T: DeserializeOwned,
106{
107  let mut deserializer = CdrDeserializer::<LittleEndian>::new(s);
108  T::deserialize(&mut deserializer)
109}
110
111#[cfg(test)]
112pub fn deserialize_from_big_endian<T>(s: &[u8]) -> Result<T>
113where
114  T: DeserializeOwned,
115{
116  let mut deserializer = CdrDeserializer::<BigEndian>::new(s);
117  T::deserialize(&mut deserializer)
118}
119
120/// macro for writing primitive number deserializers. Rust does not allow
121/// declaring a macro inside impl block, so it is here.
122macro_rules! deserialize_multibyte_number {
123  ($num_type:ident) => {
124    paste! {
125      fn [<deserialize_ $num_type>]<V>(self, visitor: V) -> Result<V::Value>
126      where
127        V: Visitor<'de>,
128      {
129        const SIZE :usize = std::mem::size_of::<$num_type>();
130        static_assertions::const_assert!(SIZE > 1); // "multibyte means size must be > 1"
131        self.calculate_padding_count_from_written_bytes_and_remove(SIZE)?;
132        visitor.[<visit_ $num_type>](
133          self.next_bytes(SIZE)?.[<read_ $num_type>]::<BO>().unwrap() )
134      }
135    }
136  };
137}
138
139impl<'de, 'a, 'c, BO> de::Deserializer<'de> for &'a mut CdrDeserializer<'c, BO>
140where
141  BO: ByteOrder,
142{
143  type Error = Error;
144
145  /// CDR serialization is not a self-describing data format, so we cannot
146  /// implement this. Serialized CDR data has no clue to what each bit means,
147  /// so we have to know the structure beforehand.
148  fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
149  where
150    V: Visitor<'de>,
151  {
152    Err(Error::NotSelfDescribingFormat(
153      "CDR cannot deserialize \"any\" type. ".to_string(),
154    ))
155  }
156
157  // 15.3.1.5 Boolean
158  //  Boolean values are encoded as single octets, where TRUE is the value 1, and
159  // FALSE as 0.
160  fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
161  where
162    V: Visitor<'de>,
163  {
164    match self.next_bytes(1)?.first().unwrap() {
165      0 => visitor.visit_bool(false),
166      1 => visitor.visit_bool(true),
167      x => Err(Error::BadBoolean(*x)),
168    }
169  }
170
171  deserialize_multibyte_number!(i16);
172  deserialize_multibyte_number!(i32);
173  deserialize_multibyte_number!(i64);
174
175  deserialize_multibyte_number!(u16);
176  deserialize_multibyte_number!(u32);
177  deserialize_multibyte_number!(u64);
178
179  deserialize_multibyte_number!(f32);
180  deserialize_multibyte_number!(f64);
181
182  // Single-byte numbers have a bit simpler logic: No alignment, no endianness.
183  fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
184  where
185    V: Visitor<'de>,
186  {
187    visitor.visit_i8(self.next_bytes(1)?.read_i8().unwrap())
188  }
189
190  fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
191  where
192    V: Visitor<'de>,
193  {
194    visitor.visit_u8(self.next_bytes(1)?.read_u8().unwrap())
195  }
196
197  /// Since this is Rust, a char is 32-bit Unicode codepoint.
198  fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
199  where
200    V: Visitor<'de>,
201  {
202    self.calculate_padding_count_from_written_bytes_and_remove(4)?;
203    let codepoint = self.next_bytes(4)?.read_u32::<BO>().unwrap();
204    match char::from_u32(codepoint) {
205      Some(c) => visitor.visit_char(c),
206      None => Err(Error::BadChar(codepoint)),
207    }
208  }
209
210  fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
211  where
212    V: Visitor<'de>,
213  {
214    // read string length
215    self.calculate_padding_count_from_written_bytes_and_remove(4)?;
216    let bytes_len = self.next_bytes(4)?.read_u32::<BO>().unwrap() as usize;
217
218    let bytes = self.next_bytes(bytes_len)?; // length includes null terminator
219
220    // Remove the null terminating character
221    let bytes_without_null = match bytes.split_last() {
222      None => {
223        //  This is a hacky "Fix" for IntercomDDS version 01.05 protocol version 2.1.
224        // Where IntercomDDS sends an empty string with no NULL terminator.
225        info!("deserialize_str: Received string with not even a null terminator.");
226        bytes
227      }
228      Some((null_char, contents)) => {
229        if *null_char != 0 {
230          warn!(
231            "deserialize_str: Expected string null terminator, got {:#x} instead.",
232            null_char
233          );
234        }
235        contents
236      }
237    };
238
239    // convert contents without NUL to String and apply visitor
240    std::str::from_utf8(bytes_without_null)
241      .map_err(Error::BadUTF8)
242      .and_then(|s| visitor.visit_str(s))
243
244    // match  {
245    //   Ok(s) => visitor.visit_str(s),
246    //   Err(utf8_err) => Err(Error::BadUTF8(utf8_err)),
247    // }
248  }
249
250  fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
251  where
252    V: Visitor<'de>,
253  {
254    self.deserialize_str(visitor)
255  }
256
257  // Byte strings
258
259  fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
260  where
261    V: Visitor<'de>,
262  {
263    self.deserialize_seq(visitor)
264  }
265
266  fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
267  where
268    V: Visitor<'de>,
269  {
270    self.deserialize_seq(visitor)
271  }
272
273  fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
274  where
275    V: Visitor<'de>,
276  {
277    self.calculate_padding_count_from_written_bytes_and_remove(4)?;
278    let enum_tag = self.next_bytes(4)?.read_u32::<BO>().unwrap();
279    match enum_tag {
280      0 => visitor.visit_none(),
281      1 => visitor.visit_some(self),
282      wtf => Err(Error::BadOption(wtf)),
283    }
284  }
285
286  fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
287  where
288    V: Visitor<'de>,
289  {
290    // Unit data is not put on wire, to match behavior with cdr_serializer
291    visitor.visit_unit()
292  }
293
294  fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
295  where
296    V: Visitor<'de>,
297  {
298    self.deserialize_unit(visitor) // This means a named type, which has no
299                                   // data.
300  }
301
302  fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
303  where
304    V: Visitor<'de>,
305  {
306    visitor.visit_newtype_struct(self)
307  }
308
309  /// Sequences are encoded as an unsigned long value, followed by the elements
310  /// of the
311  // sequence. The initial unsigned long contains the number of elements in the
312  // sequence. The elements of the sequence are encoded as specified for their
313  // type.
314  fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
315  where
316    V: Visitor<'de>,
317  {
318    self.calculate_padding_count_from_written_bytes_and_remove(4)?;
319    let element_count = self.next_bytes(4)?.read_u32::<BO>().unwrap() as usize;
320    visitor.visit_seq(SequenceHelper::new(self, element_count))
321  }
322
323  // if sequence is fixed length array then number of elements is not included
324  fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
325  where
326    V: Visitor<'de>,
327  {
328    visitor.visit_seq(SequenceHelper::new(self, len))
329  }
330
331  fn deserialize_tuple_struct<V>(
332    self,
333    _name: &'static str,
334    len: usize,
335    visitor: V,
336  ) -> Result<V::Value>
337  where
338    V: Visitor<'de>,
339  {
340    visitor.visit_seq(SequenceHelper::new(self, len))
341  }
342
343  fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
344  where
345    V: Visitor<'de>,
346  {
347    self.calculate_padding_count_from_written_bytes_and_remove(4)?;
348    let element_count = self.next_bytes(4)?.read_u32::<BO>().unwrap() as usize;
349    visitor.visit_map(SequenceHelper::new(self, element_count))
350  }
351
352  fn deserialize_struct<V>(
353    self,
354    _name: &'static str,
355    fields: &'static [&'static str],
356    visitor: V,
357  ) -> Result<V::Value>
358  where
359    V: Visitor<'de>,
360  {
361    visitor.visit_seq(SequenceHelper::new(self, fields.len()))
362  }
363
364  /// Enum values are encoded as unsigned longs. (u32)
365  /// The numeric values associated with enum identifiers are determined by the
366  /// order in which the identifiers appear in the enum declaration. The first
367  /// enum identifier has the numeric value zero (0). Successive enum
368  /// identifiers take ascending numeric values, in order of declaration from
369  /// left to right.
370  fn deserialize_enum<V>(
371    self,
372    _name: &'static str,
373    _variants: &'static [&'static str],
374    visitor: V,
375  ) -> Result<V::Value>
376  where
377    V: Visitor<'de>,
378  {
379    self.calculate_padding_count_from_written_bytes_and_remove(4)?;
380    visitor.visit_enum(EnumerationHelper::<BO>::new(self))
381  }
382
383  /// An identifier in Serde is the type that identifies a field of a struct or
384  /// the variant of an enum. In JSON, struct fields and enum variants are
385  /// represented as strings. In other formats they may be represented as
386  /// numeric indices.
387  fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
388  where
389    V: Visitor<'de>,
390  {
391    self.deserialize_u32(visitor)
392  }
393
394  fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
395  where
396    V: Visitor<'de>,
397  {
398    self.deserialize_any(visitor)
399  }
400
401  fn is_human_readable(&self) -> bool {
402    false
403  }
404}
405
406// ----------------------------------------------------------
407
408struct EnumerationHelper<'a, 'i: 'a, BO> {
409  de: &'a mut CdrDeserializer<'i, BO>,
410}
411
412impl<'a, 'i, BO> EnumerationHelper<'a, 'i, BO>
413where
414  BO: ByteOrder,
415{
416  fn new(de: &'a mut CdrDeserializer<'i, BO>) -> Self {
417    EnumerationHelper::<BO> { de }
418  }
419}
420
421impl<'de, 'a, BO> EnumAccess<'de> for EnumerationHelper<'a, '_, BO>
422where
423  BO: ByteOrder,
424{
425  type Error = Error;
426  type Variant = Self;
427
428  fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
429  where
430    V: DeserializeSeed<'de>,
431  {
432    // preceding deserialize_enum aligned to 4
433    let enum_tag = self.de.next_bytes(4)?.read_u32::<BO>().unwrap();
434    let val: Result<_> = seed.deserialize(enum_tag.into_deserializer());
435    Ok((val?, self))
436  }
437}
438
439// ----------------------------------------------------------
440
441impl<'de, 'a, BO> VariantAccess<'de> for EnumerationHelper<'a, '_, BO>
442where
443  BO: ByteOrder,
444{
445  type Error = Error;
446
447  fn unit_variant(self) -> Result<()> {
448    Ok(())
449  }
450
451  fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
452  where
453    T: DeserializeSeed<'de>,
454  {
455    seed.deserialize(self.de)
456  }
457
458  fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value>
459  where
460    V: Visitor<'de>,
461  {
462    de::Deserializer::deserialize_tuple(self.de, len, visitor)
463  }
464
465  fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
466  where
467    V: Visitor<'de>,
468  {
469    de::Deserializer::deserialize_tuple(self.de, fields.len(), visitor)
470  }
471}
472
473// ----------------------------------------------------------
474
475struct SequenceHelper<'a, 'i: 'a, BO> {
476  de: &'a mut CdrDeserializer<'i, BO>,
477  element_counter: usize,
478  expected_count: usize,
479}
480
481impl<'a, 'i, BO> SequenceHelper<'a, 'i, BO> {
482  fn new(de: &'a mut CdrDeserializer<'i, BO>, expected_count: usize) -> Self {
483    SequenceHelper {
484      de,
485      element_counter: 0,
486      expected_count,
487    }
488  }
489}
490
491// `SeqAccess` is provided to the `Visitor` to give it the ability to iterate
492// through elements of the sequence.
493impl<'a, 'de, BO> SeqAccess<'de> for SequenceHelper<'a, '_, BO>
494where
495  BO: ByteOrder,
496{
497  type Error = Error;
498
499  fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
500  where
501    T: DeserializeSeed<'de>,
502  {
503    if self.element_counter == self.expected_count {
504      Ok(None)
505    } else {
506      self.element_counter += 1;
507      seed.deserialize(&mut *self.de).map(Some)
508    }
509  }
510}
511
512// `MapAccess` is provided to the `Visitor` to give it the ability to iterate
513// through entries of the map.
514impl<'de, 'a, BO> MapAccess<'de> for SequenceHelper<'a, '_, BO>
515where
516  BO: ByteOrder,
517{
518  type Error = Error;
519
520  fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
521  where
522    K: DeserializeSeed<'de>,
523  {
524    if self.element_counter == self.expected_count {
525      Ok(None)
526    } else {
527      self.element_counter += 1;
528      seed.deserialize(&mut *self.de).map(Some)
529    }
530  }
531
532  fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
533  where
534    V: DeserializeSeed<'de>,
535  {
536    // Deserialize a map value.
537    seed.deserialize(&mut *self.de)
538  }
539}
540
541#[cfg(test)]
542#[allow(clippy::needless_pass_by_value)]
543mod tests {
544  use byteorder::{BigEndian, LittleEndian};
545  use log::info;
546  use serde::{Deserialize, Serialize};
547  use serde_repr::{Deserialize_repr, Serialize_repr};
548  use test_case::test_case;
549
550  use crate::{
551    cdr_deserializer::{deserialize_from_big_endian, deserialize_from_little_endian},
552    cdr_serializer::to_vec,
553    from_bytes,
554  };
555
556  #[test]
557  fn cdr_deserialization_struct() {
558    //IDL
559    /*
560    struct MyType
561    {
562     octet first;
563    octet second;
564    long third;
565    unsigned long long fourth;
566    boolean fifth;
567    float sixth;
568    boolean seventh;
569    sequence<long> eighth;
570    sequence<octet> ninth;
571    sequence<short> tenth;
572    sequence<long long> eleventh;
573    unsigned short twelve [3];
574    string thirteen;
575    };
576    */
577
578    /*
579
580      ser_var.first(1);
581    ser_var.second(-3);
582    ser_var.third(-5000);
583    ser_var.fourth(1234);
584    ser_var.fifth(true);
585    ser_var.sixth(-6.6);
586    ser_var.seventh(true);
587    ser_var.eighth({1,2});
588    ser_var.ninth({1});
589    ser_var.tenth({5,-4,3,-2,1});
590    ser_var.eleventh({});
591    ser_var.twelve({3,2,1});
592    ser_var.thirteen("abc");
593
594      */
595    #[derive(Serialize, Deserialize, Debug, PartialEq)]
596    struct MyType {
597      first_value: u8,
598      second_value: i8,
599      third_value: i32,
600      fourth_value: u64,
601      fifth: bool,
602      sixth: f32,
603      seventh: bool,
604      eighth: Vec<i32>,
605      ninth: Vec<u8>,
606      tenth: Vec<i16>,
607      eleventh: Vec<i64>,
608      twelve: [u16; 3],
609      thirteen: String,
610    }
611
612    let micky_mouse = MyType {
613      first_value: 1,
614      second_value: -3,
615      third_value: -5000,
616      fourth_value: 1234u64,
617      fifth: true,
618      sixth: -6.6f32,
619      seventh: true,
620      eighth: vec![1, 2],
621      ninth: vec![1],
622      tenth: vec![5, -4, 3, -2, 1],
623      eleventh: vec![],
624      twelve: [3, 2, 1],
625      thirteen: "abc".to_string(),
626    };
627
628    let expected_serialized_result: Vec<u8> = vec![
629      0x01, 0xfd, 0x00, 0x00, 0x78, 0xec, 0xff, 0xff, 0xd2, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
630      0x00, 0x01, 0x00, 0x00, 0x00, 0x33, 0x33, 0xd3, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
631      0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
632      0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfe, 0xff,
633      0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00,
634      0x00, 0x04, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x00,
635    ];
636
637    let serialized = to_vec::<MyType, LittleEndian>(&micky_mouse).unwrap();
638
639    for x in 0..expected_serialized_result.len() {
640      if expected_serialized_result[x] != serialized[x] {
641        info!("index: {}", x);
642      }
643    }
644    assert_eq!(serialized, expected_serialized_result);
645    info!("serialization successful!");
646
647    let built: MyType = deserialize_from_little_endian(&expected_serialized_result).unwrap();
648    assert_eq!(built, micky_mouse);
649    info!("deserialized: {:?}", built);
650  }
651
652  #[test]
653
654  fn cdr_deserialization_user_defined_data() {
655    // look this example https://www.omg.org/spec/DDSI-RTPS/2.3/PDF
656    // 10.7 Example for User-defined Topic Data
657    #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
658    struct ShapeType {
659      color: String,
660      x: i32,
661      y: i32,
662      size: i32,
663    }
664
665    let message = ShapeType {
666      color: "BLUE".to_string(),
667      x: 34,
668      y: 100,
669      size: 24,
670    };
671
672    let expected_serialized_result: Vec<u8> = vec![
673      0x05, 0x00, 0x00, 0x00, 0x42, 0x4c, 0x55, 0x45, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
674      0x00, 0x64, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
675    ];
676
677    let serialized = to_vec::<ShapeType, LittleEndian>(&message).unwrap();
678    assert_eq!(serialized, expected_serialized_result);
679    let deserialized_message: ShapeType = deserialize_from_little_endian(&serialized).unwrap();
680    assert_eq!(deserialized_message, message);
681  }
682
683  #[test]
684
685  fn cdr_deserialization_serialization_topic_name() {
686    // look this example https://www.omg.org/spec/DDSI-RTPS/2.3/PDF
687    // 10.6 Example for Built-in Endpoint Data
688    // this is just CRD topic name strings
689
690    // TODO what about padding??
691    let received_cdr_string: Vec<u8> = vec![
692      0x07, 0x00, 0x00, 0x00, 0x053, 0x71, 0x75, 0x61, 0x72, 0x65, 0x00, // 0x00,
693    ];
694
695    let deserialized_message: String =
696      deserialize_from_little_endian(&received_cdr_string).unwrap();
697    info!("{:?}", deserialized_message);
698    assert_eq!("Square", deserialized_message);
699
700    let received_cdr_string2: Vec<u8> = vec![
701      0x0A, 0x00, 0x00, 0x00, 0x53, 0x68, 0x61, 0x70, 0x65, 0x54, 0x79, 0x70, 0x65,
702      0x00, // 0x00, 0x00,
703    ];
704
705    let deserialized_message2: String =
706      deserialize_from_little_endian(&received_cdr_string2).unwrap();
707    info!("{:?}", deserialized_message2);
708    assert_eq!("ShapeType", deserialized_message2);
709  }
710
711  #[test]
712  fn cdr_deserialization_example_struct() {
713    // look this example https://www.omg.org/spec/DDSI-RTPS/2.2/PDF
714    // 10.2.2 Example
715
716    #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
717    struct Example {
718      a: u32,
719      b: [u8; 4],
720    }
721
722    let o = Example {
723      a: 1,
724      b: [b'a', b'b', b'c', b'd'],
725    };
726
727    let serialized_le: Vec<u8> = vec![0x01, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64];
728
729    let serialized_be: Vec<u8> = vec![0x00, 0x00, 0x00, 0x01, 0x61, 0x62, 0x63, 0x64];
730
731    let deserialized_le: Example = deserialize_from_little_endian(&serialized_le).unwrap();
732    let deserialized_be: Example = deserialize_from_big_endian(&serialized_be).unwrap();
733    let serialized_o_le = to_vec::<Example, LittleEndian>(&o).unwrap();
734    let serialized_o_be = to_vec::<Example, BigEndian>(&o).unwrap();
735
736    assert_eq!(
737      serialized_o_le,
738      vec![0x01, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64,]
739    );
740
741    assert_eq!(
742      serialized_o_be,
743      vec![0x00, 0x00, 0x00, 0x01, 0x61, 0x62, 0x63, 0x64,]
744    );
745
746    info!("serialization success");
747
748    assert_eq!(deserialized_le, o);
749    assert_eq!(deserialized_be, o);
750    info!("deserialization success");
751  }
752
753  #[test]
754
755  fn cdr_deserialization_serialization_payload_shapes() {
756    // This test uses wireshark captured shapes demo part of serialized message as
757    // received_message.
758    #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
759    struct ShapeType {
760      color: String,
761      x: i32,
762      y: i32,
763      size: i32,
764    }
765    // this message is DataMessages serialized data without encapsulation kind and
766    // encapsulation options
767    let received_message: Vec<u8> = vec![
768      0x04, 0x00, 0x00, 0x00, 0x52, 0x45, 0x44, 0x00, 0x61, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00,
769      0x00, 0x1e, 0x00, 0x00, 0x00,
770    ];
771    let received_message2: Vec<u8> = vec![
772      0x04, 0x00, 0x00, 0x00, 0x52, 0x45, 0x44, 0x00, 0x61, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00,
773      0x00, 0x1e, 0x00, 0x00, 0x00,
774    ];
775
776    let deserialized_message: ShapeType =
777      deserialize_from_little_endian(&received_message).unwrap();
778    info!("{:?}", deserialized_message);
779
780    let serialized_message = to_vec::<ShapeType, LittleEndian>(&deserialized_message).unwrap();
781
782    assert_eq!(serialized_message, received_message2);
783    // assert_eq!(deserialized_message,received_message)
784  }
785
786  #[test]
787
788  fn cdr_deserialization_custom_data_message_from_ros_and_wireshark() {
789    // IDL of message
790    // float64 x
791    // float64 y
792    // float64 heading
793    // float64 v_x
794    // float64 v_y
795    // float64 kappa
796    // string test
797
798    #[derive(Serialize, Deserialize, Debug, PartialEq)]
799    struct MessageType {
800      x: f64,
801      y: f64,
802      heading: f64,
803      v_x: f64,
804      v_y: f64,
805      kappa: f64,
806      test: String,
807    }
808
809    // The serialized form of the message "Toimiiko?" (?) (Finnish for "Working?")
810    let received_message_le: Vec<u8> = vec![
811      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
812      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
813      0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x85, 0xeb, 0x51, 0xb8,
814      0x1e, 0xd5, 0x3f, 0x0a, 0x00, 0x00, 0x00, 0x54, 0x6f, 0x69, 0x6d, 0x69, 0x69, 0x6b, 0x6f,
815      0x3f, 0x00, // 0x00, 0x00,
816    ];
817
818    let value: MessageType = deserialize_from_little_endian(&received_message_le).unwrap();
819    info!("{:?}", value);
820    assert_eq!(value.test, "Toimiiko?");
821  }
822
823  #[derive(Serialize, Deserialize, Debug, PartialEq)]
824  struct InterestingMessage {
825    unbounded_string: String,
826    x: i32,
827    y: i32,
828    shape_size: i32,
829    slide: f32,
830    double_slide: f64,
831    three_short: [u16; 3],
832    four_short: [i16; 4],
833    booleans: Vec<bool>,
834    three_bytes: Vec<u8>,
835  }
836
837  #[derive(Serialize, Deserialize, Debug, PartialEq)]
838  enum BigEnum {
839    Interesting(InterestingMessage),
840    Boring,
841    Something { x: f32, y: f32 },
842  }
843
844  #[test]
845  fn cdr_deserialization_custom_type() {
846    // IDL Definition of message:
847    /*struct InterestingMessage
848    {
849    string unbounded_string;
850      long x;
851      long y;
852      long shape_size;
853      float slide;
854      double double_slide;
855      unsigned short three_short [3];
856      short four_short [4];
857      sequence<boolean> booleans;
858      sequence<octet,3> three_bytes;
859    };
860    */
861
862    // values put to serialization message with eprosima fastbuffers
863    /*
864      ser_var.unbounded_string("Here is a fairly long text");
865      ser_var.x(1);
866      ser_var.x(2);
867      ser_var.y(-3);
868      ser_var.shape_size(-4);
869      ser_var.slide(5.5);
870      ser_var.double_slide(-6.6);
871      std::array<uint16_t, 3> foo  = {1,2,3};
872      ser_var.three_short(foo);
873      std::array<int16_t, 4>  faa = {1,-2,-3,4};
874      ser_var.four_short(faa);
875      ser_var.booleans({true,false,true});
876      ser_var.three_bytes({23,0,2});
877    */
878
879    let value = InterestingMessage {
880      unbounded_string: "Tassa on aika pitka teksti".to_string(), /* Finnish for "Here us a
881                                                                   * fairly long text" */
882      x: 2,
883      y: -3,
884      shape_size: -4,
885      slide: 5.5,
886      double_slide: -6.6,
887      three_short: [1, 2, 3],
888      four_short: [1, -2, -3, 4],
889      booleans: vec![true, false, true],
890      three_bytes: [23, 0, 2].to_vec(),
891    };
892
893    const DATA: &[u8] = &[
894      0x1b, 0x00, 0x00, 0x00, 0x54, 0x61, 0x73, 0x73, 0x61, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x69,
895      0x6b, 0x61, 0x20, 0x70, 0x69, 0x74, 0x6b, 0x61, 0x20, 0x74, 0x65, 0x6b, 0x73, 0x74, 0x69,
896      0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x00,
897      0x00, 0xb0, 0x40, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x1a, 0xc0, 0x01, 0x00, 0x02, 0x00,
898      0x03, 0x00, 0x01, 0x00, 0xfe, 0xff, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
899      0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x02,
900    ];
901
902    let serialization_result_le = to_vec::<InterestingMessage, LittleEndian>(&value).unwrap();
903
904    assert_eq!(serialization_result_le, DATA);
905    info!("serialization success!");
906    let deserialization_result: InterestingMessage = deserialize_from_little_endian(DATA).unwrap();
907
908    info!("{:?}", deserialization_result);
909  }
910
911  #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
912  enum SomeTupleEnum {
913    A(i32),
914    B(i32),
915    C(i32),
916  }
917
918  #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
919  enum MixedEnum {
920    A(i32),
921    B { value: i32 },
922    C(i32, i32),
923  }
924
925  #[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
926  #[repr(i8)]
927  pub enum GoalStatusEnum {
928    Unknown = 0, // Let's use this also for "New"
929    Accepted = 1,
930    Executing = 2,
931    Canceling = 3,
932    Succeeded = 4,
933    Canceled = 5,
934    Aborted = 6,
935  }
936
937  #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
938  struct AlignMe {
939    some_bytes: [u8; 4],
940    status: i8,
941  }
942
943  #[test_case(35_u8 ; "u8")]
944  #[test_case(35_u16 ; "u16")]
945  #[test_case(352323_u32 ; "u32")]
946  #[test_case(352323232_u64 ; "u64")]
947  #[test_case(-3_i8 ; "i8")]
948  #[test_case(-3_i16 ; "i16")]
949  #[test_case(-323232_i32 ; "i32")]
950  #[test_case(-3232323434_i64 ; "i64")]
951  #[test_case(true)]
952  #[test_case(false)]
953  #[test_case(2.35_f32 ; "f32")]
954  #[test_case(278.35_f64 ; "f64")]
955  #[test_case('a' ; "char")]
956  #[test_case("BLUE".to_string() ; "string")]
957  #[test_case(vec![1_i32, -2_i32, 3_i32] ; "Vec<i32>")]
958  #[test_case(InterestingMessage {
959      unbounded_string: "Here is a fairly long text".to_string(),
960      x: 2,
961      y: -3,
962      shape_size: -4,
963      slide: 5.5,
964      double_slide: -6.6,
965      three_short: [1, 2, 3],
966      four_short: [1, -2, -3, 4],
967      booleans: vec![true, false, true],
968      three_bytes: [23, 0, 2].to_vec(),
969    } ; "InterestingMessage")]
970  #[test_case( BigEnum::Boring ; "BigEnum::Boring")]
971  #[test_case( BigEnum::Interesting(InterestingMessage {
972      unbounded_string: "Here is a fairly long text".to_string(),
973      x: 2,
974      y: -3,
975      shape_size: -4,
976      slide: 5.5,
977      double_slide: -6.6,
978      three_short: [1, 2, 3],
979      four_short: [1, -2, -3, 4],
980      booleans: vec![true, false, true],
981      three_bytes: [23, 0, 2].to_vec(),
982    }) ; "BigEnum::Interesting")]
983  #[test_case( BigEnum::Something{ x:123.0, y:-0.1 } ; "BigEnum::Something")]
984  #[test_case( SomeTupleEnum::A(123) ; "SomeTupleEnum::A")]
985  #[test_case( SomeTupleEnum::B(1234) ; "SomeTupleEnum::B")]
986  #[test_case( SomeTupleEnum::C(-1) ; "SomeTupleEnum::C")]
987  #[test_case( MixedEnum::A(123) ; "MixedEnum::A")]
988  #[test_case( MixedEnum::B{ value:1234 } ; "MixedEnum::B")]
989  #[test_case( MixedEnum::C(42,43) ; "MixedEnum::C")]
990  #[test_case( GoalStatusEnum::Accepted ; "GoalStatusEnum::Accepted")]
991  #[test_case( [AlignMe{some_bytes: [1,2,3,4], status:10 } ,
992                AlignMe{some_bytes: [5,6,7,8], status:11 } ]  ; "AlignMeArray")]
993  fn cdr_serde_round_trip<T>(input: T)
994  where
995    T: PartialEq + std::fmt::Debug + Serialize + for<'a> Deserialize<'a>,
996  {
997    let serialized = to_vec::<_, LittleEndian>(&input).unwrap();
998    println!("Serialized data: {:x?}", &serialized);
999    let (deserialized, bytes_consumed): (T, usize) =
1000      from_bytes::<T, LittleEndian>(&serialized).unwrap();
1001    // let deserialized = deserialize_from_little_endian(&serialized).unwrap();
1002    assert_eq!(input, deserialized);
1003    assert_eq!(serialized.len(), bytes_consumed);
1004  }
1005
1006  /*
1007  #[test]
1008  fn cdr_deserialization_bytes(){
1009    let mut buf = B::with_capacity(1024);
1010    buf.put(&b"hello world"[..]);
1011    buf.put_u16(1234);
1012
1013    let ubuf = buf.into(u8);
1014    let mut serialized = to_little_endian_binary(&ubuf).unwrap();
1015    let deserialized : Vec<u8> = deserialize_from_little_endian(&mut serialized).unwrap();
1016
1017  }
1018  */
1019}