15 #ifndef _FASTCDR_CDRSIZECALCULATOR_HPP_
16 #define _FASTCDR_CDRSIZECALCULATOR_HPP_
25 #include "fastcdr_dll.h"
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"
38 class CdrSizeCalculator;
92 template<class _T, typename std::enable_if<!std::is_enum<_T>::value>::type* =
nullptr,
typename =
void>
95 size_t& current_alignment)
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>
113 size_t& current_alignment)
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>
131 size_t& current_alignment)
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>
149 size_t& current_alignment)
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>
167 size_t& current_alignment)
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>
185 size_t& current_alignment)
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>
203 size_t& current_alignment)
217 size_t& current_alignment)
219 static_cast<void>(data);
233 size_t& current_alignment)
235 static_cast<void>(data);
249 size_t& current_alignment)
251 static_cast<void>(data);
265 size_t& current_alignment)
267 static_cast<void>(data);
281 size_t& current_alignment)
283 static_cast<void>(data);
284 size_t calculated_size {2 + alignment(current_alignment, 2)};
285 current_alignment += calculated_size;
286 return calculated_size;
298 size_t& current_alignment)
300 static_cast<void>(data);
301 size_t calculated_size {2 + alignment(current_alignment, 2)};
302 current_alignment += calculated_size;
303 return calculated_size;
314 const uint16_t& data,
315 size_t& current_alignment)
317 static_cast<void>(data);
318 size_t calculated_size {2 + alignment(current_alignment, 2)};
319 current_alignment += calculated_size;
320 return calculated_size;
332 size_t& current_alignment)
334 static_cast<void>(data);
335 size_t calculated_size {4 + alignment(current_alignment, 4)};
336 current_alignment += calculated_size;
337 return calculated_size;
348 const uint32_t& data,
349 size_t& current_alignment)
351 static_cast<void>(data);
352 size_t calculated_size {4 + alignment(current_alignment, 4)};
353 current_alignment += calculated_size;
354 return calculated_size;
366 size_t& current_alignment)
368 static_cast<void>(data);
369 size_t calculated_size {8 + alignment(current_alignment, align64_)};
370 current_alignment += calculated_size;
371 return calculated_size;
382 const uint64_t& data,
383 size_t& current_alignment)
385 static_cast<void>(data);
386 size_t calculated_size {8 + alignment(current_alignment, align64_)};
387 current_alignment += calculated_size;
388 return calculated_size;
400 size_t& current_alignment)
402 static_cast<void>(data);
403 size_t calculated_size {4 + alignment(current_alignment, 4)};
404 current_alignment += calculated_size;
405 return calculated_size;
417 size_t& current_alignment)
419 static_cast<void>(data);
420 size_t calculated_size {8 + alignment(current_alignment, align64_)};
421 current_alignment += calculated_size;
422 return calculated_size;
433 const long double& data,
434 size_t& current_alignment)
436 static_cast<void>(data);
437 size_t calculated_size {16 + alignment(current_alignment, align64_)};
438 current_alignment += calculated_size;
439 return calculated_size;
450 const std::string& data,
451 size_t& current_alignment)
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;
457 return calculated_size;
468 const std::wstring& data,
469 size_t& current_alignment)
471 size_t calculated_size {4 + alignment(current_alignment, 4) + data.size() * 2};
472 current_alignment += calculated_size;
474 return calculated_size;
483 template <
size_t MAX_CHARS>
486 size_t& current_alignment)
488 size_t calculated_size {4 + alignment(current_alignment, 4) + data.
size() + 1};
489 current_alignment += calculated_size;
490 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
492 return calculated_size;
501 template<class _T, typename std::enable_if<!std::is_enum<_T>::value &&
502 !std::is_arithmetic<_T>::value>::type* =
nullptr>
504 const std::vector<_T>& data,
505 size_t& current_alignment)
507 size_t initial_alignment {current_alignment};
509 if (CdrVersion::XCDRv2 == cdr_version_)
512 current_alignment += 4 + alignment(current_alignment, 4);
515 current_alignment += 4 + alignment(current_alignment, 4);
517 size_t calculated_size {current_alignment - initial_alignment};
520 if (CdrVersion::XCDRv2 == cdr_version_)
523 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
526 return calculated_size;
535 template<class _T, typename std::enable_if<std::is_enum<_T>::value ||
536 std::is_arithmetic<_T>::value>::type* =
nullptr>
538 const std::vector<_T>& data,
539 size_t& current_alignment)
541 size_t initial_alignment {current_alignment};
543 current_alignment += 4 + alignment(current_alignment, 4);
545 size_t calculated_size {current_alignment - initial_alignment};
548 if (CdrVersion::XCDRv2 == cdr_version_)
550 serialized_member_size_ = get_serialized_member_size<_T>();
553 return calculated_size;
564 const std::vector<bool>& data,
565 size_t& current_alignment)
567 size_t calculated_size {data.size() + 4 + alignment(current_alignment, 4)};
568 current_alignment += calculated_size;
570 return calculated_size;
579 template<
class _T,
size_t _Size>
581 const std::array<_T, _Size>& data,
582 size_t& current_alignment)
584 size_t initial_alignment {current_alignment};
586 if (CdrVersion::XCDRv2 == cdr_version_ &&
590 current_alignment += 4 + alignment(current_alignment, 4);
593 size_t calculated_size {current_alignment - initial_alignment};
596 if (CdrVersion::XCDRv2 == cdr_version_ &&
600 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
603 return calculated_size;
612 template<class _K, class _V, typename std::enable_if<!std::is_enum<_V>::value &&
613 !std::is_arithmetic<_V>::value>::type* =
nullptr>
615 const std::map<_K, _V>& data,
616 size_t& current_alignment)
618 size_t initial_alignment {current_alignment};
620 if (CdrVersion::XCDRv2 == cdr_version_)
623 current_alignment += 4 + alignment(current_alignment, 4);
626 current_alignment += 4 + alignment(current_alignment, 4);
628 size_t calculated_size {current_alignment - initial_alignment};
629 for (
auto it = data.begin(); it != data.end(); ++it)
635 if (CdrVersion::XCDRv2 == cdr_version_)
638 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
641 return calculated_size;
650 template<class _K, class _V, typename std::enable_if<std::is_enum<_V>::value ||
651 std::is_arithmetic<_V>::value>::type* =
nullptr>
653 const std::map<_K, _V>& data,
654 size_t& current_alignment)
656 size_t initial_alignment {current_alignment};
658 current_alignment += 4 + alignment(current_alignment, 4);
660 size_t calculated_size {current_alignment - initial_alignment};
661 for (
auto it = data.begin(); it != data.end(); ++it)
667 return calculated_size;
676 template<
size_t N,
typename std::enable_if < (N < 9) > ::type* =
nullptr>
677 size_t calculate_serialized_size(
678 const std::bitset<N>& data,
679 size_t& current_alignment)
681 static_cast<
void>(data);
692 template<
size_t N,
typename std::enable_if < (8 < N && N < 17) > ::type* =
nullptr>
693 size_t calculate_serialized_size(
694 const std::bitset<N>& data,
695 size_t& current_alignment)
697 static_cast<
void>(data);
698 size_t calculated_size {2 + alignment(current_alignment, 2)};
699 current_alignment += calculated_size;
700 return calculated_size;
709 template<
size_t N,
typename std::enable_if < (16 < N && N < 33) > ::type* =
nullptr>
710 size_t calculate_serialized_size(
711 const std::bitset<N>& data,
712 size_t& current_alignment)
714 static_cast<
void>(data);
715 size_t calculated_size {4 + alignment(current_alignment, 4)};
716 current_alignment += calculated_size;
717 return calculated_size;
726 template<
size_t N,
typename std::enable_if < (32 < N && N < 65) > ::type* =
nullptr>
727 size_t calculate_serialized_size(
728 const std::bitset<N>& data,
729 size_t& current_alignment)
731 static_cast<
void>(data);
732 size_t calculated_size {8 + alignment(current_alignment, align64_)};
733 current_alignment += calculated_size;
734 return calculated_size;
746 size_t& current_alignment)
748 size_t initial_alignment = current_alignment;
750 if (CdrVersion::XCDRv2 == cdr_version_ &&
751 EncodingAlgorithmFlag::PL_CDR2 != current_encoding_)
757 size_t calculated_size {current_alignment - initial_alignment};
764 return calculated_size;
777 size_t& current_alignment)
799 size_t& current_alignment)
801 size_t calculated_size {0};
803 for (
size_t count = 0; count < num_elements; ++count)
808 return calculated_size;
822 size_t& current_alignment)
824 static_cast<void>(data);
825 current_alignment += num_elements;
840 size_t& current_alignment)
842 static_cast<void>(data);
843 current_alignment += num_elements;
858 size_t& current_alignment)
860 static_cast<void>(data);
861 current_alignment += num_elements;
876 size_t& current_alignment)
878 static_cast<void>(data);
879 size_t calculated_size {num_elements* 2 + alignment(current_alignment, 2)};
880 current_alignment += calculated_size;
881 return calculated_size;
895 size_t& current_alignment)
897 static_cast<void>(data);
898 size_t calculated_size {num_elements* 2 + alignment(current_alignment, 2)};
899 current_alignment += calculated_size;
900 return calculated_size;
912 const uint16_t* data,
914 size_t& current_alignment)
916 static_cast<void>(data);
917 size_t calculated_size {num_elements* 2 + alignment(current_alignment, 2)};
918 current_alignment += calculated_size;
919 return calculated_size;
933 size_t& current_alignment)
935 static_cast<void>(data);
936 size_t calculated_size {num_elements* 4 + alignment(current_alignment, 4)};
937 current_alignment += calculated_size;
938 return calculated_size;
950 const uint32_t* data,
952 size_t& current_alignment)
954 static_cast<void>(data);
955 size_t calculated_size {num_elements* 4 + alignment(current_alignment, 4)};
956 current_alignment += calculated_size;
957 return calculated_size;
971 size_t& current_alignment)
973 static_cast<void>(data);
974 size_t calculated_size {num_elements* 8 + alignment(current_alignment, align64_)};
975 current_alignment += calculated_size;
976 return calculated_size;
988 const uint64_t* data,
990 size_t& current_alignment)
992 static_cast<void>(data);
993 size_t calculated_size {num_elements* 8 + alignment(current_alignment, align64_)};
994 current_alignment += calculated_size;
995 return calculated_size;
1008 size_t num_elements,
1009 size_t& current_alignment)
1011 static_cast<void>(data);
1012 size_t calculated_size {num_elements* 4 + alignment(current_alignment, 4)};
1013 current_alignment += calculated_size;
1014 return calculated_size;
1027 size_t num_elements,
1028 size_t& current_alignment)
1030 static_cast<void>(data);
1031 size_t calculated_size {num_elements* 8 + alignment(current_alignment, align64_)};
1032 current_alignment += calculated_size;
1033 return calculated_size;
1045 const long double* data,
1046 size_t num_elements,
1047 size_t& current_alignment)
1049 static_cast<void>(data);
1050 size_t calculated_size {num_elements* 16 + alignment(current_alignment, align64_)};
1051 current_alignment += calculated_size;
1052 return calculated_size;
1062 template<
class _T,
size_t _N>
1064 const std::array<_T, _N>* data,
1065 size_t num_elements,
1066 size_t& current_alignment)
1077 template<class _T, typename std::enable_if<std::is_enum<_T>::value ||
1078 std::is_arithmetic<_T>::value>::type* =
nullptr>
1080 const std::vector<_T>& data,
1081 size_t& current_alignment)
1092 template<class _T, typename std::enable_if<!std::is_enum<_T>::value &&
1093 !std::is_arithmetic<_T>::value>::type* =
nullptr>
1095 const std::vector<_T>& data,
1096 size_t& current_alignment)
1098 size_t initial_alignment {current_alignment};
1100 if (CdrVersion::XCDRv2 == cdr_version_)
1103 current_alignment += 4 + alignment(current_alignment, 4);
1106 size_t calculated_size {current_alignment - initial_alignment};
1109 if (CdrVersion::XCDRv2 == cdr_version_)
1112 serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
1115 return calculated_size;
1126 const std::vector<bool>& data,
1127 size_t& current_alignment)
1129 current_alignment += data.size();
1145 size_t& current_alignment)
1147 size_t initial_alignment {current_alignment};
1149 if (EncodingAlgorithmFlag::PL_CDR == current_encoding_ ||
1150 EncodingAlgorithmFlag::PL_CDR2 == current_encoding_)
1153 current_alignment += alignment(current_alignment, 4);
1156 size_t prev_size {current_alignment - initial_alignment};
1157 size_t extra_size {0};
1159 if (EncodingAlgorithmFlag::PL_CDR == current_encoding_)
1161 current_alignment = 0;
1166 if (CdrVersion::XCDRv2 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR2 == current_encoding_ &&
1167 0 < calculated_size)
1170 if (8 < calculated_size ||
1171 (1 != calculated_size && 2 != calculated_size && 4 != calculated_size &&
1172 8 != calculated_size))
1175 if (NO_SERIALIZED_MEMBER_SIZE != serialized_member_size_)
1177 calculated_size -= 4;
1185 else if (CdrVersion::XCDRv1 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR == current_encoding_ &&
1186 0 < calculated_size)
1190 if (0x3F00 < id.id || calculated_size > std::numeric_limits<uint16_t>::max())
1197 calculated_size += prev_size + extra_size;
1198 if (EncodingAlgorithmFlag::PL_CDR != current_encoding_)
1200 current_alignment += extra_size;
1203 serialized_member_size_ = NO_SERIALIZED_MEMBER_SIZE;
1205 return calculated_size;
1220 size_t& current_alignment)
1222 size_t initial_alignment = current_alignment;
1224 if (CdrVersion::XCDRv2 != cdr_version_ ||
1225 EncodingAlgorithmFlag::PL_CDR2 == current_encoding_)
1227 if (data.
has_value() || EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_)
1230 current_alignment += alignment(current_alignment, 4);
1234 size_t prev_size = {current_alignment - initial_alignment};
1235 size_t extra_size {0};
1237 if (CdrVersion::XCDRv1 == cdr_version_ &&
1238 (data.
has_value() || EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_))
1240 current_alignment = 0;
1245 if (CdrVersion::XCDRv2 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR2 == current_encoding_ &&
1246 0 < calculated_size)
1248 if (8 < calculated_size)
1251 if (NO_SERIALIZED_MEMBER_SIZE != serialized_member_size_)
1261 else if (CdrVersion::XCDRv1 == cdr_version_ &&
1262 (0 < calculated_size || EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_))
1266 if (0x3F00 < id.id || calculated_size > std::numeric_limits<uint16_t>::max())
1273 calculated_size += prev_size + extra_size;
1274 if (CdrVersion::XCDRv1 != cdr_version_)
1276 current_alignment += extra_size;
1280 return calculated_size;
1291 size_t& current_alignment);
1301 size_t& current_alignment);
1307 CdrVersion cdr_version_ {CdrVersion::XCDRv2};
1311 enum SerializedMemberSizeForNextInt
1313 NO_SERIALIZED_MEMBER_SIZE,
1314 SERIALIZED_MEMBER_SIZE,
1315 SERIALIZED_MEMBER_SIZE_4,
1316 SERIALIZED_MEMBER_SIZE_8
1319 serialized_member_size_ {NO_SERIALIZED_MEMBER_SIZE};
1322 size_t align64_ {4};
1324 inline size_t alignment(
1325 size_t current_alignment,
1326 size_t data_size)
const
1328 return (data_size - (current_alignment % data_size)) & (data_size - 1);
1331 template<class _T, typename std::enable_if<std::is_enum<_T>::value ||
1332 std::is_arithmetic<_T>::value>::type* =
nullptr>
1333 constexpr SerializedMemberSizeForNextInt get_serialized_member_size()
const
1335 return (1 ==
sizeof(_T) ? SERIALIZED_MEMBER_SIZE :
1336 (4 ==
sizeof(_T) ? SERIALIZED_MEMBER_SIZE_4 :
1337 (8 ==
sizeof(_T) ? SERIALIZED_MEMBER_SIZE_8 : NO_SERIALIZED_MEMBER_SIZE)));
1345 #endif // _FASTCDR_CDRSIZECALCULATOR_HPP_