FastCDR  Version 2.3.0
FastCDR
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 
35 namespace eprosima {
36 namespace fastcdr {
37 
38 class CdrSizeCalculator;
39 
40 template<class _T>
41 extern size_t calculate_serialized_size(
42  CdrSizeCalculator&,
43  const _T&,
44  size_t&);
45 
52 {
53 public:
54 
60  Cdr_DllAPI CdrSizeCalculator(
61  CdrVersion cdr_version);
62 
69  Cdr_DllAPI CdrSizeCalculator(
70  CdrVersion cdr_version,
71  EncodingAlgorithmFlag encoding);
72 
77  Cdr_DllAPI CdrVersion get_cdr_version() const;
78 
83  Cdr_DllAPI EncodingAlgorithmFlag get_encoding() const;
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  serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
491 
492  return calculated_size;
493  }
494 
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)
506  {
507  size_t initial_alignment {current_alignment};
508 
509  if (CdrVersion::XCDRv2 == cdr_version_)
510  {
511  // DHEADER
512  current_alignment += 4 + alignment(current_alignment, 4);
513  }
514 
515  current_alignment += 4 + alignment(current_alignment, 4);
516 
517  size_t calculated_size {current_alignment - initial_alignment};
518  calculated_size += calculate_array_serialized_size(data.data(), data.size(), current_alignment);
519 
520  if (CdrVersion::XCDRv2 == cdr_version_)
521  {
522  // Inform DHEADER can be joined with NEXTINT
523  serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
524  }
525 
526  return calculated_size;
527  }
528 
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)
540  {
541  size_t initial_alignment {current_alignment};
542 
543  current_alignment += 4 + alignment(current_alignment, 4);
544 
545  size_t calculated_size {current_alignment - initial_alignment};
546  calculated_size += calculate_array_serialized_size(data.data(), data.size(), current_alignment);
547 
548  if (CdrVersion::XCDRv2 == cdr_version_)
549  {
550  serialized_member_size_ = get_serialized_member_size<_T>();
551  }
552 
553  return calculated_size;
554  }
555 
562  TEMPLATE_SPEC
564  const std::vector<bool>& data,
565  size_t& current_alignment)
566  {
567  size_t calculated_size {data.size() + 4 + alignment(current_alignment, 4)};
568  current_alignment += calculated_size;
569 
570  return calculated_size;
571  }
572 
579  template<class _T, size_t _Size>
581  const std::array<_T, _Size>& data,
582  size_t& current_alignment)
583  {
584  size_t initial_alignment {current_alignment};
585 
586  if (CdrVersion::XCDRv2 == cdr_version_ &&
587  !is_multi_array_primitive(&data))
588  {
589  // DHEADER
590  current_alignment += 4 + alignment(current_alignment, 4);
591  }
592 
593  size_t calculated_size {current_alignment - initial_alignment};
594  calculated_size += calculate_array_serialized_size(data.data(), data.size(), current_alignment);
595 
596  if (CdrVersion::XCDRv2 == cdr_version_ &&
597  !is_multi_array_primitive(&data))
598  {
599  // Inform DHEADER can be joined with NEXTINT
600  serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
601  }
602 
603  return calculated_size;
604  }
605 
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)
617  {
618  size_t initial_alignment {current_alignment};
619 
620  if (CdrVersion::XCDRv2 == cdr_version_)
621  {
622  // DHEADER
623  current_alignment += 4 + alignment(current_alignment, 4);
624  }
625 
626  current_alignment += 4 + alignment(current_alignment, 4);
627 
628  size_t calculated_size {current_alignment - initial_alignment};
629  for (auto it = data.begin(); it != data.end(); ++it)
630  {
631  calculated_size += calculate_serialized_size(it->first, current_alignment);
632  calculated_size += calculate_serialized_size(it->second, current_alignment);
633  }
634 
635  if (CdrVersion::XCDRv2 == cdr_version_)
636  {
637  // Inform DHEADER can be joined with NEXTINT
638  serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
639  }
640 
641  return calculated_size;
642  }
643 
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)
655  {
656  size_t initial_alignment {current_alignment};
657 
658  current_alignment += 4 + alignment(current_alignment, 4);
659 
660  size_t calculated_size {current_alignment - initial_alignment};
661  for (auto it = data.begin(); it != data.end(); ++it)
662  {
663  calculated_size += calculate_serialized_size(it->first, current_alignment);
664  calculated_size += calculate_serialized_size(it->second, current_alignment);
665  }
666 
667  return calculated_size;
668  }
669 
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)
680  {
681  static_cast<void>(data);
682  ++current_alignment;
683  return 1;
684  }
685 
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)
696  {
697  static_cast<void>(data);
698  size_t calculated_size {2 + alignment(current_alignment, 2)};
699  current_alignment += calculated_size;
700  return calculated_size;
701  }
702 
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)
713  {
714  static_cast<void>(data);
715  size_t calculated_size {4 + alignment(current_alignment, 4)};
716  current_alignment += calculated_size;
717  return calculated_size;
718  }
719 
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)
730  {
731  static_cast<void>(data);
732  size_t calculated_size {8 + alignment(current_alignment, align64_)};
733  current_alignment += calculated_size;
734  return calculated_size;
735  }
736 
743  template<class _T>
745  const optional<_T>& data,
746  size_t& current_alignment)
747  {
748  size_t initial_alignment = current_alignment;
749 
750  if (CdrVersion::XCDRv2 == cdr_version_ &&
751  EncodingAlgorithmFlag::PL_CDR2 != current_encoding_)
752  {
753  // Take into account the boolean is_present;
754  ++current_alignment;
755  }
756 
757  size_t calculated_size {current_alignment - initial_alignment};
758 
759  if (data.has_value())
760  {
761  calculated_size += calculate_serialized_size(data.value(), current_alignment);
762  }
763 
764  return calculated_size;
765  }
766 
774  template<class _T>
776  const external<_T>& data,
777  size_t& current_alignment)
778  {
779  if (!data)
780  {
781  throw exception::BadParamException("External member is null");
782  }
783 
784  return calculate_serialized_size(*data, current_alignment);
785  }
786 
795  template<class _T>
797  const _T* data,
798  size_t num_elements,
799  size_t& current_alignment)
800  {
801  size_t calculated_size {0};
802 
803  for (size_t count = 0; count < num_elements; ++count)
804  {
805  calculated_size += calculate_serialized_size(data[count], current_alignment);
806  }
807 
808  return calculated_size;
809  }
810 
818  TEMPLATE_SPEC
820  const int8_t* data,
821  size_t num_elements,
822  size_t& current_alignment)
823  {
824  static_cast<void>(data);
825  current_alignment += num_elements;
826  return num_elements;
827  }
828 
836  TEMPLATE_SPEC
838  const uint8_t* data,
839  size_t num_elements,
840  size_t& current_alignment)
841  {
842  static_cast<void>(data);
843  current_alignment += num_elements;
844  return num_elements;
845  }
846 
854  TEMPLATE_SPEC
856  const char* data,
857  size_t num_elements,
858  size_t& current_alignment)
859  {
860  static_cast<void>(data);
861  current_alignment += num_elements;
862  return num_elements;
863  }
864 
872  TEMPLATE_SPEC
874  const wchar_t* data,
875  size_t num_elements,
876  size_t& current_alignment)
877  {
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;
882  }
883 
891  TEMPLATE_SPEC
893  const int16_t* data,
894  size_t num_elements,
895  size_t& current_alignment)
896  {
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;
901  }
902 
910  TEMPLATE_SPEC
912  const uint16_t* data,
913  size_t num_elements,
914  size_t& current_alignment)
915  {
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;
920  }
921 
929  TEMPLATE_SPEC
931  const int32_t* data,
932  size_t num_elements,
933  size_t& current_alignment)
934  {
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;
939  }
940 
948  TEMPLATE_SPEC
950  const uint32_t* data,
951  size_t num_elements,
952  size_t& current_alignment)
953  {
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;
958  }
959 
967  TEMPLATE_SPEC
969  const int64_t* data,
970  size_t num_elements,
971  size_t& current_alignment)
972  {
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;
977  }
978 
986  TEMPLATE_SPEC
988  const uint64_t* data,
989  size_t num_elements,
990  size_t& current_alignment)
991  {
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;
996  }
997 
1005  TEMPLATE_SPEC
1007  const float* data,
1008  size_t num_elements,
1009  size_t& current_alignment)
1010  {
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;
1015  }
1016 
1024  TEMPLATE_SPEC
1026  const double* data,
1027  size_t num_elements,
1028  size_t& current_alignment)
1029  {
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;
1034  }
1035 
1043  TEMPLATE_SPEC
1045  const long double* data,
1046  size_t num_elements,
1047  size_t& current_alignment)
1048  {
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;
1053  }
1054 
1062  template<class _T, size_t _N>
1064  const std::array<_T, _N>* data,
1065  size_t num_elements,
1066  size_t& current_alignment)
1067  {
1068  return calculate_array_serialized_size(data->data(), num_elements * data->size(), current_alignment);
1069  }
1070 
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)
1082  {
1083  return calculate_array_serialized_size(data.data(), data.size(), current_alignment);
1084  }
1085 
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)
1097  {
1098  size_t initial_alignment {current_alignment};
1099 
1100  if (CdrVersion::XCDRv2 == cdr_version_)
1101  {
1102  // DHEADER
1103  current_alignment += 4 + alignment(current_alignment, 4);
1104  }
1105 
1106  size_t calculated_size {current_alignment - initial_alignment};
1107  calculated_size += calculate_array_serialized_size(data.data(), data.size(), current_alignment);
1108 
1109  if (CdrVersion::XCDRv2 == cdr_version_)
1110  {
1111  // Inform DHEADER can be joined with NEXTINT
1112  serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
1113  }
1114 
1115  return calculated_size;
1116  }
1117 
1124  TEMPLATE_SPEC
1126  const std::vector<bool>& data,
1127  size_t& current_alignment)
1128  {
1129  current_alignment += data.size();
1130  return data.size();
1131  }
1132 
1141  template<class _T>
1143  const MemberId& id,
1144  const _T& data,
1145  size_t& current_alignment)
1146  {
1147  size_t initial_alignment {current_alignment};
1148 
1149  if (EncodingAlgorithmFlag::PL_CDR == current_encoding_ ||
1150  EncodingAlgorithmFlag::PL_CDR2 == current_encoding_)
1151  {
1152  // Align to 4 for the XCDR header before calculating the data serialized size.
1153  current_alignment += alignment(current_alignment, 4);
1154  }
1155 
1156  size_t prev_size {current_alignment - initial_alignment};
1157  size_t extra_size {0};
1158 
1159  if (EncodingAlgorithmFlag::PL_CDR == current_encoding_)
1160  {
1161  current_alignment = 0;
1162  }
1163 
1164  size_t calculated_size {calculate_serialized_size(data, current_alignment)};
1165 
1166  if (CdrVersion::XCDRv2 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR2 == current_encoding_ &&
1167  0 < calculated_size)
1168  {
1169 
1170  if (8 < calculated_size ||
1171  (1 != calculated_size && 2 != calculated_size && 4 != calculated_size &&
1172  8 != calculated_size))
1173  {
1174  extra_size = 8; // Long EMHEADER.
1175  if (NO_SERIALIZED_MEMBER_SIZE != serialized_member_size_)
1176  {
1177  calculated_size -= 4; // Join NEXTINT and DHEADER.
1178  }
1179  }
1180  else
1181  {
1182  extra_size = 4; // EMHEADER;
1183  }
1184  }
1185  else if (CdrVersion::XCDRv1 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR == current_encoding_ &&
1186  0 < calculated_size)
1187  {
1188  extra_size = 4; // ShortMemberHeader
1189 
1190  if (0x3F00 < id.id || calculated_size > std::numeric_limits<uint16_t>::max())
1191  {
1192  extra_size += 8; // LongMemberHeader
1193  }
1194 
1195  }
1196 
1197  calculated_size += prev_size + extra_size;
1198  if (EncodingAlgorithmFlag::PL_CDR != current_encoding_)
1199  {
1200  current_alignment += extra_size;
1201  }
1202 
1203  serialized_member_size_ = NO_SERIALIZED_MEMBER_SIZE;
1204 
1205  return calculated_size;
1206  }
1207 
1216  template<class _T>
1218  const MemberId& id,
1219  const optional<_T>& data,
1220  size_t& current_alignment)
1221  {
1222  size_t initial_alignment = current_alignment;
1223 
1224  if (CdrVersion::XCDRv2 != cdr_version_ ||
1225  EncodingAlgorithmFlag::PL_CDR2 == current_encoding_)
1226  {
1227  if (data.has_value() || EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_)
1228  {
1229  // Align to 4 for the XCDR header before calculating the data serialized size.
1230  current_alignment += alignment(current_alignment, 4);
1231  }
1232  }
1233 
1234  size_t prev_size = {current_alignment - initial_alignment};
1235  size_t extra_size {0};
1236 
1237  if (CdrVersion::XCDRv1 == cdr_version_ &&
1238  (data.has_value() || EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_))
1239  {
1240  current_alignment = 0;
1241  }
1242 
1243  size_t calculated_size {calculate_serialized_size(data, current_alignment)};
1244 
1245  if (CdrVersion::XCDRv2 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR2 == current_encoding_ &&
1246  0 < calculated_size)
1247  {
1248  if (8 < calculated_size)
1249  {
1250  extra_size = 8; // Long EMHEADER.
1251  if (NO_SERIALIZED_MEMBER_SIZE != serialized_member_size_)
1252  {
1253  extra_size -= 4; // Join NEXTINT and DHEADER.
1254  }
1255  }
1256  else
1257  {
1258  extra_size = 4; // EMHEADER;
1259  }
1260  }
1261  else if (CdrVersion::XCDRv1 == cdr_version_ &&
1262  (0 < calculated_size || EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_))
1263  {
1264  extra_size = 4; // ShortMemberHeader
1265 
1266  if (0x3F00 < id.id || calculated_size > std::numeric_limits<uint16_t>::max())
1267  {
1268  extra_size += 8; // LongMemberHeader
1269  }
1270 
1271  }
1272 
1273  calculated_size += prev_size + extra_size;
1274  if (CdrVersion::XCDRv1 != cdr_version_)
1275  {
1276  current_alignment += extra_size;
1277  }
1278 
1279 
1280  return calculated_size;
1281  }
1282 
1289  Cdr_DllAPI size_t begin_calculate_type_serialized_size(
1290  EncodingAlgorithmFlag new_encoding,
1291  size_t& current_alignment);
1292 
1299  Cdr_DllAPI size_t end_calculate_type_serialized_size(
1300  EncodingAlgorithmFlag new_encoding,
1301  size_t& current_alignment);
1302 
1303 private:
1304 
1305  CdrSizeCalculator() = delete;
1306 
1307  CdrVersion cdr_version_ {CdrVersion::XCDRv2};
1308 
1309  EncodingAlgorithmFlag current_encoding_ {EncodingAlgorithmFlag::PLAIN_CDR2};
1310 
1311  enum SerializedMemberSizeForNextInt
1312  {
1313  NO_SERIALIZED_MEMBER_SIZE,
1314  SERIALIZED_MEMBER_SIZE,
1315  SERIALIZED_MEMBER_SIZE_4,
1316  SERIALIZED_MEMBER_SIZE_8
1317  }
1319  serialized_member_size_ {NO_SERIALIZED_MEMBER_SIZE};
1320 
1322  size_t align64_ {4};
1323 
1324  inline size_t alignment(
1325  size_t current_alignment,
1326  size_t data_size) const
1327  {
1328  return (data_size - (current_alignment % data_size)) & (data_size - 1);
1329  }
1330 
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
1334  {
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)));
1338  }
1339 
1340 };
1341 
1342 } // namespace fastcdr
1343 } // namespace eprosima
1344 
1345 #endif // _FASTCDR_CDRSIZECALCULATOR_HPP_
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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:744
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:987
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:911
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:1025
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:855
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:837
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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:614
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:930
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:949
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:1063
eprosima::fastcdr::CdrSizeCalculator::get_encoding
Cdr_DllAPI EncodingAlgorithmFlag get_encoding() const
Retrieves the current encoding algorithm used by the instance.
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::optional::value
T & value() &
Returns the contained value.
Definition: optional.hpp:135
eprosima::fastcdr::CdrSizeCalculator::end_calculate_type_serialized_size
Cdr_DllAPI size_t end_calculate_type_serialized_size(EncodingAlgorithmFlag new_encoding, size_t &current_alignment)
Indicates the ending of a constructed type.
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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:775
eprosima::fastcdr::CdrSizeCalculator::calculate_member_serialized_size
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:1217
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:796
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::CdrSizeCalculator::get_cdr_version
Cdr_DllAPI CdrVersion get_cdr_version() const
Retrieves the version of the encoding algorithm used by the instance.
eprosima::fastcdr::calculate_serialized_size
size_t calculate_serialized_size(CdrSizeCalculator &, const _T &, size_t &)
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::MemberId
Definition: MemberId.hpp:27
eprosima::fastcdr::CdrSizeCalculator::begin_calculate_type_serialized_size
Cdr_DllAPI size_t begin_calculate_type_serialized_size(EncodingAlgorithmFlag new_encoding, size_t &current_alignment)
Indicates a new constructed type will be calculated.
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::external
This class template manages an external member, a member declared to be external to the storage of a ...
Definition: external.hpp:29
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:968
eprosima::fastcdr::optional
This class template manages an optional contained value, i.e.
Definition: optional.hpp:46
eprosima::fastcdr::is_multi_array_primitive
constexpr bool is_multi_array_primitive(...)
Basis.
Definition: container_recursive_inspector.hpp:27
eprosima::fastcdr::CdrSizeCalculator::calculate_member_serialized_size
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:1142
eprosima::fastcdr::EncodingAlgorithmFlag
EncodingAlgorithmFlag
This enumeration represents the supported XCDR encoding algorithms.
Definition: CdrEncoding.hpp:37
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:1125
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:1079
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:1006
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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:580
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:892
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:1044
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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:503
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::optional::has_value
bool has_value() const
Checks whether the optional contains a value.
Definition: optional.hpp:202
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:819
eprosima::fastcdr::fixed_string
Template class for non-alloc strings.
Definition: fixed_size_string.hpp:44
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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:563
eprosima::fastcdr::CdrVersion
CdrVersion
This enumeration represents the kinds of CDR serialization supported by eprosima::fastcdr::CDR.
Definition: CdrEncoding.hpp:24
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::fixed_string::size
size_t size() const noexcept
Returns the size of the string.
Definition: fixed_size_string.hpp:288
eprosima::fastcdr::CdrSizeCalculator
This class offers an interface to calculate the encoded size of a type serialized using a support enc...
Definition: CdrSizeCalculator.hpp:51
eprosima
Definition: fixed_size_string.hpp:32
eprosima::fastcdr::CdrSizeCalculator::calculate_serialized_size
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
eprosima::fastcdr::exception::BadParamException
This class is thrown as an exception when an invalid parameter is being serialized.
Definition: BadParamException.h:27
eprosima::fastcdr::CdrSizeCalculator::calculate_array_serialized_size
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:873