Fast CDR  Version 2.2.1
Fast CDR
Loading...
Searching...
No Matches
CdrSizeCalculator.hpp
1// Copyright 2023 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#ifndef _FASTCDR_CDRSIZECALCULATOR_HPP_
16#define _FASTCDR_CDRSIZECALCULATOR_HPP_
17
18#include <array>
19#include <bitset>
20#include <cstdint>
21#include <limits>
22#include <map>
23#include <vector>
24
25#include "fastcdr_dll.h"
26
27#include "CdrEncoding.hpp"
28#include "cdr/fixed_size_string.hpp"
29#include "detail/container_recursive_inspector.hpp"
30#include "exceptions/BadParamException.h"
31#include "xcdr/external.hpp"
32#include "xcdr/MemberId.hpp"
33#include "xcdr/optional.hpp"
34
35namespace eprosima {
36namespace fastcdr {
37
38class CdrSizeCalculator;
39
40template<class _T>
43 const _T&,
44 size_t&);
45
52{
53public:
54
61 CdrVersion cdr_version);
62
70 CdrVersion cdr_version,
71 EncodingAlgorithmFlag encoding);
72
77 Cdr_DllAPI CdrVersion get_cdr_version() const;
78
84
92 template<class _T, typename std::enable_if<!std::is_enum<_T>::value>::type* = nullptr, typename = void>
94 const _T& data,
95 size_t& current_alignment)
96 {
97 return eprosima::fastcdr::calculate_serialized_size(*this, data, current_alignment);
98 }
99
107 template<class _T,
108 typename std::enable_if<std::is_enum<_T>::value>::type* = nullptr,
109 typename std::enable_if<std::is_same<typename std::underlying_type<_T>::type,
110 int32_t>::value>::type* = nullptr>
112 const _T& data,
113 size_t& current_alignment)
114 {
115 return calculate_serialized_size(static_cast<int32_t>(data), current_alignment);
116 }
117
125 template<class _T,
126 typename std::enable_if<std::is_enum<_T>::value>::type* = nullptr,
127 typename std::enable_if<std::is_same<typename std::underlying_type<_T>::type,
128 uint32_t>::value>::type* = nullptr>
130 const _T& data,
131 size_t& current_alignment)
132 {
133 return calculate_serialized_size(static_cast<uint32_t>(data), current_alignment);
134 }
135
143 template<class _T,
144 typename std::enable_if<std::is_enum<_T>::value>::type* = nullptr,
145 typename std::enable_if<std::is_same<typename std::underlying_type<_T>::type,
146 int16_t>::value>::type* = nullptr>
148 const _T& data,
149 size_t& current_alignment)
150 {
151 return calculate_serialized_size(static_cast<int16_t>(data), current_alignment);
152 }
153
161 template<class _T,
162 typename std::enable_if<std::is_enum<_T>::value>::type* = nullptr,
163 typename std::enable_if<std::is_same<typename std::underlying_type<_T>::type,
164 uint16_t>::value>::type* = nullptr>
166 const _T& data,
167 size_t& current_alignment)
168 {
169 return calculate_serialized_size(static_cast<uint16_t>(data), current_alignment);
170 }
171
179 template<class _T,
180 typename std::enable_if<std::is_enum<_T>::value>::type* = nullptr,
181 typename std::enable_if<std::is_same<typename std::underlying_type<_T>::type,
182 int8_t>::value>::type* = nullptr>
184 const _T& data,
185 size_t& current_alignment)
186 {
187 return calculate_serialized_size(static_cast<int8_t>(data), current_alignment);
188 }
189
197 template<class _T,
198 typename std::enable_if<std::is_enum<_T>::value>::type* = nullptr,
199 typename std::enable_if<std::is_same<typename std::underlying_type<_T>::type,
200 uint8_t>::value>::type* = nullptr>
202 const _T& data,
203 size_t& current_alignment)
204 {
205 return calculate_serialized_size(static_cast<uint8_t>(data), current_alignment);
206 }
207
214 TEMPLATE_SPEC
216 const int8_t& data,
217 size_t& current_alignment)
218 {
219 static_cast<void>(data);
220 ++current_alignment;
221 return 1;
222 }
223
230 TEMPLATE_SPEC
232 const uint8_t& data,
233 size_t& current_alignment)
234 {
235 static_cast<void>(data);
236 ++current_alignment;
237 return 1;
238 }
239
246 TEMPLATE_SPEC
248 const char& data,
249 size_t& current_alignment)
250 {
251 static_cast<void>(data);
252 ++current_alignment;
253 return 1;
254 }
255
262 TEMPLATE_SPEC
264 const bool& data,
265 size_t& current_alignment)
266 {
267 static_cast<void>(data);
268 ++current_alignment;
269 return 1;
270 }
271
278 TEMPLATE_SPEC
280 const wchar_t& data,
281 size_t& current_alignment)
282 {
283 static_cast<void>(data);
284 size_t calculated_size {2 + alignment(current_alignment, 2)};
285 current_alignment += calculated_size;
286 return calculated_size;
287 }
288
295 TEMPLATE_SPEC
297 const int16_t& data,
298 size_t& current_alignment)
299 {
300 static_cast<void>(data);
301 size_t calculated_size {2 + alignment(current_alignment, 2)};
302 current_alignment += calculated_size;
303 return calculated_size;
304 }
305
312 TEMPLATE_SPEC
314 const uint16_t& data,
315 size_t& current_alignment)
316 {
317 static_cast<void>(data);
318 size_t calculated_size {2 + alignment(current_alignment, 2)};
319 current_alignment += calculated_size;
320 return calculated_size;
321 }
322
329 TEMPLATE_SPEC
331 const int32_t& data,
332 size_t& current_alignment)
333 {
334 static_cast<void>(data);
335 size_t calculated_size {4 + alignment(current_alignment, 4)};
336 current_alignment += calculated_size;
337 return calculated_size;
338 }
339
346 TEMPLATE_SPEC
348 const uint32_t& data,
349 size_t& current_alignment)
350 {
351 static_cast<void>(data);
352 size_t calculated_size {4 + alignment(current_alignment, 4)};
353 current_alignment += calculated_size;
354 return calculated_size;
355 }
356
363 TEMPLATE_SPEC
365 const int64_t& data,
366 size_t& current_alignment)
367 {
368 static_cast<void>(data);
369 size_t calculated_size {8 + alignment(current_alignment, align64_)};
370 current_alignment += calculated_size;
371 return calculated_size;
372 }
373
380 TEMPLATE_SPEC
382 const uint64_t& data,
383 size_t& current_alignment)
384 {
385 static_cast<void>(data);
386 size_t calculated_size {8 + alignment(current_alignment, align64_)};
387 current_alignment += calculated_size;
388 return calculated_size;
389 }
390
397 TEMPLATE_SPEC
399 const float& data,
400 size_t& current_alignment)
401 {
402 static_cast<void>(data);
403 size_t calculated_size {4 + alignment(current_alignment, 4)};
404 current_alignment += calculated_size;
405 return calculated_size;
406 }
407
414 TEMPLATE_SPEC
416 const double& data,
417 size_t& current_alignment)
418 {
419 static_cast<void>(data);
420 size_t calculated_size {8 + alignment(current_alignment, align64_)};
421 current_alignment += calculated_size;
422 return calculated_size;
423 }
424
431 TEMPLATE_SPEC
433 const long double& data,
434 size_t& current_alignment)
435 {
436 static_cast<void>(data);
437 size_t calculated_size {16 + alignment(current_alignment, align64_)};
438 current_alignment += calculated_size;
439 return calculated_size;
440 }
441
448 TEMPLATE_SPEC
450 const std::string& data,
451 size_t& current_alignment)
452 {
453 size_t calculated_size {4 + alignment(current_alignment, 4) + data.size() + 1};
454 current_alignment += calculated_size;
455 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
456
457 return calculated_size;
458 }
459
466 TEMPLATE_SPEC
468 const std::wstring& data,
469 size_t& current_alignment)
470 {
471 size_t calculated_size {4 + alignment(current_alignment, 4) + data.size() * 2};
472 current_alignment += calculated_size;
473
474 return calculated_size;
475 }
476
483 template <size_t MAX_CHARS>
485 const fixed_string<MAX_CHARS>& data,
486 size_t& current_alignment)
487 {
488 size_t calculated_size {4 + alignment(current_alignment, 4) + data.size() + 1};
489 current_alignment += calculated_size;
490
491 return calculated_size;
492 }
493
500 template<class _T, typename std::enable_if<!std::is_enum<_T>::value &&
501 !std::is_arithmetic<_T>::value>::type* = nullptr>
503 const std::vector<_T>& data,
504 size_t& current_alignment)
505 {
506 size_t initial_alignment {current_alignment};
507
508 if (CdrVersion::XCDRv2 == cdr_version_)
509 {
510 // DHEADER
511 current_alignment += 4 + alignment(current_alignment, 4);
512 }
513
514 current_alignment += 4 + alignment(current_alignment, 4);
515
516 size_t calculated_size {current_alignment - initial_alignment};
517 calculated_size += calculate_array_serialized_size(data.data(), data.size(), current_alignment);
518
519 if (CdrVersion::XCDRv2 == cdr_version_)
520 {
521 // Inform DHEADER can be joined with NEXTINT
522 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
523 }
524
525 return calculated_size;
526 }
527
534 template<class _T, typename std::enable_if<std::is_enum<_T>::value ||
535 std::is_arithmetic<_T>::value>::type* = nullptr>
537 const std::vector<_T>& data,
538 size_t& current_alignment)
539 {
540 size_t initial_alignment {current_alignment};
541
542 current_alignment += 4 + alignment(current_alignment, 4);
543
544 size_t calculated_size {current_alignment - initial_alignment};
545 calculated_size += calculate_array_serialized_size(data.data(), data.size(), current_alignment);
546
547 if (CdrVersion::XCDRv2 == cdr_version_)
548 {
549 serialized_member_size_ = get_serialized_member_size<_T>();
550 }
551
552 return calculated_size;
553 }
554
561 TEMPLATE_SPEC
563 const std::vector<bool>& data,
564 size_t& current_alignment)
565 {
566 size_t calculated_size {data.size() + 4 + alignment(current_alignment, 4)};
567 current_alignment += calculated_size;
568
569 return calculated_size;
570 }
571
578 template<class _T, size_t _Size>
580 const std::array<_T, _Size>& data,
581 size_t& current_alignment)
582 {
583 size_t initial_alignment {current_alignment};
584
585 if (CdrVersion::XCDRv2 == cdr_version_ &&
587 {
588 // DHEADER
589 current_alignment += 4 + alignment(current_alignment, 4);
590 }
591
592 size_t calculated_size {current_alignment - initial_alignment};
593 calculated_size += calculate_array_serialized_size(data.data(), data.size(), current_alignment);
594
595 if (CdrVersion::XCDRv2 == cdr_version_ &&
597 {
598 // Inform DHEADER can be joined with NEXTINT
599 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
600 }
601
602 return calculated_size;
603 }
604
611 template<class _K, class _V, typename std::enable_if<!std::is_enum<_V>::value &&
612 !std::is_arithmetic<_V>::value>::type* = nullptr>
614 const std::map<_K, _V>& data,
615 size_t& current_alignment)
616 {
617 size_t initial_alignment {current_alignment};
618
619 if (CdrVersion::XCDRv2 == cdr_version_)
620 {
621 // DHEADER
622 current_alignment += 4 + alignment(current_alignment, 4);
623 }
624
625 current_alignment += 4 + alignment(current_alignment, 4);
626
627 size_t calculated_size {current_alignment - initial_alignment};
628 for (auto it = data.begin(); it != data.end(); ++it)
629 {
630 calculated_size += calculate_serialized_size(it->first, current_alignment);
631 calculated_size += calculate_serialized_size(it->second, current_alignment);
632 }
633
634 if (CdrVersion::XCDRv2 == cdr_version_)
635 {
636 // Inform DHEADER can be joined with NEXTINT
637 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
638 }
639
640 return calculated_size;
641 }
642
649 template<class _K, class _V, typename std::enable_if<std::is_enum<_V>::value ||
650 std::is_arithmetic<_V>::value>::type* = nullptr>
652 const std::map<_K, _V>& data,
653 size_t& current_alignment)
654 {
655 size_t initial_alignment {current_alignment};
656
657 current_alignment += 4 + alignment(current_alignment, 4);
658
659 size_t calculated_size {current_alignment - initial_alignment};
660 for (auto it = data.begin(); it != data.end(); ++it)
661 {
662 calculated_size += calculate_serialized_size(it->first, current_alignment);
663 calculated_size += calculate_serialized_size(it->second, current_alignment);
664 }
665
666 return calculated_size;
667 }
668
675 template<size_t N, typename std::enable_if < (N < 9) > ::type* = nullptr>
676 size_t calculate_serialized_size(
677 const std::bitset<N>& data,
678 size_t& current_alignment)
679 {
680 static_cast<void>(data);
681 ++current_alignment;
682 return 1;
683 }
684
691 template<size_t N, typename std::enable_if < (8 < N && N < 17) > ::type* = nullptr>
692 size_t calculate_serialized_size(
693 const std::bitset<N>& data,
694 size_t& current_alignment)
695 {
696 static_cast<void>(data);
697 size_t calculated_size {2 + alignment(current_alignment, 2)};
698 current_alignment += calculated_size;
699 return calculated_size;
700 }
701
708 template<size_t N, typename std::enable_if < (16 < N && N < 33) > ::type* = nullptr>
709 size_t calculate_serialized_size(
710 const std::bitset<N>& data,
711 size_t& current_alignment)
712 {
713 static_cast<void>(data);
714 size_t calculated_size {4 + alignment(current_alignment, 4)};
715 current_alignment += calculated_size;
716 return calculated_size;
717 }
718
725 template<size_t N, typename std::enable_if < (32 < N && N < 65) > ::type* = nullptr>
726 size_t calculate_serialized_size(
727 const std::bitset<N>& data,
728 size_t& current_alignment)
729 {
730 static_cast<void>(data);
731 size_t calculated_size {8 + alignment(current_alignment, align64_)};
732 current_alignment += calculated_size;
733 return calculated_size;
734 }
735
742 template<class _T>
744 const optional<_T>& data,
745 size_t& current_alignment)
746 {
747 size_t initial_alignment = current_alignment;
748
749 if (CdrVersion::XCDRv2 == cdr_version_ &&
750 EncodingAlgorithmFlag::PL_CDR2 != current_encoding_)
751 {
752 // Take into account the boolean is_present;
753 ++current_alignment;
754 }
755
756 size_t calculated_size {current_alignment - initial_alignment};
757
758 if (data.has_value())
759 {
760 calculated_size += calculate_serialized_size(data.value(), current_alignment);
761 }
762
763 return calculated_size;
764 }
765
773 template<class _T>
775 const external<_T>& data,
776 size_t& current_alignment)
777 {
778 if (!data)
779 {
780 throw exception::BadParamException("External member is null");
781 }
782
783 return calculate_serialized_size(*data, current_alignment);
784 }
785
794 template<class _T>
796 const _T* data,
797 size_t num_elements,
798 size_t& current_alignment)
799 {
800 size_t calculated_size {0};
801
802 for (size_t count = 0; count < num_elements; ++count)
803 {
804 calculated_size += calculate_serialized_size(data[count], current_alignment);
805 }
806
807 return calculated_size;
808 }
809
817 TEMPLATE_SPEC
819 const int8_t* data,
820 size_t num_elements,
821 size_t& current_alignment)
822 {
823 static_cast<void>(data);
824 current_alignment += num_elements;
825 return num_elements;
826 }
827
835 TEMPLATE_SPEC
837 const uint8_t* data,
838 size_t num_elements,
839 size_t& current_alignment)
840 {
841 static_cast<void>(data);
842 current_alignment += num_elements;
843 return num_elements;
844 }
845
853 TEMPLATE_SPEC
855 const char* data,
856 size_t num_elements,
857 size_t& current_alignment)
858 {
859 static_cast<void>(data);
860 current_alignment += num_elements;
861 return num_elements;
862 }
863
871 TEMPLATE_SPEC
873 const wchar_t* data,
874 size_t num_elements,
875 size_t& current_alignment)
876 {
877 static_cast<void>(data);
878 size_t calculated_size {num_elements* 2 + alignment(current_alignment, 2)};
879 current_alignment += calculated_size;
880 return calculated_size;
881 }
882
890 TEMPLATE_SPEC
892 const int16_t* data,
893 size_t num_elements,
894 size_t& current_alignment)
895 {
896 static_cast<void>(data);
897 size_t calculated_size {num_elements* 2 + alignment(current_alignment, 2)};
898 current_alignment += calculated_size;
899 return calculated_size;
900 }
901
909 TEMPLATE_SPEC
911 const uint16_t* data,
912 size_t num_elements,
913 size_t& current_alignment)
914 {
915 static_cast<void>(data);
916 size_t calculated_size {num_elements* 2 + alignment(current_alignment, 2)};
917 current_alignment += calculated_size;
918 return calculated_size;
919 }
920
928 TEMPLATE_SPEC
930 const int32_t* data,
931 size_t num_elements,
932 size_t& current_alignment)
933 {
934 static_cast<void>(data);
935 size_t calculated_size {num_elements* 4 + alignment(current_alignment, 4)};
936 current_alignment += calculated_size;
937 return calculated_size;
938 }
939
947 TEMPLATE_SPEC
949 const uint32_t* data,
950 size_t num_elements,
951 size_t& current_alignment)
952 {
953 static_cast<void>(data);
954 size_t calculated_size {num_elements* 4 + alignment(current_alignment, 4)};
955 current_alignment += calculated_size;
956 return calculated_size;
957 }
958
966 TEMPLATE_SPEC
968 const int64_t* data,
969 size_t num_elements,
970 size_t& current_alignment)
971 {
972 static_cast<void>(data);
973 size_t calculated_size {num_elements* 8 + alignment(current_alignment, align64_)};
974 current_alignment += calculated_size;
975 return calculated_size;
976 }
977
985 TEMPLATE_SPEC
987 const uint64_t* data,
988 size_t num_elements,
989 size_t& current_alignment)
990 {
991 static_cast<void>(data);
992 size_t calculated_size {num_elements* 8 + alignment(current_alignment, align64_)};
993 current_alignment += calculated_size;
994 return calculated_size;
995 }
996
1004 TEMPLATE_SPEC
1006 const float* data,
1007 size_t num_elements,
1008 size_t& current_alignment)
1009 {
1010 static_cast<void>(data);
1011 size_t calculated_size {num_elements* 4 + alignment(current_alignment, 4)};
1012 current_alignment += calculated_size;
1013 return calculated_size;
1014 }
1015
1023 TEMPLATE_SPEC
1025 const double* data,
1026 size_t num_elements,
1027 size_t& current_alignment)
1028 {
1029 static_cast<void>(data);
1030 size_t calculated_size {num_elements* 8 + alignment(current_alignment, align64_)};
1031 current_alignment += calculated_size;
1032 return calculated_size;
1033 }
1034
1042 TEMPLATE_SPEC
1044 const long double* data,
1045 size_t num_elements,
1046 size_t& current_alignment)
1047 {
1048 static_cast<void>(data);
1049 size_t calculated_size {num_elements* 16 + alignment(current_alignment, align64_)};
1050 current_alignment += calculated_size;
1051 return calculated_size;
1052 }
1053
1061 template<class _T, size_t _N>
1063 const std::array<_T, _N>* data,
1064 size_t num_elements,
1065 size_t& current_alignment)
1066 {
1067 return calculate_array_serialized_size(data->data(), num_elements * data->size(), current_alignment);
1068 }
1069
1076 template<class _T, typename std::enable_if<std::is_enum<_T>::value ||
1077 std::is_arithmetic<_T>::value>::type* = nullptr>
1079 const std::vector<_T>& data,
1080 size_t& current_alignment)
1081 {
1082 return calculate_array_serialized_size(data.data(), data.size(), current_alignment);
1083 }
1084
1091 template<class _T, typename std::enable_if<!std::is_enum<_T>::value &&
1092 !std::is_arithmetic<_T>::value>::type* = nullptr>
1094 const std::vector<_T>& data,
1095 size_t& current_alignment)
1096 {
1097 size_t initial_alignment {current_alignment};
1098
1099 if (CdrVersion::XCDRv2 == cdr_version_)
1100 {
1101 // DHEADER
1102 current_alignment += 4 + alignment(current_alignment, 4);
1103 }
1104
1105 size_t calculated_size {current_alignment - initial_alignment};
1106 calculated_size += calculate_array_serialized_size(data.data(), data.size(), current_alignment);
1107
1108 if (CdrVersion::XCDRv2 == cdr_version_)
1109 {
1110 // Inform DHEADER can be joined with NEXTINT
1111 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
1112 }
1113
1114 return calculated_size;
1115 }
1116
1123 TEMPLATE_SPEC
1125 const std::vector<bool>& data,
1126 size_t& current_alignment)
1127 {
1128 current_alignment += data.size();
1129 return data.size();
1130 }
1131
1140 template<class _T>
1142 const MemberId& id,
1143 const _T& data,
1144 size_t& current_alignment)
1145 {
1146 size_t initial_alignment {current_alignment};
1147
1148 if (EncodingAlgorithmFlag::PL_CDR == current_encoding_ ||
1149 EncodingAlgorithmFlag::PL_CDR2 == current_encoding_)
1150 {
1151 // Align to 4 for the XCDR header before calculating the data serialized size.
1152 current_alignment += alignment(current_alignment, 4);
1153 }
1154
1155 size_t prev_size {current_alignment - initial_alignment};
1156 size_t extra_size {0};
1157
1158 if (EncodingAlgorithmFlag::PL_CDR == current_encoding_)
1159 {
1160 current_alignment = 0;
1161 }
1162
1163 size_t calculated_size {calculate_serialized_size(data, current_alignment)};
1164
1165 if (CdrVersion::XCDRv2 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR2 == current_encoding_ &&
1166 0 < calculated_size)
1167 {
1168
1169 if (8 < calculated_size)
1170 {
1171 extra_size = 8; // Long EMHEADER.
1172 if (NO_SERIALIZED_MEMBER_SIZE != serialized_member_size_)
1173 {
1174 calculated_size -= 4; // Join NEXTINT and DHEADER.
1175 }
1176 }
1177 else
1178 {
1179 extra_size = 4; // EMHEADER;
1180 }
1181 }
1182 else if (CdrVersion::XCDRv1 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR == current_encoding_ &&
1183 0 < calculated_size)
1184 {
1185 extra_size = 4; // ShortMemberHeader
1186
1187 if (0x3F00 < id.id || calculated_size > std::numeric_limits<uint16_t>::max())
1188 {
1189 extra_size += 8; // LongMemberHeader
1190 }
1191
1192 }
1193
1194 calculated_size += prev_size + extra_size;
1195 if (EncodingAlgorithmFlag::PL_CDR != current_encoding_)
1196 {
1197 current_alignment += extra_size;
1198 }
1199
1200 serialized_member_size_ = NO_SERIALIZED_MEMBER_SIZE;
1201
1202 return calculated_size;
1203 }
1204
1213 template<class _T>
1215 const MemberId& id,
1216 const optional<_T>& data,
1217 size_t& current_alignment)
1218 {
1219 size_t initial_alignment = current_alignment;
1220
1221 if (CdrVersion::XCDRv2 != cdr_version_ ||
1222 EncodingAlgorithmFlag::PL_CDR2 == current_encoding_)
1223 {
1224 if (data.has_value() || EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_)
1225 {
1226 // Align to 4 for the XCDR header before calculating the data serialized size.
1227 current_alignment += alignment(current_alignment, 4);
1228 }
1229 }
1230
1231 size_t prev_size = {current_alignment - initial_alignment};
1232 size_t extra_size {0};
1233
1234 if (CdrVersion::XCDRv1 == cdr_version_ &&
1235 (data.has_value() || EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_))
1236 {
1237 current_alignment = 0;
1238 }
1239
1240 size_t calculated_size {calculate_serialized_size(data, current_alignment)};
1241
1242 if (CdrVersion::XCDRv2 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR2 == current_encoding_ &&
1243 0 < calculated_size)
1244 {
1245 if (8 < calculated_size)
1246 {
1247 extra_size = 8; // Long EMHEADER.
1248 if (NO_SERIALIZED_MEMBER_SIZE != serialized_member_size_)
1249 {
1250 extra_size -= 4; // Join NEXTINT and DHEADER.
1251 }
1252 }
1253 else
1254 {
1255 extra_size = 4; // EMHEADER;
1256 }
1257 }
1258 else if (CdrVersion::XCDRv1 == cdr_version_ &&
1259 (0 < calculated_size || EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_))
1260 {
1261 extra_size = 4; // ShortMemberHeader
1262
1263 if (0x3F00 < id.id || calculated_size > std::numeric_limits<uint16_t>::max())
1264 {
1265 extra_size += 8; // LongMemberHeader
1266 }
1267
1268 }
1269
1270 calculated_size += prev_size + extra_size;
1271 if (CdrVersion::XCDRv1 != cdr_version_)
1272 {
1273 current_alignment += extra_size;
1274 }
1275
1276
1277 return calculated_size;
1278 }
1279
1287 EncodingAlgorithmFlag new_encoding,
1288 size_t& current_alignment);
1289
1297 EncodingAlgorithmFlag new_encoding,
1298 size_t& current_alignment);
1299
1300private:
1301
1302 CdrSizeCalculator() = delete;
1303
1304 CdrVersion cdr_version_ {CdrVersion::XCDRv2};
1305
1307
1308 enum SerializedMemberSizeForNextInt
1309 {
1310 NO_SERIALIZED_MEMBER_SIZE,
1311 SERIALIZED_MEMBER_SIZE,
1312 SERIALIZED_MEMBER_SIZE_4,
1313 SERIALIZED_MEMBER_SIZE_8
1314 }
1316 serialized_member_size_ {NO_SERIALIZED_MEMBER_SIZE};
1317
1319 size_t align64_ {4};
1320
1321 inline size_t alignment(
1322 size_t current_alignment,
1323 size_t data_size) const
1324 {
1325 return (data_size - (current_alignment % data_size)) & (data_size - 1);
1326 }
1327
1328 template<class _T, typename std::enable_if<std::is_enum<_T>::value ||
1329 std::is_arithmetic<_T>::value>::type* = nullptr>
1330 constexpr SerializedMemberSizeForNextInt get_serialized_member_size() const
1331 {
1332 return (1 == sizeof(_T) ? SERIALIZED_MEMBER_SIZE :
1333 (4 == sizeof(_T) ? SERIALIZED_MEMBER_SIZE_4 :
1334 (8 == sizeof(_T) ? SERIALIZED_MEMBER_SIZE_8 : NO_SERIALIZED_MEMBER_SIZE)));
1335 }
1336
1337};
1338
1339} // namespace fastcdr
1340} // namespace eprosima
1341
1342#endif // _FASTCDR_CDRSIZECALCULATOR_HPP_
This class offers an interface to calculate the encoded size of a type serialized using a support enc...
Definition CdrSizeCalculator.hpp:52
size_t calculate_serialized_size(const _T &data, size_t &current_alignment)
Generic template which calculates the encoded size of an instance of an unknown type.
Definition CdrSizeCalculator.hpp:93
Cdr_DllAPI CdrSizeCalculator(CdrVersion cdr_version)
Constructor.
Cdr_DllAPI EncodingAlgorithmFlag get_encoding() const
Retrieves the current encoding algorithm used by the instance.
TEMPLATE_SPEC size_t calculate_array_serialized_size(const uint64_t *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of uint64_t.
Definition CdrSizeCalculator.hpp:986
TEMPLATE_SPEC size_t calculate_array_serialized_size(const uint16_t *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of uint16_t.
Definition CdrSizeCalculator.hpp:910
Cdr_DllAPI size_t end_calculate_type_serialized_size(EncodingAlgorithmFlag new_encoding, size_t &current_alignment)
Indicates the ending of a constructed type.
TEMPLATE_SPEC size_t calculate_array_serialized_size(const uint32_t *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of uint32_t.
Definition CdrSizeCalculator.hpp:948
TEMPLATE_SPEC size_t calculate_serialized_size(const uint8_t &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an uint8_t.
Definition CdrSizeCalculator.hpp:231
TEMPLATE_SPEC size_t calculate_array_serialized_size(const int64_t *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of int64_t.
Definition CdrSizeCalculator.hpp:967
TEMPLATE_SPEC size_t calculate_array_serialized_size(const uint8_t *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of uint8_t.
Definition CdrSizeCalculator.hpp:836
size_t calculate_serialized_size(const fixed_string< MAX_CHARS > &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a fixed_string.
Definition CdrSizeCalculator.hpp:484
TEMPLATE_SPEC size_t calculate_array_serialized_size(const int32_t *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of int32_t.
Definition CdrSizeCalculator.hpp:929
size_t calculate_array_serialized_size(const std::array< _T, _N > *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a multi-dimensional array.
Definition CdrSizeCalculator.hpp:1062
size_t calculate_array_serialized_size(const _T *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of unknown type.
Definition CdrSizeCalculator.hpp:795
size_t calculate_serialized_size(const optional< _T > &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an optional type.
Definition CdrSizeCalculator.hpp:743
TEMPLATE_SPEC size_t calculate_array_serialized_size(const int8_t *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of int8_t.
Definition CdrSizeCalculator.hpp:818
TEMPLATE_SPEC size_t calculate_array_serialized_size(const long double *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of long double.
Definition CdrSizeCalculator.hpp:1043
TEMPLATE_SPEC size_t calculate_serialized_size(const long double &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a long double.
Definition CdrSizeCalculator.hpp:432
TEMPLATE_SPEC size_t calculate_array_serialized_size(const int16_t *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of int16_t.
Definition CdrSizeCalculator.hpp:891
size_t calculate_array_serialized_size(const std::vector< _T > &data, size_t &current_alignment)
Specific template which calculates the encoded size of an std::vector of primitives as an array.
Definition CdrSizeCalculator.hpp:1078
TEMPLATE_SPEC size_t calculate_serialized_size(const int8_t &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an int8_t.
Definition CdrSizeCalculator.hpp:215
Cdr_DllAPI size_t begin_calculate_type_serialized_size(EncodingAlgorithmFlag new_encoding, size_t &current_alignment)
Indicates a new constructed type will be calculated.
TEMPLATE_SPEC size_t calculate_serialized_size(const double &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a double.
Definition CdrSizeCalculator.hpp:415
TEMPLATE_SPEC size_t calculate_array_serialized_size(const char *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of char.
Definition CdrSizeCalculator.hpp:854
size_t calculate_member_serialized_size(const MemberId &id, const _T &data, size_t &current_alignment)
Generic template which calculates the encoded size of the constructed type's member of a unknown type...
Definition CdrSizeCalculator.hpp:1141
TEMPLATE_SPEC size_t calculate_serialized_size(const int16_t &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a int16_t.
Definition CdrSizeCalculator.hpp:296
TEMPLATE_SPEC size_t calculate_serialized_size(const std::vector< bool > &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a sequence of bool.
Definition CdrSizeCalculator.hpp:562
TEMPLATE_SPEC size_t calculate_array_serialized_size(const std::vector< bool > &data, size_t &current_alignment)
Specific template which calculates the encoded size of an std::vector of bool as an array.
Definition CdrSizeCalculator.hpp:1124
size_t calculate_serialized_size(const std::array< _T, _Size > &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array.
Definition CdrSizeCalculator.hpp:579
TEMPLATE_SPEC size_t calculate_array_serialized_size(const float *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of float.
Definition CdrSizeCalculator.hpp:1005
TEMPLATE_SPEC size_t calculate_serialized_size(const float &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a float.
Definition CdrSizeCalculator.hpp:398
TEMPLATE_SPEC size_t calculate_array_serialized_size(const double *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of double.
Definition CdrSizeCalculator.hpp:1024
TEMPLATE_SPEC size_t calculate_serialized_size(const int32_t &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a int32_t.
Definition CdrSizeCalculator.hpp:330
TEMPLATE_SPEC size_t calculate_array_serialized_size(const wchar_t *data, size_t num_elements, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an array of wchar.
Definition CdrSizeCalculator.hpp:872
TEMPLATE_SPEC size_t calculate_serialized_size(const uint64_t &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a uint64_t.
Definition CdrSizeCalculator.hpp:381
TEMPLATE_SPEC size_t calculate_serialized_size(const std::wstring &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a std::wstring.
Definition CdrSizeCalculator.hpp:467
TEMPLATE_SPEC size_t calculate_serialized_size(const bool &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a bool.
Definition CdrSizeCalculator.hpp:263
TEMPLATE_SPEC size_t calculate_serialized_size(const char &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a char.
Definition CdrSizeCalculator.hpp:247
TEMPLATE_SPEC size_t calculate_serialized_size(const uint32_t &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a uint32_t.
Definition CdrSizeCalculator.hpp:347
size_t calculate_serialized_size(const std::vector< _T > &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a sequence of non-primitives.
Definition CdrSizeCalculator.hpp:502
TEMPLATE_SPEC size_t calculate_serialized_size(const int64_t &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a int64_t.
Definition CdrSizeCalculator.hpp:364
Cdr_DllAPI CdrVersion get_cdr_version() const
Retrieves the version of the encoding algorithm used by the instance.
TEMPLATE_SPEC size_t calculate_serialized_size(const std::string &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a std::string.
Definition CdrSizeCalculator.hpp:449
size_t calculate_serialized_size(const std::map< _K, _V > &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a map of non-primitives.
Definition CdrSizeCalculator.hpp:613
size_t calculate_serialized_size(const external< _T > &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of an external type.
Definition CdrSizeCalculator.hpp:774
TEMPLATE_SPEC size_t calculate_serialized_size(const wchar_t &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a wchar.
Definition CdrSizeCalculator.hpp:279
size_t calculate_member_serialized_size(const MemberId &id, const optional< _T > &data, size_t &current_alignment)
Generic template which calculates the encoded size of the constructed type's member of type optional.
Definition CdrSizeCalculator.hpp:1214
Cdr_DllAPI CdrSizeCalculator(CdrVersion cdr_version, EncodingAlgorithmFlag encoding)
Constructor.
TEMPLATE_SPEC size_t calculate_serialized_size(const uint16_t &data, size_t &current_alignment)
Specific template which calculates the encoded size of an instance of a uint16_t.
Definition CdrSizeCalculator.hpp:313
Definition MemberId.hpp:28
This class is thrown as an exception when an invalid parameter is being serialized.
Definition BadParamException.h:28
This class template manages an external member, a member declared to be external to the storage of a ...
Definition external.hpp:30
This class template manages an optional contained value, i.e.
Definition optional.hpp:47
T & value() &
Returns the contained value.
Definition optional.hpp:129
bool has_value() const
Checks whether the optional contains a value.
Definition optional.hpp:196
EncodingAlgorithmFlag
This enumeration represents the supported XCDR encoding algorithms.
Definition CdrEncoding.hpp:38
@ PL_CDR2
Specifies that the content is PL_CDR2.
Definition CdrEncoding.hpp:48
@ PL_CDR
Specifies that the content is PL_CDR,.
Definition CdrEncoding.hpp:42
@ PLAIN_CDR
Specifies that the content is PLAIN_CDR.
Definition CdrEncoding.hpp:40
@ PLAIN_CDR2
Specifies that the content is PLAIN_CDR2.
Definition CdrEncoding.hpp:44
constexpr bool is_multi_array_primitive(...)
Basis.
Definition container_recursive_inspector.hpp:27
size_t calculate_serialized_size(CdrSizeCalculator &, const _T &, size_t &)
CdrVersion
This enumeration represents the kinds of CDR serialization supported by eprosima::fastcdr::CDR.
Definition CdrEncoding.hpp:25
@ XCDRv2
XCDRv2 encoding defined by standard DDS X-Types 1.3.
Definition CdrEncoding.hpp:33
@ XCDRv1
XCDRv1 encoding defined by standard DDS X-Types 1.3.
Definition CdrEncoding.hpp:31
Definition Cdr.h:48
Template class for non-alloc strings.
Definition fixed_size_string.hpp:45
size_t size() const noexcept
Returns the size of the string.
Definition fixed_size_string.hpp:288