pjmsg_mcap_wrapper
Loading...
Searching...
No Matches
Cdr.cpp
Go to the documentation of this file.
1// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include <cstring>
16#include <limits>
17
18#include <fastcdr/Cdr.h>
19
20namespace eprosima {
21namespace fastcdr {
22
23using namespace exception;
24
25#if FASTCDR_IS_BIG_ENDIAN_TARGET
26const Cdr::Endianness Cdr::DEFAULT_ENDIAN = BIG_ENDIANNESS;
27#else
28const Cdr::Endianness Cdr::DEFAULT_ENDIAN = LITTLE_ENDIANNESS;
29#endif // if FASTCDR_IS_BIG_ENDIAN_TARGET
30
31constexpr uint16_t PID_EXTENDED = 0x3F01;
32constexpr uint16_t PID_EXTENDED_LENGTH = 0x8;
33constexpr uint16_t PID_SENTINEL = 0x3F02;
34constexpr uint16_t PID_SENTINEL_LENGTH = 0x0;
35
36constexpr uint8_t operator ""_8u(
37 unsigned long long int value)
38{
39 return static_cast<uint8_t>(value);
40}
41
42inline size_t alignment_on_state(
43 const FastBuffer::iterator& origin,
44 const FastBuffer::iterator& offset,
45 size_t data_size)
46{
47 return (data_size - ((offset - origin) % data_size)) & (data_size - 1);
48}
49
50inline uint32_t Cdr::get_long_lc(
51 SerializedMemberSizeForNextInt serialized_member_size)
52{
53 uint32_t lc {0x40000000};
54
55 switch (serialized_member_size)
56 {
58 lc = 0x70000000u;
59 break;
61 lc = 0x60000000u;
62 break;
64 lc = 0x50000000u;
65 break;
66 default:
67 break;
68 }
69
70 return lc;
71}
72
73inline uint32_t Cdr::get_short_lc(
74 size_t member_serialized_size)
75{
76 uint32_t lc {0xFFFFFFFFu};
77 switch (member_serialized_size)
78 {
79 case 1:
80 lc = 0x00000000u;
81 break;
82 case 2:
83 lc = 0x10000000u;
84 break;
85 case 4:
86 lc = 0x20000000u;
87 break;
88 case 8:
89 lc = 0x30000000u;
90 break;
91 default:
92 break;
93 }
94
95 return lc;
96}
97
99 const Cdr& cdr)
100 : offset_(cdr.offset_)
101 , origin_(cdr.origin_)
102 , swap_bytes_(cdr.swap_bytes_)
103 , last_data_size_(cdr.last_data_size_)
104 , next_member_id_(cdr.next_member_id_)
105 , previous_encoding_(cdr.current_encoding_)
106{
107}
108
110 const state& current_state)
111 : offset_(current_state.offset_)
112 , origin_(current_state.origin_)
113 , swap_bytes_(current_state.swap_bytes_)
114 , last_data_size_(current_state.last_data_size_)
115 , next_member_id_(current_state.next_member_id_)
116 , previous_encoding_(current_state.previous_encoding_)
117{
118}
119
121 const Cdr::state& other_state) const
122{
123 return
124 other_state.offset_ == offset_ &&
125 other_state.origin_ == origin_ &&
126 other_state.swap_bytes_ == swap_bytes_ &&
127 (0 == other_state.last_data_size_ ||
128 0 == last_data_size_ ||
129 other_state.last_data_size_ == last_data_size_
130 );
131}
132
134 FastBuffer& cdr_buffer,
136 const CdrVersion cdr_version)
137 : cdr_buffer_(cdr_buffer)
138 , cdr_version_(cdr_version)
140 , swap_bytes_(endianness == DEFAULT_ENDIAN ? false : true)
141 , offset_(cdr_buffer.begin())
142 , origin_(cdr_buffer.begin())
143 , end_(cdr_buffer.end())
144 , initial_state_(*this)
145{
146 switch (cdr_version_)
147 {
149 break;
151 align64_ = 8;
154 break;
155 default:
156 align64_ = 8;
159 break;
160 }
162}
163
197
199{
200 uint8_t dummy {0};
201 uint8_t encapsulation {0};
202 state state_before_error(*this);
203
204 try
205 {
206 // If it is DDS_CDR, the first step is to get the dummy byte.
208 {
209 (*this) >> dummy;
210 if (0 != dummy)
211 {
212 throw BadParamException("Unexpected non-zero initial byte received in Cdr::read_encapsulation");
213 }
214 }
215
216 // Get the ecampsulation byte.
217 (*this) >> encapsulation;
218
219
220 // If it is a different endianness, make changes.
221 const uint8_t endianness = encapsulation & 0x1_8u;
222 if (endianness_ != endianness)
223 {
226 }
227
228 // Check encapsulationKind correctness
229 const uint8_t encoding_flag = encapsulation & static_cast<uint8_t>(~0x1);
230 switch (encoding_flag)
231 {
236 {
238 align64_ = 4;
239 }
240 else
241 {
242 throw BadParamException(
243 "Unexpected encoding algorithm received in Cdr::read_encapsulation. XCDRv2 should be selected.");
244 }
245 break;
248 {
250 align64_ = 8;
251 }
252 else
253 {
254 throw BadParamException(
255 "Unexpected encoding algorithm received in Cdr::read_encapsulation. XCDRv1 should be selected");
256 }
257 break;
260 {
262 align64_ = 8;
263 }
264 break;
265 default:
266 throw BadParamException("Unexpected encoding algorithm received in Cdr::read_encapsulation for DDS CDR");
267 }
269
270 encoding_flag_ = static_cast<EncodingAlgorithmFlag>(encoding_flag);
272
274 {
276
277 uint8_t option_align {static_cast<uint8_t>(options_[1] & 0x3u)};
278
279 if (0 < option_align)
280 {
281 auto length {end_ - cdr_buffer_.begin()};
282 auto alignment = ((length + 3u) & ~3u) - length;
283
284 if (0 == alignment)
285 {
286 end_ -= option_align;
287 }
288 }
289 }
290
291 }
292 catch (Exception& ex)
293 {
294 set_state(state_before_error);
295 ex.raise();
296 }
297
299 return *this;
300}
301
303{
304 uint8_t dummy = 0;
305 uint8_t encapsulation = 0;
306 state state_before_error(*this);
307
308 try
309 {
310 // If it is DDS_CDR, the first step is to serialize the dummy byte.
312 {
313 (*this) << dummy;
314 }
315
316 // Construct encapsulation byte.
317 encapsulation = (encoding_flag_ | endianness_);
318
319 // Serialize the encapsulation byte.
320 (*this) << encapsulation;
321
323 }
324 catch (Exception& ex)
325 {
326 set_state(state_before_error);
327 ex.raise();
328 }
329
330 try
331 {
333 {
335 }
336 }
337 catch (Exception& ex)
338 {
339 set_state(state_before_error);
340 ex.raise();
341 }
342
345 return *this;
346}
347
349{
350 return cdr_version_;
351}
352
357
359 EncodingAlgorithmFlag encoding_flag)
360{
361 bool ret_value = false;
362
364 {
365 if (offset_ == cdr_buffer_.begin())
366 {
367 encoding_flag_ = encoding_flag;
368 ret_value = true;
369 }
370 }
371
372 return ret_value;
373}
374
379
381 const std::array<uint8_t, 2>& options)
382{
383 options_ = options;
384
387 {
388 auto length {offset_ - cdr_buffer_.begin()};
389 auto alignment = ((length + 3u) & ~3u) - length;
390 options_[1] = static_cast<uint8_t>(options_[1] & 0xC) + static_cast<uint8_t>(alignment & 0x3);
391 }
392
394 {
395 state previous_state(*this);
397
398 jump(2);
400
401 set_state(previous_state);
402 }
403}
404
406 Endianness endianness)
407{
408 if (endianness_ != endianness)
409 {
412 }
413}
414
416{
417 return static_cast<Endianness>(endianness_);
418}
419
421 size_t num_bytes)
422{
423 bool ret_value = false;
424
425 if (((end_ - offset_) >= num_bytes) || resize(num_bytes))
426 {
427 offset_ += num_bytes;
428 last_data_size_ = 0;
429 ret_value = true;
430 }
431
432 return ret_value;
433}
434
436{
437 return cdr_buffer_.getBuffer();
438}
439
441{
442 return &offset_;
443}
444
446{
447 return offset_ - cdr_buffer_.begin();
448}
449
451{
452 return Cdr::state(*this);
453}
454
456 const state& current_state)
457{
458 offset_ >> current_state.offset_;
459 origin_ >> current_state.origin_;
460 swap_bytes_ = current_state.swap_bytes_;
461 last_data_size_ = current_state.last_data_size_;
462 next_member_id_ = current_state.next_member_id_;
463}
464
477
479 size_t num_bytes)
480{
481 bool ret_value = false;
482
483 if (((end_ - origin_) >= num_bytes) || resize(num_bytes))
484 {
485 origin_ += num_bytes;
486 last_data_size_ = 0;
487 ret_value = true;
488 }
489
490 return ret_value;
491}
492
494 size_t min_size_inc)
495{
496 if (cdr_buffer_.resize(min_size_inc))
497 {
500 end_ = cdr_buffer_.end();
501 return true;
502 }
503
504 return false;
505}
506
508 const uint8_t& octet_t)
509{
510 return serialize(static_cast<char>(octet_t));
511}
512
514 const char char_t)
515{
516 if (((end_ - offset_) >= sizeof(char_t)) || resize(sizeof(char_t)))
517 {
518 // Save last datasize.
519 last_data_size_ = sizeof(char_t);
520
521 offset_++ << char_t;
522 return *this;
523 }
524
526}
527
529 const int8_t int8)
530{
531 return serialize(static_cast<char>(int8));
532}
533
535 const uint16_t ushort_t)
536{
537 return serialize(static_cast<int16_t>(ushort_t));
538}
539
541 const int16_t short_t)
542{
543 size_t align = alignment(sizeof(short_t));
544 size_t size_aligned = sizeof(short_t) + align;
545
546 if (((end_ - offset_) >= size_aligned) || resize(size_aligned))
547 {
548 // Save last datasize.
549 last_data_size_ = sizeof(short_t);
550
551 // Align.
552 make_alignment(align);
553
554 if (swap_bytes_)
555 {
556 const char* dst = reinterpret_cast<const char*>(&short_t);
557
558 offset_++ << dst[1];
559 offset_++ << dst[0];
560 }
561 else
562 {
563 offset_ << short_t;
564 offset_ += sizeof(short_t);
565 }
566
567 return *this;
568 }
569
571}
572
574 const uint32_t ulong_t)
575{
576 return serialize(static_cast<int32_t>(ulong_t));
577}
578
580 const int32_t long_t)
581{
582 size_t align = alignment(sizeof(long_t));
583 size_t size_aligned = sizeof(long_t) + align;
584
585 if (((end_ - offset_) >= size_aligned) || resize(size_aligned))
586 {
587 // Save last datasize.
588 last_data_size_ = sizeof(long_t);
589
590 // Align.
591 make_alignment(align);
592
593 if (swap_bytes_)
594 {
595 const char* dst = reinterpret_cast<const char*>(&long_t);
596
597 offset_++ << dst[3];
598 offset_++ << dst[2];
599 offset_++ << dst[1];
600 offset_++ << dst[0];
601 }
602 else
603 {
604 offset_ << long_t;
605 offset_ += sizeof(long_t);
606 }
607
608 return *this;
609 }
610
612}
613
615 const wchar_t wchar)
616{
617 return serialize(static_cast<uint16_t>(wchar));
618}
619
621 const uint64_t ulonglong_t)
622{
623 return serialize(static_cast<int64_t>(ulonglong_t));
624}
625
627 const int64_t longlong_t)
628{
629 size_t align = alignment(align64_);
630 size_t size_aligned = sizeof(longlong_t) + align;
631
632 if (((end_ - offset_) >= size_aligned) || resize(size_aligned))
633 {
634 // Save last datasize.
636
637 // Align.
638 make_alignment(align);
639
640 if (swap_bytes_)
641 {
642 const char* dst = reinterpret_cast<const char*>(&longlong_t);
643
644 offset_++ << dst[7];
645 offset_++ << dst[6];
646 offset_++ << dst[5];
647 offset_++ << dst[4];
648 offset_++ << dst[3];
649 offset_++ << dst[2];
650 offset_++ << dst[1];
651 offset_++ << dst[0];
652 }
653 else
654 {
655 offset_ << longlong_t;
656 offset_ += sizeof(longlong_t);
657 }
658
659 return *this;
660 }
661
663}
664
666 const float float_t)
667{
668 size_t align = alignment(sizeof(float_t));
669 size_t size_aligned = sizeof(float_t) + align;
670
671 if (((end_ - offset_) >= size_aligned) || resize(size_aligned))
672 {
673 // Save last datasize.
674 last_data_size_ = sizeof(float_t);
675
676 // Align.
677 make_alignment(align);
678
679 if (swap_bytes_)
680 {
681 const char* dst = reinterpret_cast<const char*>(&float_t);
682
683 offset_++ << dst[3];
684 offset_++ << dst[2];
685 offset_++ << dst[1];
686 offset_++ << dst[0];
687 }
688 else
689 {
690 offset_ << float_t;
691 offset_ += sizeof(float_t);
692 }
693
694 return *this;
695 }
696
698}
699
701 const double double_t)
702{
703 size_t align = alignment(align64_);
704 size_t size_aligned = sizeof(double_t) + align;
705
706 if (((end_ - offset_) >= size_aligned) || resize(size_aligned))
707 {
708 // Save last datasize.
710
711 // Align.
712 make_alignment(align);
713
714 if (swap_bytes_)
715 {
716 const char* dst = reinterpret_cast<const char*>(&double_t);
717
718 offset_++ << dst[7];
719 offset_++ << dst[6];
720 offset_++ << dst[5];
721 offset_++ << dst[4];
722 offset_++ << dst[3];
723 offset_++ << dst[2];
724 offset_++ << dst[1];
725 offset_++ << dst[0];
726 }
727 else
728 {
729 offset_ << double_t;
730 offset_ += sizeof(double_t);
731 }
732
733 return *this;
734 }
735
737}
738
740 const long double ldouble_t)
741{
742 size_t align = alignment(align64_);
743 size_t size_aligned = sizeof(ldouble_t) + align;
744
745 if (((end_ - offset_) >= size_aligned) || resize(size_aligned))
746 {
747 // Save last datasize.
749
750 // Align.
751 make_alignment(align);
752
753 if (swap_bytes_)
754 {
755#if FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
756 __float128 tmp = ldouble_t;
757 const char* dst = reinterpret_cast<const char*>(&tmp);
758#else
759 const char* dst = reinterpret_cast<const char*>(&ldouble_t);
760#endif // FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
761#if FASTCDR_HAVE_FLOAT128 || FASTCDR_SIZEOF_LONG_DOUBLE == 16
762 offset_++ << dst[15];
763 offset_++ << dst[14];
764 offset_++ << dst[13];
765 offset_++ << dst[12];
766 offset_++ << dst[11];
767 offset_++ << dst[10];
768 offset_++ << dst[9];
769 offset_++ << dst[8];
770 offset_++ << dst[7];
771 offset_++ << dst[6];
772 offset_++ << dst[5];
773 offset_++ << dst[4];
774 offset_++ << dst[3];
775 offset_++ << dst[2];
776 offset_++ << dst[1];
777 offset_++ << dst[0];
778#else
779#if FASTCDR_SIZEOF_LONG_DOUBLE == 8
780 // Filled with 0's.
781 offset_++ << static_cast<char>(0);
782 offset_++ << static_cast<char>(0);
783 offset_++ << static_cast<char>(0);
784 offset_++ << static_cast<char>(0);
785 offset_++ << static_cast<char>(0);
786 offset_++ << static_cast<char>(0);
787 offset_++ << static_cast<char>(0);
788 offset_++ << static_cast<char>(0);
789 offset_++ << dst[7];
790 offset_++ << dst[6];
791 offset_++ << dst[5];
792 offset_++ << dst[4];
793 offset_++ << dst[3];
794 offset_++ << dst[2];
795 offset_++ << dst[1];
796 offset_++ << dst[0];
797#else
798#error unsupported long double type and no __float128 available
799#endif // FASTCDR_SIZEOF_LONG_DOUBLE == 8
800#endif // FASTCDR_HAVE_FLOAT128 || FASTCDR_SIZEOF_LONG_DOUBLE == 16
801 }
802 else
803 {
804#if FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
805 __float128 tmp = ldouble_t;
806 offset_ << tmp;
807 offset_ += 16;
808#else
809#if FASTCDR_SIZEOF_LONG_DOUBLE == 8
810 offset_ << static_cast<long double>(0);
811 offset_ += sizeof(ldouble_t);
812#endif // FASTCDR_SIZEOF_LONG_DOUBLE == 8
813#if FASTCDR_SIZEOF_LONG_DOUBLE == 8 || FASTCDR_SIZEOF_LONG_DOUBLE == 16
814 offset_ << ldouble_t;
815 offset_ += sizeof(ldouble_t);
816#else
817#error unsupported long double type and no __float128 available
818#endif // FASTCDR_SIZEOF_LONG_DOUBLE == 8 || FASTCDR_SIZEOF_LONG_DOUBLE == 16
819#endif // FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
820 }
821
822 return *this;
823 }
824
826}
827
829 const bool bool_t)
830{
831 if (((end_ - offset_) >= sizeof(uint8_t)) || resize(sizeof(uint8_t)))
832 {
833 // Save last datasize.
834 last_data_size_ = sizeof(uint8_t);
835
836 if (bool_t)
837 {
838 offset_++ << static_cast<uint8_t>(1);
839 }
840 else
841 {
842 offset_++ << static_cast<uint8_t>(0);
843 }
844
845 return *this;
846 }
847
849}
850
852 char* string_t)
853{
854 return serialize(static_cast<const char*>(string_t));
855}
856
858 const char* string_t)
859{
860 uint32_t length = 0;
861
862 if (string_t != nullptr)
863 {
864 length = size_to_uint32(strlen(string_t)) + 1;
865 }
866
867 if (length > 0)
868 {
869 Cdr::state state_before_error(*this);
870 serialize(length);
871
872 if (((end_ - offset_) >= length) || resize(length))
873 {
874 // Save last datasize.
875 last_data_size_ = sizeof(uint8_t);
876
877 offset_.memcopy(string_t, length);
878 offset_ += length;
879 }
880 else
881 {
882 set_state(state_before_error);
884 }
885 }
886 else
887 {
888 serialize(length);
889 }
890
891 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
892
893 return *this;
894}
895
897 const wchar_t* string_t)
898{
899 uint32_t bytes_length = 0;
900 size_t wstrlen = 0;
901
902 if (string_t != nullptr)
903 {
904 wstrlen = wcslen(string_t);
905 bytes_length = size_to_uint32(wstrlen * 2);
906 }
907
908 if (bytes_length > 0)
909 {
910 Cdr::state state_(*this);
911 serialize(size_to_uint32(wstrlen));
912
913 if (((end_ - offset_) >= bytes_length) || resize(bytes_length))
914 {
915 serialize_array(string_t, wstrlen);
916 }
917 else
918 {
919 set_state(state_);
921 }
922 }
923 else
924 {
925 serialize(bytes_length);
926 }
927
928 return *this;
929}
930
932 const bool* bool_t,
933 size_t num_elements)
934{
935 size_t total_size = sizeof(*bool_t) * num_elements;
936
937 if (((end_ - offset_) >= total_size) || resize(total_size))
938 {
939 // Save last datasize.
940 last_data_size_ = sizeof(*bool_t);
941
942 for (size_t count = 0; count < num_elements; ++count)
943 {
944 uint8_t value = 0;
945
946 if (bool_t[count])
947 {
948 value = 1;
949 }
950 offset_++ << value;
951 }
952
953 return *this;
954 }
955
957}
958
960 const char* char_t,
961 size_t num_elements)
962{
963 size_t total_size = sizeof(*char_t) * num_elements;
964
965 if (((end_ - offset_) >= total_size) || resize(total_size))
966 {
967 // Save last datasize.
968 last_data_size_ = sizeof(*char_t);
969
970 offset_.memcopy(char_t, total_size);
971 offset_ += total_size;
972 return *this;
973 }
974
976}
977
979 const int16_t* short_t,
980 size_t num_elements)
981{
982 if (num_elements == 0)
983 {
984 return *this;
985 }
986
987 size_t align = alignment(sizeof(*short_t));
988 size_t total_size = sizeof(*short_t) * num_elements;
989 size_t size_aligned = total_size + align;
990
991 if (((end_ - offset_) >= size_aligned) || resize(size_aligned))
992 {
993 // Save last datasize.
994 last_data_size_ = sizeof(*short_t);
995
996 // Align if there are any elements
997 if (num_elements)
998 {
999 make_alignment(align);
1000 }
1001
1002 if (swap_bytes_)
1003 {
1004 const char* dst = reinterpret_cast<const char*>(short_t);
1005 const char* end = dst + total_size;
1006
1007 for (; dst < end; dst += sizeof(*short_t))
1008 {
1009 offset_++ << dst[1];
1010 offset_++ << dst[0];
1011 }
1012 }
1013 else
1014 {
1015 offset_.memcopy(short_t, total_size);
1016 offset_ += total_size;
1017 }
1018
1019 return *this;
1020 }
1021
1023}
1024
1026 const int32_t* long_t,
1027 size_t num_elements)
1028{
1029 if (num_elements == 0)
1030 {
1031 return *this;
1032 }
1033
1034 size_t align = alignment(sizeof(*long_t));
1035 size_t total_size = sizeof(*long_t) * num_elements;
1036 size_t size_aligned = total_size + align;
1037
1038 if (((end_ - offset_) >= size_aligned) || resize(size_aligned))
1039 {
1040 // Save last datasize.
1041 last_data_size_ = sizeof(*long_t);
1042
1043 // Align if there are any elements
1044 if (num_elements)
1045 {
1046 make_alignment(align);
1047 }
1048
1049 if (swap_bytes_)
1050 {
1051 const char* dst = reinterpret_cast<const char*>(long_t);
1052 const char* end = dst + total_size;
1053
1054 for (; dst < end; dst += sizeof(*long_t))
1055 {
1056 offset_++ << dst[3];
1057 offset_++ << dst[2];
1058 offset_++ << dst[1];
1059 offset_++ << dst[0];
1060 }
1061 }
1062 else
1063 {
1064 offset_.memcopy(long_t, total_size);
1065 offset_ += total_size;
1066 }
1067
1068 return *this;
1069 }
1070
1072}
1073
1075 const wchar_t* wchar,
1076 size_t num_elements)
1077{
1078 if (num_elements == 0)
1079 {
1080 return *this;
1081 }
1082
1083 for (size_t count = 0; count < num_elements; ++count)
1084 {
1085 serialize(wchar[count]);
1086 }
1087 return *this;
1088}
1089
1091 const int64_t* longlong_t,
1092 size_t num_elements)
1093{
1094 if (num_elements == 0)
1095 {
1096 return *this;
1097 }
1098
1099 size_t align = alignment(align64_);
1100 size_t total_size = sizeof(*longlong_t) * num_elements;
1101 size_t size_aligned = total_size + align;
1102
1103 if (((end_ - offset_) >= size_aligned) || resize(size_aligned))
1104 {
1105 // Save last datasize.
1107
1108 // Align if there are any elements
1109 if (num_elements)
1110 {
1111 make_alignment(align);
1112 }
1113
1114 if (swap_bytes_)
1115 {
1116 const char* dst = reinterpret_cast<const char*>(longlong_t);
1117 const char* end = dst + total_size;
1118
1119 for (; dst < end; dst += sizeof(*longlong_t))
1120 {
1121 offset_++ << dst[7];
1122 offset_++ << dst[6];
1123 offset_++ << dst[5];
1124 offset_++ << dst[4];
1125 offset_++ << dst[3];
1126 offset_++ << dst[2];
1127 offset_++ << dst[1];
1128 offset_++ << dst[0];
1129 }
1130 }
1131 else
1132 {
1133 offset_.memcopy(longlong_t, total_size);
1134 offset_ += total_size;
1135 }
1136
1137 return *this;
1138 }
1139
1141}
1142
1144 const float* float_t,
1145 size_t num_elements)
1146{
1147 if (num_elements == 0)
1148 {
1149 return *this;
1150 }
1151
1152 size_t align = alignment(sizeof(*float_t));
1153 size_t total_size = sizeof(*float_t) * num_elements;
1154 size_t size_aligned = total_size + align;
1155
1156 if (((end_ - offset_) >= size_aligned) || resize(size_aligned))
1157 {
1158 // Save last datasize.
1159 last_data_size_ = sizeof(*float_t);
1160
1161 // Align if there are any elements
1162 if (num_elements)
1163 {
1164 make_alignment(align);
1165 }
1166
1167 if (swap_bytes_)
1168 {
1169 const char* dst = reinterpret_cast<const char*>(float_t);
1170 const char* end = dst + total_size;
1171
1172 for (; dst < end; dst += sizeof(*float_t))
1173 {
1174 offset_++ << dst[3];
1175 offset_++ << dst[2];
1176 offset_++ << dst[1];
1177 offset_++ << dst[0];
1178 }
1179 }
1180 else
1181 {
1182 offset_.memcopy(float_t, total_size);
1183 offset_ += total_size;
1184 }
1185
1186 return *this;
1187 }
1188
1190}
1191
1193 const double* double_t,
1194 size_t num_elements)
1195{
1196 if (num_elements == 0)
1197 {
1198 return *this;
1199 }
1200
1201 size_t align = alignment(align64_);
1202 size_t total_size = sizeof(*double_t) * num_elements;
1203 size_t size_aligned = total_size + align;
1204
1205 if (((end_ - offset_) >= size_aligned) || resize(size_aligned))
1206 {
1207 // Save last datasize.
1209
1210 // Align if there are any elements
1211 if (num_elements)
1212 {
1213 make_alignment(align);
1214 }
1215
1216 if (swap_bytes_)
1217 {
1218 const char* dst = reinterpret_cast<const char*>(double_t);
1219 const char* end = dst + total_size;
1220
1221 for (; dst < end; dst += sizeof(*double_t))
1222 {
1223 offset_++ << dst[7];
1224 offset_++ << dst[6];
1225 offset_++ << dst[5];
1226 offset_++ << dst[4];
1227 offset_++ << dst[3];
1228 offset_++ << dst[2];
1229 offset_++ << dst[1];
1230 offset_++ << dst[0];
1231 }
1232 }
1233 else
1234 {
1235 offset_.memcopy(double_t, total_size);
1236 offset_ += total_size;
1237 }
1238
1239 return *this;
1240 }
1241
1243}
1244
1246 const long double* ldouble_t,
1247 size_t num_elements)
1248{
1249 if (num_elements == 0)
1250 {
1251 return *this;
1252 }
1253
1254 size_t align = alignment(align64_);
1255 // Fix for Windows ( long doubles only store 8 bytes )
1256 size_t total_size = 16 * num_elements; // sizeof(*ldouble_t)
1257 size_t size_aligned = total_size + align;
1258
1259 if (((end_ - offset_) >= size_aligned) || resize(size_aligned))
1260 {
1261 // Save last datasize.
1263
1264 // Align if there are any elements
1265 if (num_elements)
1266 {
1267 make_alignment(align);
1268 }
1269
1270#if FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
1271 if (swap_bytes_)
1272 {
1273 for (size_t i = 0; i < num_elements; ++i, ++ldouble_t)
1274 {
1275 __float128 tmp = *ldouble_t;
1276 const char* dst = reinterpret_cast<const char*>(&tmp);
1277 offset_++ << dst[15];
1278 offset_++ << dst[14];
1279 offset_++ << dst[13];
1280 offset_++ << dst[12];
1281 offset_++ << dst[11];
1282 offset_++ << dst[10];
1283 offset_++ << dst[9];
1284 offset_++ << dst[8];
1285 offset_++ << dst[7];
1286 offset_++ << dst[6];
1287 offset_++ << dst[5];
1288 offset_++ << dst[4];
1289 offset_++ << dst[3];
1290 offset_++ << dst[2];
1291 offset_++ << dst[1];
1292 offset_++ << dst[0];
1293 }
1294 }
1295 else
1296 {
1297 for (size_t i = 0; i < num_elements; ++i, ++ldouble_t)
1298 {
1299 __float128 tmp = *ldouble_t;
1300 offset_ << tmp;
1301 offset_ += 16;
1302 }
1303 }
1304#else
1305#if FASTCDR_SIZEOF_LONG_DOUBLE == 8 || FASTCDR_SIZEOF_LONG_DOUBLE == 16
1306 if (swap_bytes_)
1307 {
1308 const char* dst = reinterpret_cast<const char*>(ldouble_t);
1309 const char* end = dst + total_size;
1310
1311 for (; dst < end; dst += sizeof(*ldouble_t))
1312 {
1313#if FASTCDR_SIZEOF_LONG_DOUBLE == 16
1314 offset_++ << dst[15];
1315 offset_++ << dst[14];
1316 offset_++ << dst[13];
1317 offset_++ << dst[12];
1318 offset_++ << dst[11];
1319 offset_++ << dst[10];
1320 offset_++ << dst[9];
1321 offset_++ << dst[8];
1322#else
1323 offset_++ << static_cast<char>(0);
1324 offset_++ << static_cast<char>(0);
1325 offset_++ << static_cast<char>(0);
1326 offset_++ << static_cast<char>(0);
1327 offset_++ << static_cast<char>(0);
1328 offset_++ << static_cast<char>(0);
1329 offset_++ << static_cast<char>(0);
1330 offset_++ << static_cast<char>(0);
1331#endif // FASTCDR_SIZEOF_LONG_DOUBLE == 16
1332 offset_++ << dst[7];
1333 offset_++ << dst[6];
1334 offset_++ << dst[5];
1335 offset_++ << dst[4];
1336 offset_++ << dst[3];
1337 offset_++ << dst[2];
1338 offset_++ << dst[1];
1339 offset_++ << dst[0];
1340 }
1341 }
1342 else
1343 {
1344#if FASTCDR_SIZEOF_LONG_DOUBLE == 16
1345 offset_.memcopy(ldouble_t, total_size);
1346 offset_ += total_size;
1347#else
1348 for (size_t i = 0; i < num_elements; ++i)
1349 {
1350 offset_ << static_cast<long double>(0);
1351 offset_ += 8;
1352 offset_ << ldouble_t[i];
1353 offset_ += 8;
1354 }
1355#endif // FASTCDR_SIZEOF_LONG_DOUBLE == 16
1356 }
1357#else
1358#error unsupported long double type and no __float128 available
1359#endif // FASTCDR_SIZEOF_LONG_DOUBLE == 8 || FASTCDR_SIZEOF_LONG_DOUBLE == 16
1360#endif // FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
1361
1362 return *this;
1363 }
1364
1366}
1367
1369 char& char_t)
1370{
1371 if ((end_ - offset_) >= sizeof(char_t))
1372 {
1373 // Save last datasize.
1374 last_data_size_ = sizeof(char_t);
1375
1376 offset_++ >> char_t;
1377 return *this;
1378 }
1379
1381}
1382
1384 int16_t& short_t)
1385{
1386 size_t align = alignment(sizeof(short_t));
1387 size_t size_aligned = sizeof(short_t) + align;
1388
1389 if ((end_ - offset_) >= size_aligned)
1390 {
1391 // Save last datasize.
1392 last_data_size_ = sizeof(short_t);
1393
1394 // Align
1395 make_alignment(align);
1396
1397 if (swap_bytes_)
1398 {
1399 char* dst = reinterpret_cast<char*>(&short_t);
1400
1401 offset_++ >> dst[1];
1402 offset_++ >> dst[0];
1403 }
1404 else
1405 {
1406 offset_ >> short_t;
1407 offset_ += sizeof(short_t);
1408 }
1409
1410 return *this;
1411 }
1412
1414}
1415
1417 int32_t& long_t)
1418{
1419 size_t align = alignment(sizeof(long_t));
1420 size_t size_aligned = sizeof(long_t) + align;
1421
1422 if ((end_ - offset_) >= size_aligned)
1423 {
1424 // Save last datasize.
1425 last_data_size_ = sizeof(long_t);
1426
1427 // Align
1428 make_alignment(align);
1429
1430 if (swap_bytes_)
1431 {
1432 char* dst = reinterpret_cast<char*>(&long_t);
1433
1434 offset_++ >> dst[3];
1435 offset_++ >> dst[2];
1436 offset_++ >> dst[1];
1437 offset_++ >> dst[0];
1438 }
1439 else
1440 {
1441 offset_ >> long_t;
1442 offset_ += sizeof(long_t);
1443 }
1444
1445 return *this;
1446 }
1447
1449}
1450
1452 int64_t& longlong_t)
1453{
1454 size_t align = alignment(align64_);
1455 size_t size_aligned = sizeof(longlong_t) + align;
1456
1457 if ((end_ - offset_) >= size_aligned)
1458 {
1459 // Save last datasize.
1461
1462 // Align.
1463 make_alignment(align);
1464
1465 if (swap_bytes_)
1466 {
1467 char* dst = reinterpret_cast<char*>(&longlong_t);
1468
1469 offset_++ >> dst[7];
1470 offset_++ >> dst[6];
1471 offset_++ >> dst[5];
1472 offset_++ >> dst[4];
1473 offset_++ >> dst[3];
1474 offset_++ >> dst[2];
1475 offset_++ >> dst[1];
1476 offset_++ >> dst[0];
1477 }
1478 else
1479 {
1480 offset_ >> longlong_t;
1481 offset_ += sizeof(longlong_t);
1482 }
1483
1484 return *this;
1485 }
1486
1488}
1489
1491 float& float_t)
1492{
1493 size_t align = alignment(sizeof(float_t));
1494 size_t size_aligned = sizeof(float_t) + align;
1495
1496 if ((end_ - offset_) >= size_aligned)
1497 {
1498 // Save last datasize.
1499 last_data_size_ = sizeof(float_t);
1500
1501 // Align.
1502 make_alignment(align);
1503
1504 if (swap_bytes_)
1505 {
1506 char* dst = reinterpret_cast<char*>(&float_t);
1507
1508 offset_++ >> dst[3];
1509 offset_++ >> dst[2];
1510 offset_++ >> dst[1];
1511 offset_++ >> dst[0];
1512 }
1513 else
1514 {
1515 offset_ >> float_t;
1516 offset_ += sizeof(float_t);
1517 }
1518
1519 return *this;
1520 }
1521
1523}
1524
1526 double& double_t)
1527{
1528 size_t align = alignment(align64_);
1529 size_t size_aligned = sizeof(double_t) + align;
1530
1531 if ((end_ - offset_) >= size_aligned)
1532 {
1533 // Save last datasize.
1535
1536 // Align.
1537 make_alignment(align);
1538
1539 if (swap_bytes_)
1540 {
1541 char* dst = reinterpret_cast<char*>(&double_t);
1542
1543 offset_++ >> dst[7];
1544 offset_++ >> dst[6];
1545 offset_++ >> dst[5];
1546 offset_++ >> dst[4];
1547 offset_++ >> dst[3];
1548 offset_++ >> dst[2];
1549 offset_++ >> dst[1];
1550 offset_++ >> dst[0];
1551 }
1552 else
1553 {
1554 offset_ >> double_t;
1555 offset_ += sizeof(double_t);
1556 }
1557
1558 return *this;
1559 }
1560
1562}
1563
1565 long double& ldouble_t)
1566{
1567 size_t align = alignment(align64_);
1568 size_t size_aligned = sizeof(ldouble_t) + align;
1569
1570 if ((end_ - offset_) >= size_aligned)
1571 {
1572 // Save last datasize.
1574
1575 // Align.
1576 make_alignment(align);
1577
1578 if (swap_bytes_)
1579 {
1580#if FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
1581 __float128 tmp = ldouble_t;
1582 char* dst = reinterpret_cast<char*>(&tmp);
1583#else
1584 char* dst = reinterpret_cast<char*>(&ldouble_t);
1585#endif // FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
1586#if FASTCDR_HAVE_FLOAT128 || FASTCDR_SIZEOF_LONG_DOUBLE == 16
1587 offset_++ >> dst[15];
1588 offset_++ >> dst[14];
1589 offset_++ >> dst[13];
1590 offset_++ >> dst[12];
1591 offset_++ >> dst[11];
1592 offset_++ >> dst[10];
1593 offset_++ >> dst[9];
1594 offset_++ >> dst[8];
1595 offset_++ >> dst[7];
1596 offset_++ >> dst[6];
1597 offset_++ >> dst[5];
1598 offset_++ >> dst[4];
1599 offset_++ >> dst[3];
1600 offset_++ >> dst[2];
1601 offset_++ >> dst[1];
1602 offset_++ >> dst[0];
1603#if FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
1604 ldouble_t = static_cast<long double>(tmp);
1605#endif // FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
1606#else
1607#if FASTCDR_SIZEOF_LONG_DOUBLE == 8
1608 offset_ += 8;
1609 offset_++ >> dst[7];
1610 offset_++ >> dst[6];
1611 offset_++ >> dst[5];
1612 offset_++ >> dst[4];
1613 offset_++ >> dst[3];
1614 offset_++ >> dst[2];
1615 offset_++ >> dst[1];
1616 offset_++ >> dst[0];
1617#else
1618#error unsupported long double type and no __float128 available
1619#endif // FASTCDR_SIZEOF_LONG_DOUBLE == 8
1620#endif // FASTCDR_HAVE_FLOAT128 || FASTCDR_SIZEOF_LONG_DOUBLE == 16
1621 }
1622 else
1623 {
1624#if FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
1625 __float128 tmp;
1626 offset_ >> tmp;
1627 offset_ += 16;
1628 ldouble_t = static_cast<long double>(tmp);
1629#else
1630#if FASTCDR_SIZEOF_LONG_DOUBLE == 8 || FASTCDR_SIZEOF_LONG_DOUBLE == 16
1631#if FASTCDR_SIZEOF_LONG_DOUBLE == 8
1632 offset_ += 8;
1633#endif // FASTCDR_SIZEOF_LONG_DOUBLE == 8
1634 offset_ >> ldouble_t;
1635 offset_ += sizeof(ldouble_t);
1636#endif // FASTCDR_SIZEOF_LONG_DOUBLE == 8 || FASTCDR_SIZEOF_LONG_DOUBLE == 16
1637#endif // FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
1638 }
1639
1640 return *this;
1641 }
1642
1644}
1645
1647 bool& bool_t)
1648{
1649 uint8_t value = 0;
1650
1651 if ((end_ - offset_) >= sizeof(uint8_t))
1652 {
1653 // Save last datasize.
1654 last_data_size_ = sizeof(uint8_t);
1655
1656 offset_++ >> value;
1657
1658 if (value == 1)
1659 {
1660 bool_t = true;
1661 return *this;
1662 }
1663 else if (value == 0)
1664 {
1665 bool_t = false;
1666 return *this;
1667 }
1668
1669 throw BadParamException("Unexpected byte value in Cdr::deserialize(bool), expected 0 or 1");
1670 }
1671
1673}
1674
1676 char*& string_t)
1677{
1678 uint32_t length = 0;
1679 Cdr::state state_before_error(*this);
1680
1681 deserialize(length);
1682
1683 if (length == 0)
1684 {
1685 string_t = nullptr;
1686 return *this;
1687 }
1688 else if ((end_ - offset_) >= length)
1689 {
1690 // Save last datasize.
1691 last_data_size_ = sizeof(uint8_t);
1692
1693 // Allocate memory.
1694 string_t =
1695 reinterpret_cast<char*>(calloc(length + ((&offset_)[length - 1] == '\0' ? 0 : 1),
1696 sizeof(char)));
1697 memcpy(string_t, &offset_, length);
1698 offset_ += length;
1699 return *this;
1700 }
1701
1702 set_state(state_before_error);
1704}
1705
1707 wchar_t*& string_t)
1708{
1709 uint32_t length = 0;
1710 Cdr::state state_before_error(*this);
1711
1712 deserialize(length);
1713
1714 if (length == 0)
1715 {
1716 string_t = nullptr;
1717 return *this;
1718 }
1719 else if ((end_ - offset_) >= (length * 2))
1720 {
1721 // Save last datasize.
1722 last_data_size_ = sizeof(uint16_t);
1723 // Allocate memory.
1724 string_t = reinterpret_cast<wchar_t*>(calloc(length + 1, sizeof(wchar_t))); // WStrings never serialize terminating zero
1725
1726 deserialize_array(string_t, length);
1727
1728 return *this;
1729 }
1730
1731 set_state(state_before_error);
1733}
1734
1736 uint32_t& length)
1737{
1738 const char* ret_value = "";
1739 state state_before_error(*this);
1740
1741 *this >> length;
1742
1743 if (length == 0)
1744 {
1745 return ret_value;
1746 }
1747 else if ((end_ - offset_) >= length)
1748 {
1749 // Save last datasize.
1750 last_data_size_ = sizeof(uint8_t);
1751
1752 ret_value = &offset_;
1753 offset_ += length;
1754 if (ret_value[length - 1] == '\0')
1755 {
1756 --length;
1757 }
1758 return ret_value;
1759 }
1760
1761 set_state(state_before_error);
1764}
1765
1767 uint32_t& length)
1768{
1769 std::wstring ret_value = L"";
1770 state state_(*this);
1771
1772 *this >> length;
1773 uint32_t bytes_length = length * 2;
1774
1775 if (bytes_length == 0)
1776 {
1777 return ret_value;
1778 }
1779 else if ((end_ - offset_) >= bytes_length)
1780 {
1781 // Save last datasize.
1782 last_data_size_ = sizeof(uint16_t);
1783
1784 ret_value.resize(length);
1785 deserialize_array(const_cast<wchar_t*>(ret_value.c_str()), length);
1786 if (ret_value[length - 1] == L'\0')
1787 {
1788 --length;
1789 ret_value.erase(length);
1790 }
1791 return ret_value;
1792 }
1793
1794 set_state(state_);
1797}
1798
1800 bool* bool_t,
1801 size_t num_elements)
1802{
1803 size_t total_size = sizeof(*bool_t) * num_elements;
1804
1805 if ((end_ - offset_) >= total_size)
1806 {
1807 // Save last datasize.
1808 last_data_size_ = sizeof(*bool_t);
1809
1810 for (size_t count = 0; count < num_elements; ++count)
1811 {
1812 uint8_t value = 0;
1813 offset_++ >> value;
1814
1815 if (value == 1)
1816 {
1817 bool_t[count] = true;
1818 }
1819 else if (value == 0)
1820 {
1821 bool_t[count] = false;
1822 }
1823 }
1824
1825 return *this;
1826 }
1827
1829}
1830
1832 char* char_t,
1833 size_t num_elements)
1834{
1835 size_t total_size = sizeof(*char_t) * num_elements;
1836
1837 if ((end_ - offset_) >= total_size)
1838 {
1839 // Save last datasize.
1840 last_data_size_ = sizeof(*char_t);
1841
1842 offset_.rmemcopy(char_t, total_size);
1843 offset_ += total_size;
1844 return *this;
1845 }
1846
1848}
1849
1851 int16_t* short_t,
1852 size_t num_elements)
1853{
1854 if (num_elements == 0)
1855 {
1856 return *this;
1857 }
1858
1859 size_t align = alignment(sizeof(*short_t));
1860 size_t total_size = sizeof(*short_t) * num_elements;
1861 size_t size_aligned = total_size + align;
1862
1863 if ((end_ - offset_) >= size_aligned)
1864 {
1865 // Save last datasize.
1866 last_data_size_ = sizeof(*short_t);
1867
1868 // Align if there are any elements
1869 if (num_elements)
1870 {
1871 make_alignment(align);
1872 }
1873
1874 if (swap_bytes_)
1875 {
1876 char* dst = reinterpret_cast<char*>(short_t);
1877 char* end = dst + total_size;
1878
1879 for (; dst < end; dst += sizeof(*short_t))
1880 {
1881 offset_++ >> dst[1];
1882 offset_++ >> dst[0];
1883 }
1884 }
1885 else
1886 {
1887 offset_.rmemcopy(short_t, total_size);
1888 offset_ += total_size;
1889 }
1890
1891 return *this;
1892 }
1893
1895}
1896
1898 int32_t* long_t,
1899 size_t num_elements)
1900{
1901 if (num_elements == 0)
1902 {
1903 return *this;
1904 }
1905
1906 size_t align = alignment(sizeof(*long_t));
1907 size_t total_size = sizeof(*long_t) * num_elements;
1908 size_t size_aligned = total_size + align;
1909
1910 if ((end_ - offset_) >= size_aligned)
1911 {
1912 // Save last datasize.
1913 last_data_size_ = sizeof(*long_t);
1914
1915 // Align if there are any elements
1916 if (num_elements)
1917 {
1918 make_alignment(align);
1919 }
1920
1921 if (swap_bytes_)
1922 {
1923 char* dst = reinterpret_cast<char*>(long_t);
1924 char* end = dst + total_size;
1925
1926 for (; dst < end; dst += sizeof(*long_t))
1927 {
1928 offset_++ >> dst[3];
1929 offset_++ >> dst[2];
1930 offset_++ >> dst[1];
1931 offset_++ >> dst[0];
1932 }
1933 }
1934 else
1935 {
1936 offset_.rmemcopy(long_t, total_size);
1937 offset_ += total_size;
1938 }
1939
1940 return *this;
1941 }
1942
1944}
1945
1947 wchar_t* wchar,
1948 size_t num_elements)
1949{
1950 if (num_elements == 0)
1951 {
1952 return *this;
1953 }
1954
1955 uint16_t value;
1956 for (size_t count = 0; count < num_elements; ++count)
1957 {
1958 deserialize(value);
1959 wchar[count] = static_cast<wchar_t>(value);
1960 }
1961 return *this;
1962}
1963
1965 int64_t* longlong_t,
1966 size_t num_elements)
1967{
1968 if (num_elements == 0)
1969 {
1970 return *this;
1971 }
1972
1973 size_t align = alignment(align64_);
1974 size_t total_size = sizeof(*longlong_t) * num_elements;
1975 size_t size_aligned = total_size + align;
1976
1977 if ((end_ - offset_) >= size_aligned)
1978 {
1979 // Save last datasize.
1981
1982 // Align if there are any elements
1983 if (num_elements)
1984 {
1985 make_alignment(align);
1986 }
1987
1988 if (swap_bytes_)
1989 {
1990 char* dst = reinterpret_cast<char*>(longlong_t);
1991 char* end = dst + total_size;
1992
1993 for (; dst < end; dst += sizeof(*longlong_t))
1994 {
1995 offset_++ >> dst[7];
1996 offset_++ >> dst[6];
1997 offset_++ >> dst[5];
1998 offset_++ >> dst[4];
1999 offset_++ >> dst[3];
2000 offset_++ >> dst[2];
2001 offset_++ >> dst[1];
2002 offset_++ >> dst[0];
2003 }
2004 }
2005 else
2006 {
2007 offset_.rmemcopy(longlong_t, total_size);
2008 offset_ += total_size;
2009 }
2010
2011 return *this;
2012 }
2013
2015}
2016
2018 float* float_t,
2019 size_t num_elements)
2020{
2021 if (num_elements == 0)
2022 {
2023 return *this;
2024 }
2025
2026 size_t align = alignment(sizeof(*float_t));
2027 size_t total_size = sizeof(*float_t) * num_elements;
2028 size_t size_aligned = total_size + align;
2029
2030 if ((end_ - offset_) >= size_aligned)
2031 {
2032 // Save last datasize.
2033 last_data_size_ = sizeof(*float_t);
2034
2035 // Align if there are any elements
2036 if (num_elements)
2037 {
2038 make_alignment(align);
2039 }
2040
2041 if (swap_bytes_)
2042 {
2043 char* dst = reinterpret_cast<char*>(float_t);
2044 char* end = dst + total_size;
2045
2046 for (; dst < end; dst += sizeof(*float_t))
2047 {
2048 offset_++ >> dst[3];
2049 offset_++ >> dst[2];
2050 offset_++ >> dst[1];
2051 offset_++ >> dst[0];
2052 }
2053 }
2054 else
2055 {
2056 offset_.rmemcopy(float_t, total_size);
2057 offset_ += total_size;
2058 }
2059
2060 return *this;
2061 }
2062
2064}
2065
2067 double* double_t,
2068 size_t num_elements)
2069{
2070 if (num_elements == 0)
2071 {
2072 return *this;
2073 }
2074
2075 size_t align = alignment(align64_);
2076 size_t total_size = sizeof(*double_t) * num_elements;
2077 size_t size_aligned = total_size + align;
2078
2079 if ((end_ - offset_) >= size_aligned)
2080 {
2081 // Save last datasize.
2083
2084 // Align if there are any elements
2085 if (num_elements)
2086 {
2087 make_alignment(align);
2088 }
2089
2090 if (swap_bytes_)
2091 {
2092 char* dst = reinterpret_cast<char*>(double_t);
2093 char* end = dst + total_size;
2094
2095 for (; dst < end; dst += sizeof(*double_t))
2096 {
2097 offset_++ >> dst[7];
2098 offset_++ >> dst[6];
2099 offset_++ >> dst[5];
2100 offset_++ >> dst[4];
2101 offset_++ >> dst[3];
2102 offset_++ >> dst[2];
2103 offset_++ >> dst[1];
2104 offset_++ >> dst[0];
2105 }
2106 }
2107 else
2108 {
2109 offset_.rmemcopy(double_t, total_size);
2110 offset_ += total_size;
2111 }
2112
2113 return *this;
2114 }
2115
2117}
2118
2120 long double* ldouble_t,
2121 size_t num_elements)
2122{
2123 if (num_elements == 0)
2124 {
2125 return *this;
2126 }
2127
2128 size_t align = alignment(align64_);
2129 // Fix for Windows ( long doubles only store 8 bytes )
2130 size_t total_size = 16 * num_elements;
2131 size_t size_aligned = total_size + align;
2132
2133 if ((end_ - offset_) >= size_aligned)
2134 {
2135 // Save last datasize.
2137
2138 // Align if there are any elements
2139 if (num_elements)
2140 {
2141 make_alignment(align);
2142 }
2143
2144#if FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
2145 if (swap_bytes_)
2146 {
2147 for (size_t i = 0; i < num_elements; ++i)
2148 {
2149 __float128 tmp;
2150 char* dst = reinterpret_cast<char*>(&tmp);
2151 offset_++ >> dst[15];
2152 offset_++ >> dst[14];
2153 offset_++ >> dst[13];
2154 offset_++ >> dst[12];
2155 offset_++ >> dst[11];
2156 offset_++ >> dst[10];
2157 offset_++ >> dst[9];
2158 offset_++ >> dst[8];
2159 offset_++ >> dst[7];
2160 offset_++ >> dst[6];
2161 offset_++ >> dst[5];
2162 offset_++ >> dst[4];
2163 offset_++ >> dst[3];
2164 offset_++ >> dst[2];
2165 offset_++ >> dst[1];
2166 offset_++ >> dst[0];
2167 ldouble_t[i] = static_cast<long double>(tmp);
2168 }
2169 }
2170 else
2171 {
2172 for (size_t i = 0; i < num_elements; ++i)
2173 {
2174 __float128 tmp;
2175 offset_ >> tmp;
2176 offset_ += 16;
2177 ldouble_t[i] = static_cast<long double>(tmp);
2178 }
2179 }
2180#else
2181#if FASTCDR_SIZEOF_LONG_DOUBLE == 8 || FASTCDR_SIZEOF_LONG_DOUBLE == 16
2182 if (swap_bytes_)
2183 {
2184 char* dst = reinterpret_cast<char*>(ldouble_t);
2185 char* end = dst + num_elements * sizeof(*ldouble_t);
2186
2187 for (; dst < end; dst += sizeof(*ldouble_t))
2188 {
2189#if FASTCDR_SIZEOF_LONG_DOUBLE == 16
2190 offset_++ >> dst[15];
2191 offset_++ >> dst[14];
2192 offset_++ >> dst[13];
2193 offset_++ >> dst[12];
2194 offset_++ >> dst[11];
2195 offset_++ >> dst[10];
2196 offset_++ >> dst[9];
2197 offset_++ >> dst[8];
2198#else
2199 offset_ += 8;
2200#endif // FASTCDR_SIZEOF_LONG_DOUBLE == 16
2201 offset_++ >> dst[7];
2202 offset_++ >> dst[6];
2203 offset_++ >> dst[5];
2204 offset_++ >> dst[4];
2205 offset_++ >> dst[3];
2206 offset_++ >> dst[2];
2207 offset_++ >> dst[1];
2208 offset_++ >> dst[0];
2209 }
2210 }
2211 else
2212 {
2213#if FASTCDR_SIZEOF_LONG_DOUBLE == 16
2214 offset_.rmemcopy(ldouble_t, total_size);
2215 offset_ += total_size;
2216#else
2217 for (size_t i = 0; i < num_elements; ++i)
2218 {
2219 offset_ += 8; // ignore first 8 bytes
2220 offset_ >> ldouble_t[i];
2221 offset_ += 8;
2222 }
2223#endif // FASTCDR_SIZEOF_LONG_DOUBLE == 16
2224 }
2225#endif // FASTCDR_SIZEOF_LONG_DOUBLE == 8 || FASTCDR_SIZEOF_LONG_DOUBLE == 16
2226#endif // FASTCDR_HAVE_FLOAT128 && FASTCDR_SIZEOF_LONG_DOUBLE < 16
2227
2228 return *this;
2229 }
2230
2232}
2233
2235 Cdr::state& current_state,
2236 EncodingAlgorithmFlag type_encoding)
2237{
2238 return (this->*begin_serialize_type_)(current_state, type_encoding);
2239}
2240
2242 Cdr::state& current_state)
2243{
2244 return (this->*end_serialize_type_)(current_state);
2245}
2246
2248 EncodingAlgorithmFlag type_encoding,
2249 std::function<bool (Cdr&, const MemberId&)> functor)
2250{
2251 return (this->*deserialize_type_)(type_encoding, functor);
2252}
2253
2255 const MemberId& member_id)
2256{
2258 {
2259 throw exception::BadParamException("Member id already set and not encoded");
2260 }
2261
2262 next_member_id_ = member_id;
2263 return *this;
2264}
2265
2267 const std::vector<bool>& vector_t)
2268{
2269 state state_before_error(*this);
2270
2271 size_t total_size = vector_t.size() * sizeof(bool);
2272
2273 if (((end_ - offset_) >= total_size) || resize(total_size))
2274 {
2275 // Save last datasize.
2276 last_data_size_ = sizeof(bool);
2277
2278 for (size_t count = 0; count < vector_t.size(); ++count)
2279 {
2280 uint8_t value = 0;
2281 std::vector<bool>::const_reference ref = vector_t[count];
2282
2283 if (ref)
2284 {
2285 value = 1;
2286 }
2287 offset_++ << value;
2288 }
2289 }
2290 else
2291 {
2292 set_state(state_before_error);
2294 }
2295
2297 {
2298 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
2299 }
2300
2301 return *this;
2302}
2303
2305 const std::vector<bool>& vector_t)
2306{
2307 state state_before_error(*this);
2308
2309 *this << static_cast<int32_t>(vector_t.size());
2310
2311 size_t total_size = vector_t.size() * sizeof(bool);
2312
2313 if (((end_ - offset_) >= total_size) || resize(total_size))
2314 {
2315 // Save last datasize.
2316 last_data_size_ = sizeof(bool);
2317
2318 for (size_t count = 0; count < vector_t.size(); ++count)
2319 {
2320 uint8_t value = 0;
2321 std::vector<bool>::const_reference ref = vector_t[count];
2322
2323 if (ref)
2324 {
2325 value = 1;
2326 }
2327 offset_++ << value;
2328 }
2329 }
2330 else
2331 {
2332 set_state(state_before_error);
2334 }
2335
2337 {
2338 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
2339 }
2340
2341 return *this;
2342}
2343
2345 std::vector<bool>& vector_t)
2346{
2347 state state_before_error(*this);
2348
2349 size_t total_size = vector_t.size() * sizeof(bool);
2350
2351 if ((end_ - offset_) >= total_size)
2352 {
2353 // Save last datasize.
2354 last_data_size_ = sizeof(bool);
2355
2356 for (uint32_t count = 0; count < vector_t.size(); ++count)
2357 {
2358 uint8_t value = 0;
2359 offset_++ >> value;
2360
2361 if (value == 1)
2362 {
2363 vector_t[count] = true;
2364 }
2365 else if (value == 0)
2366 {
2367 vector_t[count] = false;
2368 }
2369 else
2370 {
2371 throw BadParamException("Unexpected byte value in Cdr::deserialize_bool_sequence, expected 0 or 1");
2372 }
2373 }
2374 }
2375 else
2376 {
2377 set_state(state_before_error);
2379 }
2380
2381 return *this;
2382}
2383
2385 std::vector<bool>& vector_t)
2386{
2387 uint32_t sequence_length {0};
2388 state state_before_error(*this);
2389
2390 *this >> sequence_length;
2391
2392 size_t total_size = sequence_length * sizeof(bool);
2393
2394 if ((end_ - offset_) >= total_size)
2395 {
2396 vector_t.resize(sequence_length);
2397 // Save last datasize.
2398 last_data_size_ = sizeof(bool);
2399
2400 for (uint32_t count = 0; count < sequence_length; ++count)
2401 {
2402 uint8_t value = 0;
2403 offset_++ >> value;
2404
2405 if (value == 1)
2406 {
2407 vector_t[count] = true;
2408 }
2409 else if (value == 0)
2410 {
2411 vector_t[count] = false;
2412 }
2413 else
2414 {
2415 throw BadParamException("Unexpected byte value in Cdr::deserialize_bool_sequence, expected 0 or 1");
2416 }
2417 }
2418 }
2419 else
2420 {
2421 set_state(state_before_error);
2423 }
2424
2425 return *this;
2426}
2427
2429 std::string*& sequence_t,
2430 size_t& num_elements)
2431{
2432 uint32_t sequence_length {0};
2433
2435 {
2436 uint32_t dheader {0};
2437 deserialize(dheader);
2438
2439 auto offset = offset_;
2440
2441 deserialize(sequence_length);
2442
2443 try
2444 {
2445 sequence_t = new std::string[sequence_length];
2446
2447 uint32_t count {0};
2448 while (offset_ - offset < dheader && count < sequence_length)
2449 {
2450 deserialize(sequence_t[count]);
2451 ++count;
2452 }
2453
2454 if (offset_ - offset != dheader)
2455 {
2456 throw BadParamException("Member size greater than size specified by DHEADER");
2457 }
2458 }
2459 catch (exception::Exception& ex)
2460 {
2461 delete [] sequence_t;
2462 sequence_t = nullptr;
2463 ex.raise();
2464 }
2465 }
2466 else
2467 {
2468 state state_before_error(*this);
2469
2470 deserialize(sequence_length);
2471
2472 try
2473 {
2474 sequence_t = new std::string[sequence_length];
2475 deserialize_array(sequence_t, sequence_length);
2476 }
2477 catch (exception::Exception& ex)
2478 {
2479 delete [] sequence_t;
2480 sequence_t = nullptr;
2481 set_state(state_before_error);
2482 ex.raise();
2483 }
2484 }
2485
2486 num_elements = sequence_length;
2487 return *this;
2488}
2489
2491 std::wstring*& sequence_t,
2492 size_t& num_elements)
2493{
2494 uint32_t sequence_length {0};
2495
2497 {
2498 uint32_t dheader {0};
2499 deserialize(dheader);
2500
2501 auto offset = offset_;
2502
2503 deserialize(sequence_length);
2504
2505 try
2506 {
2507 sequence_t = new std::wstring[sequence_length];
2508
2509 uint32_t count {0};
2510 while (offset_ - offset < dheader && count < sequence_length)
2511 {
2512 deserialize(sequence_t[count]);
2513 ++count;
2514 }
2515
2516 if (offset_ - offset != dheader)
2517 {
2518 throw BadParamException("Member size greater than size specified by DHEADER");
2519 }
2520 }
2521 catch (exception::Exception& ex)
2522 {
2523 delete [] sequence_t;
2524 sequence_t = nullptr;
2525 ex.raise();
2526 }
2527 }
2528 else
2529 {
2530 state state_before_error(*this);
2531
2532 deserialize(sequence_length);
2533
2534 try
2535 {
2536 sequence_t = new std::wstring[sequence_length];
2537 deserialize_array(sequence_t, sequence_length);
2538 }
2539 catch (exception::Exception& ex)
2540 {
2541 delete [] sequence_t;
2542 sequence_t = nullptr;
2543 set_state(state_before_error);
2544 ex.raise();
2545 }
2546 }
2547
2548 num_elements = sequence_length;
2549 return *this;
2550}
2551
2552////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2553/// XCDR extensions
2554////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2556 const MemberId& member_id)
2557{
2558 assert(0x3F00 >= member_id.id);
2559
2561
2562 uint16_t flags_and_member_id = static_cast<uint16_t>(member_id.must_understand ? 0x4000 : 0x0) |
2563 static_cast<uint16_t>(member_id.id);
2564 serialize(flags_and_member_id);
2565 uint16_t size = 0;
2566 serialize(size);
2568}
2569
2571 const MemberId& member_id,
2572 size_t member_serialized_size)
2573{
2574 static_cast<void>(member_id);
2575 assert(0x3F00 >= member_id.id);
2576 assert(std::numeric_limits<uint16_t>::max() >= member_serialized_size );
2578 jump(sizeof(uint16_t));
2579 uint16_t size = static_cast<uint16_t>(member_serialized_size);
2580 serialize(size);
2581}
2582
2584 const MemberId& member_id)
2585{
2587
2588 uint16_t flags_and_extended_pid = static_cast<uint16_t>(member_id.must_understand ? 0x4000 : 0x0) |
2589 static_cast<uint16_t>(PID_EXTENDED);
2590 serialize(flags_and_extended_pid);
2591 uint16_t size = PID_EXTENDED_LENGTH;
2592 serialize(size);
2593 uint32_t id = member_id.id;
2594 serialize(id);
2595 uint32_t msize = 0;
2596 serialize(msize);
2598}
2599
2601 const MemberId&,
2602 size_t member_serialized_size)
2603{
2604 jump(sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t));
2605 uint32_t msize = static_cast<uint32_t>(member_serialized_size);
2606 serialize(msize);
2607}
2608
2610 const MemberId& member_id,
2611 size_t member_serialized_size)
2612{
2613 assert(0x3F00 >= member_id.id);
2614 assert(std::numeric_limits<uint16_t>::max() >= member_serialized_size );
2615
2616 uint16_t flags_and_member_id = static_cast<uint16_t>(member_id.must_understand ? 0x4000 : 0x0) |
2617 static_cast<uint16_t>(member_id.id);
2618 serialize(flags_and_member_id);
2619 uint16_t size = static_cast<uint16_t>(member_serialized_size);
2620 serialize(size);
2621 memmove(&offset_, &offset_ + 8, member_serialized_size);
2622}
2623
2625 const MemberId& member_id,
2626 size_t member_serialized_size)
2627{
2628 if (0 < (end_ - offset_ - member_serialized_size - 11))
2629 {
2630 memmove(&offset_ + 12, &offset_ + 4, member_serialized_size);
2631 }
2632 else
2633 {
2635 }
2636 uint16_t flags_and_extended_pid = static_cast<uint16_t>(member_id.must_understand ? 0x4000 : 0x0) |
2637 static_cast<uint16_t>(PID_EXTENDED);
2638 serialize(flags_and_extended_pid);
2639 uint16_t size = PID_EXTENDED_LENGTH;
2640 serialize(size);
2641 uint32_t id = member_id.id;
2642 serialize(id);
2643 uint32_t msize = static_cast<uint32_t>(member_serialized_size);
2644 serialize(msize);
2645}
2646
2648 MemberId& member_id,
2649 Cdr::state& current_state)
2650{
2651 bool ret_value = true;
2653 uint16_t flags_and_member_id = 0;
2654 deserialize(flags_and_member_id);
2655 member_id.must_understand = (flags_and_member_id & 0x4000);
2656 uint16_t id = (flags_and_member_id & 0x3FFF);
2657
2658
2659 if (PID_EXTENDED > id)
2660 {
2661 member_id.id = id;
2662 uint16_t size = 0;
2663 deserialize(size);
2664 current_state.member_size_ = size;
2667 }
2668 else if (PID_EXTENDED == id) // PID_EXTENDED
2669 {
2670 uint16_t size = 0;
2671 deserialize(size);
2672 if (PID_EXTENDED_LENGTH != size)
2673 {
2674 throw BadParamException("PID_EXTENDED comes with a size different than 8");
2675 }
2676 uint32_t mid = 0;
2677 deserialize(mid);
2678 member_id.id = mid;
2679 deserialize(current_state.member_size_);
2682 }
2683 else if (PID_SENTINEL == id) // PID_SENTINEL
2684 {
2685 uint16_t size = 0;
2686 deserialize(size);
2687 if (0 != size)
2688 {
2689 throw BadParamException("PID_SENTINEL comes with a size different than 0");
2690 }
2691 current_state.member_size_ = size;
2692 ret_value = false;
2693 }
2694
2695 return ret_value;
2696}
2697
2699 const MemberId& member_id)
2700{
2701 assert(0x10000000 > member_id.id);
2702
2703 uint32_t flags_and_member_id = (member_id.must_understand ? 0x80000000 : 0x0) | member_id.id;
2704 serialize(flags_and_member_id);
2705}
2706
2708 const MemberId& member_id,
2709 size_t member_serialized_size)
2710{
2711 assert(0x10000000 > member_id.id);
2712 assert(8 >= member_serialized_size);
2713
2714 uint32_t lc = get_short_lc(member_serialized_size);
2715 uint32_t flags_and_member_id = (member_id.must_understand ? 0x80000000 : 0x0) | lc | member_id.id;
2716 serialize(flags_and_member_id);
2717}
2718
2720 const MemberId& member_id)
2721{
2722 assert(0x10000000 > member_id.id);
2723
2724 uint32_t flags_and_member_id = (member_id.must_understand ? 0x80000000 : 0x0) | member_id.id;
2725 serialize(flags_and_member_id);
2726 uint32_t size = 0;
2727 serialize(size);
2728}
2729
2731 const MemberId& member_id,
2732 size_t member_serialized_size)
2733{
2734 assert(0x10000000 > member_id.id);
2735
2736 uint32_t lc = 0 == member_serialized_size ? get_long_lc(serialized_member_size_) : 0x40000000;
2737 uint32_t flags_and_member_id = (member_id.must_understand ? 0x80000000 : 0x0) | lc | member_id.id;
2738 serialize(flags_and_member_id);
2739 if (0 < member_serialized_size)
2740 {
2741 uint32_t size = static_cast<uint32_t>(member_serialized_size);
2742 serialize(size);
2743 }
2744}
2745
2747 const MemberId& member_id,
2748 size_t member_serialized_size)
2749{
2750 assert(0x10000000 > member_id.id);
2751 assert(8 >= member_serialized_size);
2752
2753 uint32_t lc = get_short_lc(member_serialized_size);
2754 uint32_t flags_and_member_id = (member_id.must_understand ? 0x80000000 : 0x0) | lc | member_id.id;
2755 serialize(flags_and_member_id);
2756 memmove(&offset_, &offset_ + 4, member_serialized_size);
2757}
2758
2760 const MemberId& member_id,
2761 size_t member_serialized_size)
2762{
2763 assert(0x10000000 > member_id.id);
2764
2765 if (0 < (end_ - offset_ - member_serialized_size - 7))
2766 {
2767 memmove(&offset_ + 8, &offset_ + 4, member_serialized_size);
2768 }
2769 else
2770 {
2772 }
2773 uint32_t lc = get_long_lc(serialized_member_size_);
2774 uint32_t flags_and_member_id = (member_id.must_understand ? 0x80000000 : 0x0) | lc | member_id.id;
2775 serialize(flags_and_member_id);
2776 uint32_t size = static_cast<uint32_t>(member_serialized_size);
2777 serialize(size);
2778}
2779
2781 const MemberId& member_id,
2782 const FastBuffer::iterator& offset)
2783{
2784 assert(0x10000000 > member_id.id);
2785
2786 memmove(&offset_ + 4, &offset_ + 8, offset - offset_ - 8);
2787 uint32_t lc = get_long_lc(serialized_member_size_);
2788 uint32_t flags_and_member_id = (member_id.must_understand ? 0x80000000 : 0x0) | lc | member_id.id;
2789 serialize(flags_and_member_id);
2790}
2791
2793 const MemberId& member_id,
2794 bool is_present,
2795 Cdr::state& current_state,
2796 Cdr::XCdrHeaderSelection header_selection)
2797{
2798 static_cast<void>(is_present);
2799 assert(is_present);
2800 assert(MEMBER_ID_INVALID != member_id);
2801 assert(MEMBER_ID_INVALID == next_member_id_ || member_id == next_member_id_);
2802 assert(current_state == Cdr::state(*this));
2805
2807 {
2808 if (0x3F00 >= member_id.id)
2809 {
2810 switch (header_selection)
2811 {
2816 break;
2821 break;
2822 }
2823 }
2824 else
2825 {
2826 switch (header_selection)
2827 {
2833 break;
2834 default:
2835 throw BadParamException(
2836 "Cannot encode XCDRv1 ShortMemberHeader when member_id is bigger than 0x3F00");
2837 }
2838 }
2839 current_state.header_selection_ = header_selection;
2840 }
2841 current_state.next_member_id_ = member_id;
2843
2844 return *this;
2845}
2846
2848 const Cdr::state& current_state)
2849{
2850 assert(MEMBER_ID_INVALID != current_state.next_member_id_);
2853
2855 {
2856 auto last_offset = offset_;
2857 auto member_origin = origin_;
2858 set_state(current_state);
2860 const size_t member_serialized_size = last_offset - offset_ -
2861 (current_state.header_serialized_ == XCdrHeaderSelection::SHORT_HEADER ? 4 : 12);
2862 if (member_serialized_size > std::numeric_limits<uint16_t>::max())
2863 {
2864 switch (current_state.header_serialized_)
2865 {
2868 {
2869 xcdr1_change_to_long_member_header(current_state.next_member_id_, member_serialized_size);
2870 member_origin += 8;
2871 }
2872 else
2873 {
2874 throw BadParamException(
2875 "Cannot encode XCDRv1 ShortMemberHeader when serialized member size is greater than 0xFFFF");
2876 }
2877 break;
2879 xcdr1_end_long_member_header(current_state.next_member_id_, member_serialized_size);
2880 break;
2881 default:
2882 assert(false); // header_serialized_ must have only SHORT_HEADER or LONG_HEADER
2883 }
2884 }
2885 else
2886 {
2887 switch (current_state.header_serialized_)
2888 {
2890 xcdr1_end_short_member_header(current_state.next_member_id_, member_serialized_size);
2891 break;
2893 if (LONG_HEADER == current_state.header_selection_ ||
2894 0x3F00 < current_state.next_member_id_.id)
2895 {
2896 xcdr1_end_long_member_header(current_state.next_member_id_, member_serialized_size);
2897 }
2898 else if (AUTO_WITH_LONG_HEADER_BY_DEFAULT == current_state.header_selection_)
2899 {
2900 xcdr1_change_to_short_member_header(current_state.next_member_id_, member_serialized_size);
2901 member_origin -= 8;
2902 }
2903 break;
2904 default:
2905 assert(false); // header_serialized_ must have only SHORT_HEADER or LONG_HEADER
2906 }
2907 }
2908 origin_ = member_origin; // Don't POP(origin)
2909 jump(member_serialized_size);
2910 }
2911
2913
2914 return *this;
2915}
2916
2918 const MemberId& member_id,
2919 bool is_present,
2920 Cdr::state& current_state,
2921 Cdr::XCdrHeaderSelection header_selection)
2922{
2923 assert(MEMBER_ID_INVALID != member_id);
2924 assert(MEMBER_ID_INVALID == next_member_id_ || member_id == next_member_id_);
2925 assert(current_state == Cdr::state(*this));
2928
2930 {
2931 if (0x3F00 >= member_id.id)
2932 {
2933 switch (header_selection)
2934 {
2939 break;
2944 break;
2945 }
2946 }
2947 else
2948 {
2949 switch (header_selection)
2950 {
2956 break;
2957 default:
2958 throw BadParamException(
2959 "Cannot encode XCDRv1 ShortMemberHeader when member_id is bigger than 0x3F00");
2960 }
2961 }
2962 current_state.header_selection_ = header_selection;
2963 }
2964 current_state.member_size_ = is_present ? 1 : 0;
2965 current_state.next_member_id_ = member_id;
2967
2968 return *this;
2969}
2970
2972 const Cdr::state& current_state)
2973{
2974 assert(MEMBER_ID_INVALID != current_state.next_member_id_);
2977
2978 if (0 < current_state.member_size_)
2979 {
2980 auto last_offset = offset_;
2981 auto member_origin = origin_;
2982 set_state(current_state);
2984 const size_t member_serialized_size = last_offset - offset_ -
2985 (current_state.header_serialized_ == XCdrHeaderSelection::SHORT_HEADER ? 4 : 12);
2986 if (member_serialized_size > std::numeric_limits<uint16_t>::max())
2987 {
2988 switch (current_state.header_serialized_)
2989 {
2992 {
2993 xcdr1_change_to_long_member_header(current_state.next_member_id_, member_serialized_size);
2994 member_origin += 8;
2995 }
2996 else
2997 {
2998 throw BadParamException(
2999 "Cannot encode XCDRv1 ShortMemberHeader when serialized member size is greater than 0xFFFF");
3000 }
3001 break;
3003 xcdr1_end_long_member_header(current_state.next_member_id_, member_serialized_size);
3004 break;
3005 default:
3006 assert(false); // header_serialized_ must have only SHORT_HEADER or LONG_HEADER
3007 }
3008 }
3009 else
3010 {
3011 switch (current_state.header_serialized_)
3012 {
3014 xcdr1_end_short_member_header(current_state.next_member_id_, member_serialized_size);
3015 break;
3017 if (LONG_HEADER == current_state.header_selection_ ||
3018 0x3F00 < current_state.next_member_id_.id)
3019 {
3020 xcdr1_end_long_member_header(current_state.next_member_id_, member_serialized_size);
3021 }
3022 else if (AUTO_WITH_LONG_HEADER_BY_DEFAULT == current_state.header_selection_)
3023 {
3024 xcdr1_change_to_short_member_header(current_state.next_member_id_, member_serialized_size);
3025 member_origin -= 8;
3026 }
3027 break;
3028 default:
3029 assert(false); // header_serialized_ must have only SHORT_HEADER or LONG_HEADER
3030 }
3031 }
3032 origin_ = member_origin; // Don't POP(origin)
3033 jump(member_serialized_size);
3034 }
3035
3037
3038 return *this;
3039}
3040
3042 const MemberId& member_id,
3043 bool is_present,
3044 Cdr::state& current_state,
3045 XCdrHeaderSelection header_selection)
3046{
3047 assert(MEMBER_ID_INVALID != member_id);
3048 assert(MEMBER_ID_INVALID == next_member_id_ || member_id == next_member_id_);
3049 assert(current_state == Cdr::state(*this));
3053
3055 {
3056 if (0x10000000 <= member_id.id)
3057 {
3058 throw BadParamException("Cannot serialize a member identifier equal or greater than 0x10000000");
3059 }
3060
3061 switch (header_selection)
3062 {
3067 break;
3072 break;
3073 }
3074 current_state.header_selection_ = header_selection;
3075 }
3076
3077 current_state.member_size_ = is_present ? 1 : 0;
3078 current_state.next_member_id_ = member_id;
3080
3081 return *this;
3082}
3083
3085 const Cdr::state& current_state)
3086{
3087 assert(MEMBER_ID_INVALID != current_state.next_member_id_);
3091
3093 {
3094 auto last_offset = offset_;
3095 set_state(current_state);
3096 make_alignment(alignment(sizeof(uint32_t)));
3097 if (NO_SERIALIZED_MEMBER_SIZE == serialized_member_size_)
3098 {
3099 const size_t member_serialized_size = last_offset - offset_ -
3100 (current_state.header_serialized_ == XCdrHeaderSelection::SHORT_HEADER ? 4 : 8);
3101 if (8 < member_serialized_size || 0xFFFFFFFFu == get_short_lc(member_serialized_size))
3102 {
3103 switch (current_state.header_serialized_)
3104 {
3107 {
3108 xcdr2_change_to_long_member_header(current_state.next_member_id_, member_serialized_size);
3109 }
3110 else
3111 {
3112 throw BadParamException("Cannot encode XCDRv2 LongMemberHeader");
3113 }
3114 break;
3116 xcdr2_end_long_member_header(current_state.next_member_id_, member_serialized_size);
3117 break;
3118 default:
3119 assert(false); // header_serialized_ must have only SHORT_HEADER or LONG_HEADER
3120 }
3121 }
3122 else
3123 {
3124 switch (current_state.header_serialized_)
3125 {
3127 xcdr2_end_short_member_header(current_state.next_member_id_, member_serialized_size);
3128 break;
3131 {
3132 xcdr2_change_to_short_member_header(current_state.next_member_id_, member_serialized_size);
3133 }
3134 else
3135 {
3136 xcdr2_end_long_member_header(current_state.next_member_id_, member_serialized_size);
3137 }
3138 break;
3139 default:
3140 assert(false); // header_serialized_ must have only SHORT_HEADER or LONG_HEADER
3141 }
3142 }
3143
3144 jump(member_serialized_size);
3145 }
3146 else
3147 {
3148 // Use inner type DHEADER as NEXTINT
3149 switch (current_state.header_serialized_)
3150 {
3153 {
3155 offset_ = last_offset;
3156 }
3157 else
3158 {
3159 throw BadParamException("Cannot encode XCDRv2 LongMemberHeader");
3160 }
3161 break;
3163 xcdr2_shrink_to_long_member_header(current_state.next_member_id_, last_offset);
3164 offset_ = last_offset;
3165 offset_ -= sizeof(uint32_t);
3166 break;
3167 default:
3168 assert(false); // header_serialized_ must have only SHORT_HEADER or LONG_HEADER
3169 }
3170
3171 last_data_size_ = 0;
3172 }
3173 }
3174
3176 serialized_member_size_ = NO_SERIALIZED_MEMBER_SIZE;
3177
3178 return *this;
3179}
3180
3182 MemberId& member_id,
3183 Cdr::state& current_state)
3184{
3185 uint32_t flags_and_member_id = 0;
3186 deserialize(flags_and_member_id);
3187 member_id.must_understand = (flags_and_member_id & 0x80000000);
3188 uint32_t mid = (flags_and_member_id & 0x0FFFFFFF);
3189 uint32_t lc = (flags_and_member_id & 0x70000000) >> 28;
3190
3191 member_id.id = mid;
3192
3193 if (4 > lc)
3194 {
3195 switch (lc)
3196 {
3197 case 0:
3198 current_state.member_size_ = 1;
3199 break;
3200 case 1:
3201 current_state.member_size_ = 2;
3202 break;
3203 case 2:
3204 current_state.member_size_ = 4;
3205 break;
3206 case 3:
3207 current_state.member_size_ = 8;
3208 break;
3209 default:
3210 break;
3211 }
3213 }
3214 else if (4 == lc)
3215 {
3216 uint32_t size = 0;
3217 deserialize(size);
3218 current_state.member_size_ = size;
3220 }
3221 else
3222 {
3223 uint32_t size = 0;
3224 deserialize(size);
3225 current_state.member_size_ = 4 + (size * (5 == lc ? 1 : (6 == lc ? 4 : 8)));
3226 current_state.header_serialized_ = XCdrHeaderSelection::SHORT_HEADER; // Avoid take into account DHEADER after.
3227 offset_ -= sizeof(uint32_t);
3228 }
3229}
3230
3232 Cdr::state& current_state,
3233 EncodingAlgorithmFlag type_encoding) noexcept
3234{
3235 assert(current_state == Cdr::state(*this));
3236 assert(EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_ ||
3237 EncodingAlgorithmFlag::PL_CDR == current_encoding_);
3238 assert(EncodingAlgorithmFlag::PLAIN_CDR == type_encoding ||
3239 EncodingAlgorithmFlag::PL_CDR == type_encoding);
3240 current_state.previous_encoding_ = current_encoding_;
3241 current_encoding_ = type_encoding;
3242 return *this;
3243}
3244
3262
3264 Cdr::state& current_state,
3265 EncodingAlgorithmFlag type_encoding)
3266{
3267 assert(current_state == Cdr::state(*this));
3271 assert(EncodingAlgorithmFlag::PLAIN_CDR2 == type_encoding ||
3272 EncodingAlgorithmFlag::DELIMIT_CDR2 == type_encoding ||
3273 EncodingAlgorithmFlag::PL_CDR2 == type_encoding);
3274 if (EncodingAlgorithmFlag::PLAIN_CDR2 != type_encoding)
3275 {
3276 uint32_t dheader {0};
3277 serialize(dheader);
3278 }
3279 serialized_member_size_ = NO_SERIALIZED_MEMBER_SIZE; // Avoid error when serializing arrays, sequences, etc..
3280 current_state.previous_encoding_ = current_encoding_;
3281 current_encoding_ = type_encoding;
3282 return *this;
3283}
3284
3286 const Cdr::state& current_state)
3287{
3292 {
3293 auto last_offset = offset_;
3294 set_state(current_state);
3295 const size_t member_serialized_size = last_offset - offset_ /*DHEADER ->*/ - 4 - alignment(4);
3296 serialize(static_cast<uint32_t>(member_serialized_size));
3297 jump(member_serialized_size);
3298 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
3299 }
3300 current_encoding_ = current_state.previous_encoding_;
3301 return *this;
3302}
3303
3305 EncodingAlgorithmFlag type_encoding,
3306 std::function<bool (Cdr&, const MemberId&)> functor)
3307{
3308 assert(EncodingAlgorithmFlag::PLAIN_CDR == type_encoding ||
3309 EncodingAlgorithmFlag::PL_CDR == type_encoding);
3310 Cdr::state current_state(*this);
3311 current_encoding_ = type_encoding;
3312
3314 {
3315 while (xcdr1_deserialize_member_header(next_member_id_, current_state))
3316 {
3317 auto prev_offset = offset_;
3318 bool deser_value = functor(*this, next_member_id_);
3319
3320 if (!deser_value)
3321 {
3323 {
3324 throw BadParamException("Cannot deserialize a member with flag must_understand");
3325 }
3326 else
3327 {
3328 jump(current_state.member_size_);
3329 }
3330 }
3331
3332 if (current_state.member_size_ != offset_ - prev_offset)
3333 {
3334 throw BadParamException(
3335 "Member size provided by member header is not equal to the real decoded member size");
3336 }
3337 }
3338 }
3339 else
3340 {
3342
3343 while (offset_ != end_ && functor(*this, next_member_id_))
3344 {
3346 }
3347 }
3348
3349 next_member_id_ = current_state.next_member_id_;
3350 current_encoding_ = current_state.previous_encoding_;
3351
3352 return *this;
3353}
3354
3356 EncodingAlgorithmFlag type_encoding,
3357 std::function<bool (Cdr&, const MemberId&)> functor)
3358{
3359 assert(EncodingAlgorithmFlag::PLAIN_CDR2 == type_encoding ||
3360 EncodingAlgorithmFlag::DELIMIT_CDR2 == type_encoding ||
3361 EncodingAlgorithmFlag::PL_CDR2 == type_encoding);
3362
3363
3364 if (EncodingAlgorithmFlag::PLAIN_CDR2 != type_encoding)
3365 {
3366 uint32_t dheader {0};
3367 deserialize(dheader);
3368
3369 Cdr::state current_state(*this);
3370 current_encoding_ = type_encoding;
3371
3373 {
3374 while (offset_ - current_state.offset_ != dheader)
3375 {
3376 if (offset_ - current_state.offset_ > dheader)
3377 {
3378 throw BadParamException("Member size greater than size specified by DHEADER");
3379 }
3380
3381 auto offset = offset_;
3382
3384 bool deser_value = functor(*this, next_member_id_);
3385 if (!deser_value)
3386 {
3388 {
3389 throw BadParamException("Cannot deserialize a member with flag must_understand");
3390 }
3391 else
3392 {
3393 jump(current_state.member_size_);
3394 }
3395 }
3396
3397 if (!(0 == current_state.member_size_ &&
3398 0 == offset_ - offset) &&
3399 !(0 < current_state.member_size_ &&
3400 current_state.member_size_ == offset_ - offset -
3401 alignment_on_state(current_state.origin_, offset, sizeof(uint32_t)) -
3402 (XCdrHeaderSelection::SHORT_HEADER == current_state.header_serialized_ ? 4 : 8)))
3403 {
3404 throw BadParamException(
3405 "Member size provided by member header is not equal to the real decoded size");
3406 }
3407 }
3408
3409 next_member_id_ = current_state.next_member_id_;
3410 }
3411 else
3412 {
3414
3415 while (offset_ - current_state.offset_ < dheader && functor(*this, next_member_id_))
3416 {
3418 }
3419 size_t jump_size = dheader - (offset_ - current_state.offset_);
3420 jump(jump_size);
3421
3422 next_member_id_ = current_state.next_member_id_;
3423 }
3424
3425 current_encoding_ = current_state.previous_encoding_;
3426 }
3427 else
3428 {
3429 Cdr::state current_state(*this);
3430 current_encoding_ = type_encoding;
3432
3433 while (offset_ != end_ && functor(*this, next_member_id_))
3434 {
3436 }
3437
3438 next_member_id_ = current_state.next_member_id_;
3439 current_encoding_ = current_state.previous_encoding_;
3440 }
3441
3442 return *this;
3443}
3444
3446 const MemberId&,
3447 bool,
3448 Cdr::state&,
3450{
3452 return *this;
3453}
3454
3456 const Cdr::state&)
3457{
3459 return *this;
3460}
3461
3463 Cdr::state& current_state,
3464 EncodingAlgorithmFlag type_encoding)
3465{
3466 static_cast<void>(type_encoding);
3467 assert(EncodingAlgorithmFlag::PLAIN_CDR == type_encoding);
3468 current_state.previous_encoding_ = current_encoding_;
3469 current_encoding_ = type_encoding;
3470 return *this;
3471}
3472
3474 const Cdr::state& current_state)
3475{
3476 current_encoding_ = current_state.previous_encoding_;
3477 return *this;
3478}
3479
3481 EncodingAlgorithmFlag type_encoding,
3482 std::function<bool (Cdr&, const MemberId&)> functor)
3483{
3484 static_cast<void>(type_encoding);
3485 assert(EncodingAlgorithmFlag::PLAIN_CDR == type_encoding);
3486
3487 Cdr::state current_state(*this);
3489
3490 while (offset_ != end_ && functor(*this, next_member_id_))
3491 {
3493 }
3494
3495 next_member_id_ = current_state.next_member_id_;
3496 return *this;
3497}
3498
3500{
3501 Cdr::state dheader_state(*this);
3502
3504 {
3505 // Serialize DHEADER
3506 uint32_t dheader {0};
3507 serialize(dheader);
3508 }
3509
3510 return dheader_state;
3511}
3512
3514 const Cdr::state& dheader_state)
3515{
3517 {
3518 auto offset = offset_;
3519 Cdr::state state_after(*this);
3520 set_state(dheader_state);
3521 size_t dheader = offset - offset_ - (4 + alignment(sizeof(uint32_t))); /* DHEADER */
3522 serialize(static_cast<uint32_t>(dheader));
3523 set_state(state_after);
3524 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
3525 }
3526}
3527
3528} // namespace fastcdr
3529} // namespace eprosima
uint32_t size_to_uint32(size_t val)
Definition FastBuffer.h:25
T c_str(T... args)
This class stores the current state of a CDR serialization.
Definition Cdr.h:106
const FastBuffer::iterator origin_
The position from the alignment is calculated, when the state was created.
Definition Cdr.h:133
Cdr_DllAPI state(const Cdr &cdr)
Default constructor.
Definition Cdr.cpp:98
size_t last_data_size_
Stores the last datasize serialized/deserialized when the state was created.
Definition Cdr.h:139
const FastBuffer::iterator offset_
The position in the buffer when the state was created.
Definition Cdr.h:130
EncodingAlgorithmFlag previous_encoding_
Not related with the state. Used by encoding algorithms to store the previous encoding algorithm.
Definition Cdr.h:154
uint32_t member_size_
Not related with the state. Used by encoding algorithms to set the encoded member size.
Definition Cdr.h:145
bool swap_bytes_
This attribute specifies if it is needed to swap the bytes when the state is created.
Definition Cdr.h:136
XCdrHeaderSelection header_selection_
Not related with the state. Used by encoding algorithms to store the selected member header version.
Definition Cdr.h:148
MemberId next_member_id_
Not related with the state. Next member id which will be encoded.
Definition Cdr.h:142
Cdr_DllAPI bool operator==(const state &other_state) const
Compares two states.
Definition Cdr.cpp:120
XCdrHeaderSelection header_serialized_
Not related with the state. Used by encoding algorithms to store the allocated member header version.
Definition Cdr.h:151
This class offers an interface to serialize/deserialize some basic types using CDR protocol inside an...
Definition Cdr.h:69
uint8_t endianness_
The endianness that will be applied over the buffer.
Definition Cdr.h:3485
Cdr & xcdr2_end_serialize_type(const Cdr::state &current_state)
Tells to the encoder to finish the encoding of the type.
Definition Cdr.cpp:3285
end_serialize_member_functor end_serialize_member_
Definition Cdr.h:3442
Cdr & xcdr2_deserialize_type(EncodingAlgorithmFlag type_encoding, std::function< bool(Cdr &, const MemberId &)> functor)
Tells to the encoder a new type and its members start to be decoded according to XCDRv2.
Definition Cdr.cpp:3355
void reset_alignment()
This function resets the alignment to the current position in the buffer.
Definition Cdr.h:306
Cdr_DllAPI std::array< uint8_t, 2 > get_dds_cdr_options() const
This function returns the option flags when the CDR type is eprosima::fastcdr::DDS_CDR.
Definition Cdr.cpp:375
Cdr & xcdr1_end_serialize_member(const Cdr::state &current_state)
Tells to the encoder to finish the encoding of the member.
Definition Cdr.cpp:2847
void xcdr2_change_to_long_member_header(const MemberId &member_id, size_t member_serialized_size)
Changes the previous encoded long header to a short header according to XCDRv2.
Definition Cdr.cpp:2759
Cdr & serialize(const _T &value)
Encodes the value of a type into the buffer.
Definition Cdr.h:381
void xcdr2_end_short_member_header(const MemberId &member_id, size_t member_serialized_size)
Finish the encoding of a short member header of a member according to XCDRv2.
Definition Cdr.cpp:2707
Cdr_DllAPI bool set_encoding_flag(EncodingAlgorithmFlag encoding_flag)
Sets the EncodingAlgorithmFlag for the encapsulation when the CDR type is CdrVersion::DDS_CDR,...
Definition Cdr.cpp:358
Cdr_DllAPI bool move_alignment_forward(size_t num_bytes)
This function moves the alignment forward.
Definition Cdr.cpp:478
std::array< uint8_t, 2 > options_
This attribute stores the option flags when the CDR type is DDS_CDR;.
Definition Cdr.h:3482
static size_t alignment(size_t current_alignment, size_t data_size)
Returns the number of bytes needed to align a position to certain data size.
Definition Cdr.h:275
EncodingAlgorithmFlag encoding_flag_
Stores the main encoding algorithm.
Definition Cdr.h:3476
Cdr_DllAPI Cdr & deserialize_bool_array(std::vector< bool > &vector_t)
Definition Cdr.cpp:2344
Cdr_DllAPI Cdr & deserialize_bool_sequence(std::vector< bool > &vector_t)
Definition Cdr.cpp:2384
Cdr_DllAPI const char * read_string(uint32_t &length)
Definition Cdr.cpp:1735
Cdr_DllAPI const std::wstring read_wstring(uint32_t &length)
Definition Cdr.cpp:1766
Cdr & cdr_deserialize_type(EncodingAlgorithmFlag type_encoding, std::function< bool(Cdr &, const MemberId &)> functor)
Definition Cdr.cpp:3480
Cdr_DllAPI state allocate_xcdrv2_dheader()
Encodes an empty DHEADER if the encoding version is XCDRv2. After serializing the members's type,...
Definition Cdr.cpp:3499
Cdr_DllAPI Cdr(FastBuffer &cdr_buffer, const Endianness endianness=DEFAULT_ENDIAN, const CdrVersion cdr_version=XCDRv2)
This constructor creates an eprosima::fastcdr::Cdr object that can serialize/deserialize the assigned...
Definition Cdr.cpp:133
@ AUTO_WITH_SHORT_HEADER_BY_DEFAULT
Initially a short member header is allocated but can be changed to the longer version.
Definition Cdr.h:97
@ LONG_HEADER
Initially a long member header is allocated and cannot be changed.
Definition Cdr.h:95
@ SHORT_HEADER
Initially a short member header is allocated and cannot be changed. This option may cause an exceptio...
Definition Cdr.h:93
@ AUTO_WITH_LONG_HEADER_BY_DEFAULT
Initially a long member header is allocated but can be changed to the shorter version.
Definition Cdr.h:99
size_t align64_
Align for types equal or greater than 64bits.
Definition Cdr.h:3506
Cdr_DllAPI char * get_buffer_pointer()
This function returns the pointer to the current used buffer.
Definition Cdr.cpp:435
Cdr & xcdr2_begin_serialize_member(const MemberId &member_id, bool is_present, Cdr::state &current_state, XCdrHeaderSelection header_selection)
Tells to the encoder a member starts to be encoded according to XCDRv2.
Definition Cdr.cpp:3041
Cdr_DllAPI Cdr & begin_serialize_type(Cdr::state &current_state, EncodingAlgorithmFlag type_encoding)
Tells to the encoder a new type and its members starts to be encoded.
Definition Cdr.cpp:2234
end_serialize_member_functor end_serialize_opt_member_
Definition Cdr.h:3453
Cdr & cdr_end_serialize_member(const Cdr::state &current_state)
Definition Cdr.cpp:3455
Cdr_DllAPI Cdr & serialize_encapsulation()
This function writes the encapsulation of the CDR stream. If the CDR stream should contain an encapsu...
Definition Cdr.cpp:302
bool resize(size_t min_size_inc)
This function resizes the internal buffer. It only applies if the FastBuffer object was created with ...
Definition Cdr.cpp:493
@ SERIALIZED_MEMBER_SIZE_4
Serialized member size in a DHEADER.
Definition Cdr.h:3516
@ SERIALIZED_MEMBER_SIZE
Default. No serialized member size in a DHEADER.
Definition Cdr.h:3515
@ SERIALIZED_MEMBER_SIZE_8
Serialized member size (which is a multiple of 4) in a DHEADER.
Definition Cdr.h:3517
Cdr & xcdr1_begin_serialize_opt_member(const MemberId &member_id, bool is_present, Cdr::state &current_state, XCdrHeaderSelection header_selection)
Tells to the encoder a member starts to be encoded according to XCDRv1.
Definition Cdr.cpp:2917
FastBuffer::iterator end_
The last position in the buffer;.
Definition Cdr.h:3500
void xcdr2_deserialize_member_header(MemberId &member_id, Cdr::state &current_state)
Decodes a member header according to XCDRv2.
Definition Cdr.cpp:3181
Cdr & xcdr1_deserialize_type(EncodingAlgorithmFlag type_encoding, std::function< bool(Cdr &, const MemberId &)> functor)
Tells to the encoder a new type and its members start to be decoded according to XCDRv1.
Definition Cdr.cpp:3304
static Cdr_DllAPI const Endianness DEFAULT_ENDIAN
Default endianess in the system.
Definition Cdr.h:84
Cdr & xcdr1_begin_serialize_type(Cdr::state &current_state, EncodingAlgorithmFlag type_encoding) noexcept
Tells to the encoder a new type and its members start to be encoded according to XCDRv1.
Definition Cdr.cpp:3231
void xcdr1_end_short_member_header(const MemberId &member_id, size_t member_serialized_size)
Finish the encoding of a short member header of a member according to XCDRv1.
Definition Cdr.cpp:2570
void xcdr2_serialize_long_member_header(const MemberId &member_id)
Encodes a long member header of a member according to XCDRv2.
Definition Cdr.cpp:2719
begin_serialize_member_functor begin_serialize_member_
Definition Cdr.h:3438
void reset_callbacks()
Resets the internal callbacks depending on the current selected Cdr version.
Definition Cdr.cpp:164
Cdr & xcdr1_begin_serialize_member(const MemberId &member_id, bool is_present, Cdr::state &current_state, XCdrHeaderSelection header_selection)
Tells to the encoder a member starts to be encoded according to XCDRv1.
Definition Cdr.cpp:2792
void xcdr1_change_to_short_member_header(const MemberId &member_id, size_t member_serialized_size)
Changes the previous encoded long header to a short header according to XCDRv1.
Definition Cdr.cpp:2609
FastBuffer & cdr_buffer_
Reference to the buffer that will be serialized/deserialized.
Definition Cdr.h:3470
begin_serialize_opt_member_functor begin_serialize_opt_member_
Definition Cdr.h:3449
void xcdr1_serialize_short_member_header(const MemberId &member_id)
XCDR extensions.
Definition Cdr.cpp:2555
Cdr & cdr_begin_serialize_type(Cdr::state &current_state, EncodingAlgorithmFlag type_encoding)
Definition Cdr.cpp:3462
Cdr & serialize_array(const _T *value, size_t num_elements)
Encodes an array of a type not managed by this encoder into the buffer.
Definition Cdr.h:946
Cdr & xcdr1_end_serialize_opt_member(const Cdr::state &current_state)
Tells to the encoder to finish the encoding of the member.
Definition Cdr.cpp:2971
Cdr_DllAPI bool jump(size_t num_bytes)
This function skips a number of bytes in the CDR stream buffer.
Definition Cdr.cpp:420
state initial_state_
Stores the initial state.
Definition Cdr.h:3523
FastBuffer::iterator origin_
The position from where the alignment is calculated.
Definition Cdr.h:3497
Cdr_DllAPI void set_dds_cdr_options(const std::array< uint8_t, 2 > &options)
This function sets the option flags when the CDR type is eprosima::fastcdr::DDS_CDR.
Definition Cdr.cpp:380
uint32_t get_long_lc(SerializedMemberSizeForNextInt serialized_member_size)
Definition Cdr.cpp:50
size_t last_data_size_
Stores the last datasize serialized/deserialized. It's used to optimize.
Definition Cdr.h:3491
Cdr & deserialize_array(_T *value, size_t num_elements)
Decodes an array of a type not managed by this encoder from the buffer.
Definition Cdr.h:2134
begin_serialize_type_functor begin_serialize_type_
Definition Cdr.h:3458
Cdr & deserialize(_T &value)
Decodes the value of a type from the buffer.
Definition Cdr.h:1417
bool encapsulation_serialized_
Whether the encapsulation was serialized.
Definition Cdr.h:3526
Cdr_DllAPI Cdr & serialize_bool_array(const std::vector< bool > &vector_t)
Definition Cdr.cpp:2266
Cdr & cdr_end_serialize_type(const Cdr::state &current_state)
Definition Cdr.cpp:3473
Cdr_DllAPI Cdr & deserialize_type(EncodingAlgorithmFlag type_encoding, std::function< bool(Cdr &, const MemberId &)> functor)
Tells to the encoder a new type and its members starts to be decoded.
Definition Cdr.cpp:2247
Cdr_DllAPI char * get_current_position()
This function returns the current position in the CDR stream.
Definition Cdr.cpp:440
Cdr_DllAPI EncodingAlgorithmFlag get_encoding_flag() const
Returns the EncodingAlgorithmFlag set in the encapsulation when the CDR type is CdrVersion::DDS_CDR,...
Definition Cdr.cpp:353
Cdr_DllAPI CdrVersion get_cdr_version() const
Retrieves the CdrVersion used by the instance.
Definition Cdr.cpp:348
Cdr_DllAPI void change_endianness(Endianness endianness)
This function sets the current endianness used by the CDR type.
Definition Cdr.cpp:405
Cdr & xcdr2_begin_serialize_type(Cdr::state &current_state, EncodingAlgorithmFlag type_encoding)
Tells to the encoder a new type and its members start to be encoded according to XCDRv2.
Definition Cdr.cpp:3263
void xcdr1_end_long_member_header(const MemberId &member_id, size_t member_serialized_size)
Finish the encoding of a long member header of a member according to XCDRv1.
Definition Cdr.cpp:2600
Cdr_DllAPI void reset()
This function resets the current position in the buffer to the beginning.
Definition Cdr.cpp:465
void xcdr2_shrink_to_long_member_header(const MemberId &member_id, const FastBuffer::iterator &offset)
Join the previous encoded long header with the next DHEADER which was serialized after.
Definition Cdr.cpp:2780
Cdr_DllAPI Cdr & deserialize_wstring_sequence(std::wstring *&sequence_t, size_t &num_elements)
Definition Cdr.cpp:2490
Endianness
This enumeration represents endianness types.
Definition Cdr.h:76
Cdr & xcdr1_end_serialize_type(const Cdr::state &current_state)
Tells to the encoder to finish the encoding of the type.
Definition Cdr.cpp:3245
uint32_t get_short_lc(size_t member_serialized_size)
Definition Cdr.cpp:73
enum eprosima::fastcdr::Cdr::SerializedMemberSizeForNextInt NO_SERIALIZED_MEMBER_SIZE
Specifies if a DHEADER was serialized. Used to optimize XCDRv2 member headers.
CdrVersion cdr_version_
The type of CDR that will be use in serialization/deserialization.
Definition Cdr.h:3473
void xcdr1_serialize_long_member_header(const MemberId &member_id)
Encodes a long member header of a member according to XCDRv1.
Definition Cdr.cpp:2583
Cdr & xcdr2_end_serialize_member(const Cdr::state &current_state)
Tells to the encoder to finish the encoding of the member.
Definition Cdr.cpp:3084
Cdr_DllAPI void set_state(const state &state)
Sets a previous state of the CDR serialization process;.
Definition Cdr.cpp:455
void xcdr2_end_long_member_header(const MemberId &member_id, size_t member_serialized_size)
Finish the encoding of a long member header of a member according to XCDRv2.
Definition Cdr.cpp:2730
Cdr & operator<<(const _T &value)
Encodes the value into the buffer.
Definition Cdr.h:326
MemberId next_member_id_
Next member identifier to be processed.
Definition Cdr.h:3503
Cdr_DllAPI Cdr & read_encapsulation()
This function reads the encapsulation of the CDR stream. If the CDR stream contains an encapsulation,...
Definition Cdr.cpp:198
deserialize_type_functor deserialize_type_
Definition Cdr.h:3467
FastBuffer::iterator offset_
The current position in the serialization/deserialization process.
Definition Cdr.h:3494
Cdr_DllAPI bool xcdr1_deserialize_member_header(MemberId &member_id, Cdr::state &current_state)
Decodes a member header according to XCDRv1.
Definition Cdr.cpp:2647
Cdr_DllAPI Cdr & serialize_bool_sequence(const std::vector< bool > &vector_t)
Definition Cdr.cpp:2304
bool swap_bytes_
This attribute specifies if it is needed to swap the bytes.
Definition Cdr.h:3488
EncodingAlgorithmFlag current_encoding_
Stores the current encoding algorithm.
Definition Cdr.h:3479
Cdr_DllAPI size_t get_serialized_data_length() const
This function returns the length of the serialized data inside the stream.
Definition Cdr.cpp:445
Cdr_DllAPI void set_xcdrv2_dheader(const state &state)
Uses the state to calculate the member's type size and serialize the value in the previous allocated ...
Definition Cdr.cpp:3513
void xcdr2_serialize_short_member_header(const MemberId &member_id)
Encodes a short member header of a member according to XCDRv2.
Definition Cdr.cpp:2698
Cdr_DllAPI Cdr & deserialize_string_sequence(std::string *&sequence_t, size_t &num_elements)
Definition Cdr.cpp:2428
void make_alignment(size_t align)
This function jumps the number of bytes of the alignment. These bytes should be calculated with the f...
Definition Cdr.h:3022
Cdr & cdr_begin_serialize_member(const MemberId &member_id, bool is_present, Cdr::state &current_state, XCdrHeaderSelection header_selection)
Definition Cdr.cpp:3445
void xcdr1_change_to_long_member_header(const MemberId &member_id, size_t member_serialized_size)
Changes the previous encoded short header to a long header according to XCDRv1.
Definition Cdr.cpp:2624
void xcdr2_change_to_short_member_header(const MemberId &member_id, size_t member_serialized_size)
Changes the previous encoded long header to a short header according to XCDRv2.
Definition Cdr.cpp:2746
Cdr_DllAPI Endianness endianness() const
This function returns the current endianness used by the CDR type.
Definition Cdr.cpp:415
Cdr_DllAPI Cdr & end_serialize_type(Cdr::state &current_state)
Tells to the encoder the encoding of the type finishes.
Definition Cdr.cpp:2241
Cdr_DllAPI state get_state() const
Returns the current state of the CDR serialization process.
Definition Cdr.cpp:450
end_serialize_type_functor end_serialize_type_
Definition Cdr.h:3462
This class represents a stream of bytes that contains (or will contain) serialized data....
Definition FastBuffer.h:244
bool resize(size_t min_size_inc)
This function resizes the raw buffer. It will call the user's defined function for this purpose.
iterator begin()
This function returns a iterator that points to the begining of the stream.
Definition FastBuffer.h:317
char * getBuffer() const
This function returns the stream that the eprosima::fastcdr::FastBuffers uses to serialize data.
Definition FastBuffer.h:298
iterator end()
This function returns a iterator that points to the end of the stream.
Definition FastBuffer.h:327
This class implements the iterator used to go through a FastBuffer.
Definition FastBuffer.h:43
void memcopy(const void *src, const size_t size)
This function copies a buffer into the raw buffer.
Definition FastBuffer.h:126
void rmemcopy(void *dst, const size_t size)
This function copies from the raw buffer to a external buffer.
Definition FastBuffer.h:142
This class is thrown as an exception when an invalid parameter is being serialized.
This abstract class is used to create exceptions.
Definition Exception.h:30
virtual Cdr_DllAPI void raise() const =0
This function throws the object as exception.
This class is thrown as an exception when the buffer's internal memory reachs its size limit.
static Cdr_DllAPI const char *const NOT_ENOUGH_MEMORY_MESSAGE_DEFAULT
Default message used in the library.
T erase(T... args)
constexpr uint16_t PID_EXTENDED_LENGTH
Definition Cdr.cpp:32
EncodingAlgorithmFlag
This enumeration represents the supported XCDR encoding algorithms.
@ PLAIN_CDR
Specifies that the content is PLAIN_CDR.
@ PL_CDR2
Specifies that the content is PL_CDR2.
@ PLAIN_CDR2
Specifies that the content is PLAIN_CDR2.
@ DELIMIT_CDR2
Specifies that the content is DELIMIT_CDR2.
@ PL_CDR
Specifies that the content is PL_CDR,.
size_t alignment_on_state(const FastBuffer::iterator &origin, const FastBuffer::iterator &offset, size_t data_size)
Definition Cdr.cpp:42
constexpr uint16_t PID_SENTINEL_LENGTH
Definition Cdr.cpp:34
static const MemberId MEMBER_ID_INVALID
Definition MemberId.hpp:67
constexpr uint16_t PID_EXTENDED
Definition Cdr.cpp:31
constexpr uint16_t PID_SENTINEL
Definition Cdr.cpp:33
CdrVersion
This enumeration represents the kinds of CDR serialization supported by eprosima::fastcdr::CDR.
@ CORBA_CDR
Common CORBA CDR serialization.
@ XCDRv1
XCDRv1 encoding defined by standard DDS X-Types 1.3.
@ XCDRv2
XCDRv2 encoding defined by standard DDS X-Types 1.3.
Definition Cdr.h:49
T resize(T... args)
T size(T... args)