Coverage Report

Created: 2026-07-25 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Fast-CDR/include/fastcdr/CdrSizeCalculator.hpp
Line
Count
Source
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 <memory>
24
#include <vector>
25
26
#include "fastcdr_dll.h"
27
28
#include "CdrContext.hpp"
29
#include "CdrEncoding.hpp"
30
#include "cdr/fixed_size_string.hpp"
31
#include "detail/container_recursive_inspector.hpp"
32
#include "exceptions/BadParamException.h"
33
#include "xcdr/external.hpp"
34
#include "xcdr/MemberId.hpp"
35
#include "xcdr/optional.hpp"
36
37
namespace eprosima {
38
namespace fastcdr {
39
40
class CdrSizeCalculator;
41
42
template<class _T>
43
extern size_t calculate_serialized_size(
44
        CdrSizeCalculator&,
45
        const _T&,
46
        size_t&);
47
48
/*!
49
 * @brief This class offers an interface to calculate the encoded size of a type serialized using a support encoding
50
 * algorithm.
51
 * @ingroup FASTCDRAPIREFERENCE
52
 */
53
class CdrSizeCalculator
54
{
55
public:
56
57
    /*!
58
     * @brief Constructor.
59
     * @param[in] cdr_version Represents the version of the encoding algorithm that will be used for the encoding.
60
     * The default value is CdrVersion::XCDRv2.
61
     */
62
    Cdr_DllAPI CdrSizeCalculator(
63
            CdrVersion cdr_version);
64
65
    /*!
66
     * @brief Constructor.
67
     * @param[in] context Shared pointer to a CdrContext object that will be used during the encoding.
68
     * @param[in] cdr_version Represents the version of the encoding algorithm that will be used for the encoding.
69
     * The default value is CdrVersion::XCDRv2.
70
     */
71
    Cdr_DllAPI CdrSizeCalculator(
72
            const std::shared_ptr<CdrContext>& context,
73
            CdrVersion cdr_version);
74
75
    /*!
76
     * @brief Constructor.
77
     * @param[in] cdr_version Represents the version of the encoding algorithm that will be used for the encoding.
78
     * The default value is CdrVersion::XCDRv2.
79
     * @param[in] encoding Represents the initial encoding.
80
     */
81
    Cdr_DllAPI CdrSizeCalculator(
82
            CdrVersion cdr_version,
83
            EncodingAlgorithmFlag encoding);
84
85
    /*!
86
     * @brief Constructor.
87
     * @param[in] context Shared pointer to a CdrContext object that will be used during the encoding.
88
     * @param[in] cdr_version Represents the version of the encoding algorithm that will be used for the encoding.
89
     * The default value is CdrVersion::XCDRv2.
90
     * @param[in] encoding Represents the initial encoding.
91
     */
92
    Cdr_DllAPI CdrSizeCalculator(
93
            const std::shared_ptr<CdrContext>& context,
94
            CdrVersion cdr_version,
95
            EncodingAlgorithmFlag encoding);
96
97
    /*!
98
     * @brief Retrieves the version of the encoding algorithm used by the instance.
99
     * @return Configured CdrVersion.
100
     */
101
    Cdr_DllAPI CdrVersion get_cdr_version() const;
102
103
    /*!
104
     * @brief Retrieves the current encoding algorithm used by the instance.
105
     * @return Configured EncodingAlgorithmFlag.
106
     */
107
    Cdr_DllAPI EncodingAlgorithmFlag get_encoding() const;
108
109
    /*!
110
     * @brief Retrieves the context configured for the instance.
111
     * @return The context.
112
     */
113
    Cdr_DllAPI std::shared_ptr<CdrContext> get_context() const;
114
115
    /*!
116
     * @brief Generic template which calculates the encoded size of an instance of an unknown type.
117
     * @tparam _T Instance's type.
118
     * @param[in] data Reference to the instance.
119
     * @param[inout] current_alignment Current alignment in the encoding.
120
     * @return Encoded size of the instance.
121
     */
122
    template<class _T, typename std::enable_if<!std::is_enum<_T>::value>::type* = nullptr, typename = void>
123
    size_t calculate_serialized_size(
124
            const _T& data,
125
            size_t& current_alignment)
126
    {
127
        return eprosima::fastcdr::calculate_serialized_size(*this, data, current_alignment);
128
    }
129
130
    /*!
131
     * @brief Template which calculates the encoded size of an instance of an enumeration of 32bits.
132
     * @tparam _T Instance's type.
133
     * @param[in] data Reference to the instance.
134
     * @param[inout] current_alignment Current alignment in the encoding.
135
     * @return Encoded size of the instance.
136
     */
137
    template<class _T,
138
            typename std::enable_if<std::is_enum<_T>::value>::type* = nullptr,
139
            typename std::enable_if<std::is_same<typename std::underlying_type<_T>::type,
140
            int32_t>::value>::type* = nullptr>
141
    size_t calculate_serialized_size(
142
            const _T& data,
143
            size_t& current_alignment)
144
    {
145
        return calculate_serialized_size(static_cast<int32_t>(data), current_alignment);
146
    }
147
148
    /*!
149
     * @brief Template which calculates the encoded size of an instance of an enumeration of unsigned 32bits.
150
     * @tparam _T Instance's type.
151
     * @param[in] data Reference to the instance.
152
     * @param[inout] current_alignment Current alignment in the encoding.
153
     * @return Encoded size of the instance.
154
     */
155
    template<class _T,
156
            typename std::enable_if<std::is_enum<_T>::value>::type* = nullptr,
157
            typename std::enable_if<std::is_same<typename std::underlying_type<_T>::type,
158
            uint32_t>::value>::type* = nullptr>
159
    size_t calculate_serialized_size(
160
            const _T& data,
161
            size_t& current_alignment)
162
    {
163
        return calculate_serialized_size(static_cast<uint32_t>(data), current_alignment);
164
    }
165
166
    /*!
167
     * @brief Template which calculates the encoded size of an instance of an enumeration of 16bits.
168
     * @tparam _T Instance's type.
169
     * @param[in] data Reference to the instance.
170
     * @param[inout] current_alignment Current alignment in the encoding.
171
     * @return Encoded size of the instance.
172
     */
173
    template<class _T,
174
            typename std::enable_if<std::is_enum<_T>::value>::type* = nullptr,
175
            typename std::enable_if<std::is_same<typename std::underlying_type<_T>::type,
176
            int16_t>::value>::type* = nullptr>
177
    size_t calculate_serialized_size(
178
            const _T& data,
179
            size_t& current_alignment)
180
    {
181
        return calculate_serialized_size(static_cast<int16_t>(data), current_alignment);
182
    }
183
184
    /*!
185
     * @brief Template which calculates the encoded size of an instance of an enumeration of unsigned 16bits.
186
     * @tparam _T Instance's type.
187
     * @param[in] data Reference to the instance.
188
     * @param[inout] current_alignment Current alignment in the encoding.
189
     * @return Encoded size of the instance.
190
     */
191
    template<class _T,
192
            typename std::enable_if<std::is_enum<_T>::value>::type* = nullptr,
193
            typename std::enable_if<std::is_same<typename std::underlying_type<_T>::type,
194
            uint16_t>::value>::type* = nullptr>
195
    size_t calculate_serialized_size(
196
            const _T& data,
197
            size_t& current_alignment)
198
    {
199
        return calculate_serialized_size(static_cast<uint16_t>(data), current_alignment);
200
    }
201
202
    /*!
203
     * @brief Template which calculates the encoded size of an instance of an enumeration of 8bits.
204
     * @tparam _T Instance's type.
205
     * @param[in] data Reference to the instance.
206
     * @param[inout] current_alignment Current alignment in the encoding.
207
     * @return Encoded size of the instance.
208
     */
209
    template<class _T,
210
            typename std::enable_if<std::is_enum<_T>::value>::type* = nullptr,
211
            typename std::enable_if<std::is_same<typename std::underlying_type<_T>::type,
212
            int8_t>::value>::type* = nullptr>
213
    size_t calculate_serialized_size(
214
            const _T& data,
215
            size_t& current_alignment)
216
    {
217
        return calculate_serialized_size(static_cast<int8_t>(data), current_alignment);
218
    }
219
220
    /*!
221
     * @brief Template which calculates the encoded size of an instance of an enumeration of unsigned 8bits.
222
     * @tparam _T Instance's type.
223
     * @param[in] data Reference to the instance.
224
     * @param[inout] current_alignment Current alignment in the encoding.
225
     * @return Encoded size of the instance.
226
     */
227
    template<class _T,
228
            typename std::enable_if<std::is_enum<_T>::value>::type* = nullptr,
229
            typename std::enable_if<std::is_same<typename std::underlying_type<_T>::type,
230
            uint8_t>::value>::type* = nullptr>
231
    size_t calculate_serialized_size(
232
            const _T& data,
233
            size_t& current_alignment)
234
    {
235
        return calculate_serialized_size(static_cast<uint8_t>(data), current_alignment);
236
    }
237
238
    /*!
239
     * @brief Specific template which calculates the encoded size of an instance of an int8_t.
240
     * @param[in] data Reference to the instance.
241
     * @param[inout] current_alignment Current alignment in the encoding.
242
     * @return Encoded size of the instance.
243
     */
244
    TEMPLATE_SPEC
245
    size_t calculate_serialized_size(
246
            const int8_t& data,
247
            size_t& current_alignment)
248
0
    {
249
0
        static_cast<void>(data);
250
0
        ++current_alignment;
251
0
        return 1;
252
0
    }
253
254
    /*!
255
     * @brief Specific template which calculates the encoded size of an instance of an uint8_t.
256
     * @param[in] data Reference to the instance.
257
     * @param[inout] current_alignment Current alignment in the encoding.
258
     * @return Encoded size of the instance.
259
     */
260
    TEMPLATE_SPEC
261
    size_t calculate_serialized_size(
262
            const uint8_t& data,
263
            size_t& current_alignment)
264
0
    {
265
0
        static_cast<void>(data);
266
0
        ++current_alignment;
267
0
        return 1;
268
0
    }
269
270
    /*!
271
     * @brief Specific template which calculates the encoded size of an instance of a char.
272
     * @param[in] data Reference to the instance.
273
     * @param[inout] current_alignment Current alignment in the encoding.
274
     * @return Encoded size of the instance.
275
     */
276
    TEMPLATE_SPEC
277
    size_t calculate_serialized_size(
278
            const char& data,
279
            size_t& current_alignment)
280
0
    {
281
0
        static_cast<void>(data);
282
0
        ++current_alignment;
283
0
        return 1;
284
0
    }
285
286
    /*!
287
     * @brief Specific template which calculates the encoded size of an instance of a bool.
288
     * @param[in] data Reference to the instance.
289
     * @param[inout] current_alignment Current alignment in the encoding.
290
     * @return Encoded size of the instance.
291
     */
292
    TEMPLATE_SPEC
293
    size_t calculate_serialized_size(
294
            const bool& data,
295
            size_t& current_alignment)
296
0
    {
297
0
        static_cast<void>(data);
298
0
        ++current_alignment;
299
0
        return 1;
300
0
    }
301
302
    /*!
303
     * @brief Specific template which calculates the encoded size of an instance of a wchar.
304
     * @param[in] data Reference to the instance.
305
     * @param[inout] current_alignment Current alignment in the encoding.
306
     * @return Encoded size of the instance.
307
     */
308
    TEMPLATE_SPEC
309
    size_t calculate_serialized_size(
310
            const wchar_t& data,
311
            size_t& current_alignment)
312
0
    {
313
0
        static_cast<void>(data);
314
0
        size_t calculated_size {2 + alignment(current_alignment, 2)};
315
0
        current_alignment += calculated_size;
316
0
        return calculated_size;
317
0
    }
318
319
    /*!
320
     * @brief Specific template which calculates the encoded size of an instance of a int16_t.
321
     * @param[in] data Reference to the instance.
322
     * @param[inout] current_alignment Current alignment in the encoding.
323
     * @return Encoded size of the instance.
324
     */
325
    TEMPLATE_SPEC
326
    size_t calculate_serialized_size(
327
            const int16_t& data,
328
            size_t& current_alignment)
329
0
    {
330
0
        static_cast<void>(data);
331
0
        size_t calculated_size {2 + alignment(current_alignment, 2)};
332
0
        current_alignment += calculated_size;
333
0
        return calculated_size;
334
0
    }
335
336
    /*!
337
     * @brief Specific template which calculates the encoded size of an instance of a uint16_t.
338
     * @param[in] data Reference to the instance.
339
     * @param[inout] current_alignment Current alignment in the encoding.
340
     * @return Encoded size of the instance.
341
     */
342
    TEMPLATE_SPEC
343
    size_t calculate_serialized_size(
344
            const uint16_t& data,
345
            size_t& current_alignment)
346
0
    {
347
0
        static_cast<void>(data);
348
0
        size_t calculated_size {2 + alignment(current_alignment, 2)};
349
0
        current_alignment += calculated_size;
350
0
        return calculated_size;
351
0
    }
352
353
    /*!
354
     * @brief Specific template which calculates the encoded size of an instance of a int32_t.
355
     * @param[in] data Reference to the instance.
356
     * @param[inout] current_alignment Current alignment in the encoding.
357
     * @return Encoded size of the instance.
358
     */
359
    TEMPLATE_SPEC
360
    size_t calculate_serialized_size(
361
            const int32_t& data,
362
            size_t& current_alignment)
363
0
    {
364
0
        static_cast<void>(data);
365
0
        size_t calculated_size {4 + alignment(current_alignment, 4)};
366
0
        current_alignment += calculated_size;
367
0
        return calculated_size;
368
0
    }
369
370
    /*!
371
     * @brief Specific template which calculates the encoded size of an instance of a uint32_t.
372
     * @param[in] data Reference to the instance.
373
     * @param[inout] current_alignment Current alignment in the encoding.
374
     * @return Encoded size of the instance.
375
     */
376
    TEMPLATE_SPEC
377
    size_t calculate_serialized_size(
378
            const uint32_t& data,
379
            size_t& current_alignment)
380
0
    {
381
0
        static_cast<void>(data);
382
0
        size_t calculated_size {4 + alignment(current_alignment, 4)};
383
0
        current_alignment += calculated_size;
384
0
        return calculated_size;
385
0
    }
386
387
    /*!
388
     * @brief Specific template which calculates the encoded size of an instance of a int64_t.
389
     * @param[in] data Reference to the instance.
390
     * @param[inout] current_alignment Current alignment in the encoding.
391
     * @return Encoded size of the instance.
392
     */
393
    TEMPLATE_SPEC
394
    size_t calculate_serialized_size(
395
            const int64_t& data,
396
            size_t& current_alignment)
397
0
    {
398
0
        static_cast<void>(data);
399
0
        size_t calculated_size {8 + alignment(current_alignment, align64_)};
400
0
        current_alignment += calculated_size;
401
0
        return calculated_size;
402
0
    }
403
404
    /*!
405
     * @brief Specific template which calculates the encoded size of an instance of a uint64_t.
406
     * @param[in] data Reference to the instance.
407
     * @param[inout] current_alignment Current alignment in the encoding.
408
     * @return Encoded size of the instance.
409
     */
410
    TEMPLATE_SPEC
411
    size_t calculate_serialized_size(
412
            const uint64_t& data,
413
            size_t& current_alignment)
414
0
    {
415
0
        static_cast<void>(data);
416
0
        size_t calculated_size {8 + alignment(current_alignment, align64_)};
417
0
        current_alignment += calculated_size;
418
0
        return calculated_size;
419
0
    }
420
421
    /*!
422
     * @brief Specific template which calculates the encoded size of an instance of a float.
423
     * @param[in] data Reference to the instance.
424
     * @param[inout] current_alignment Current alignment in the encoding.
425
     * @return Encoded size of the instance.
426
     */
427
    TEMPLATE_SPEC
428
    size_t calculate_serialized_size(
429
            const float& data,
430
            size_t& current_alignment)
431
0
    {
432
0
        static_cast<void>(data);
433
0
        size_t calculated_size {4 + alignment(current_alignment, 4)};
434
0
        current_alignment += calculated_size;
435
0
        return calculated_size;
436
0
    }
437
438
    /*!
439
     * @brief Specific template which calculates the encoded size of an instance of a double.
440
     * @param[in] data Reference to the instance.
441
     * @param[inout] current_alignment Current alignment in the encoding.
442
     * @return Encoded size of the instance.
443
     */
444
    TEMPLATE_SPEC
445
    size_t calculate_serialized_size(
446
            const double& data,
447
            size_t& current_alignment)
448
0
    {
449
0
        static_cast<void>(data);
450
0
        size_t calculated_size {8 + alignment(current_alignment, align64_)};
451
0
        current_alignment += calculated_size;
452
0
        return calculated_size;
453
0
    }
454
455
    /*!
456
     * @brief Specific template which calculates the encoded size of an instance of a long double.
457
     * @param[in] data Reference to the instance.
458
     * @param[inout] current_alignment Current alignment in the encoding.
459
     * @return Encoded size of the instance.
460
     */
461
    TEMPLATE_SPEC
462
    size_t calculate_serialized_size(
463
            const long double& data,
464
            size_t& current_alignment)
465
0
    {
466
0
        static_cast<void>(data);
467
0
        size_t calculated_size {16 + alignment(current_alignment, align64_)};
468
0
        current_alignment += calculated_size;
469
0
        return calculated_size;
470
0
    }
471
472
    /*!
473
     * @brief Specific template which calculates the encoded size of an instance of a std::string.
474
     * @param[in] data Reference to the instance.
475
     * @param[inout] current_alignment Current alignment in the encoding.
476
     * @return Encoded size of the instance.
477
     */
478
    TEMPLATE_SPEC
479
    size_t calculate_serialized_size(
480
            const std::string& data,
481
            size_t& current_alignment)
482
0
    {
483
0
        size_t calculated_size {4 + alignment(current_alignment, 4) + data.size() + 1};
484
0
        current_alignment += calculated_size;
485
0
        serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
486
0
487
0
        return calculated_size;
488
0
    }
489
490
    /*!
491
     * @brief Specific template which calculates the encoded size of an instance of a std::wstring.
492
     * @param[in] data Reference to the instance.
493
     * @param[inout] current_alignment Current alignment in the encoding.
494
     * @return Encoded size of the instance.
495
     */
496
    TEMPLATE_SPEC
497
    size_t calculate_serialized_size(
498
            const std::wstring& data,
499
            size_t& current_alignment)
500
0
    {
501
0
        size_t calculated_size {4 + alignment(current_alignment, 4) + data.size() * 2};
502
0
        current_alignment += calculated_size;
503
0
504
0
        return calculated_size;
505
0
    }
506
507
    /*!
508
     * @brief Specific template which calculates the encoded size of an instance of a fixed_string.
509
     * @param[in] data Reference to the instance.
510
     * @param[inout] current_alignment Current alignment in the encoding.
511
     * @return Encoded size of the instance.
512
     */
513
    template<size_t MAX_CHARS>
514
    size_t calculate_serialized_size(
515
            const fixed_string<MAX_CHARS>& data,
516
            size_t& current_alignment)
517
    {
518
        size_t calculated_size {4 + alignment(current_alignment, 4) + data.size() + 1};
519
        current_alignment += calculated_size;
520
        serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
521
522
        return calculated_size;
523
    }
524
525
    /*!
526
     * @brief Specific template which calculates the encoded size of an instance of a sequence of non-primitives.
527
     * @param[in] data Reference to the instance.
528
     * @param[inout] current_alignment Current alignment in the encoding.
529
     * @return Encoded size of the instance.
530
     */
531
    template<class _T, typename std::enable_if<!std::is_enum<_T>::value &&
532
            !std::is_arithmetic<_T>::value>::type* = nullptr>
533
    size_t calculate_serialized_size(
534
            const std::vector<_T>& data,
535
            size_t& current_alignment)
536
    {
537
        size_t initial_alignment {current_alignment};
538
539
        if (CdrVersion::XCDRv2 == cdr_version_)
540
        {
541
            // DHEADER
542
            current_alignment += 4 + alignment(current_alignment, 4);
543
        }
544
545
        current_alignment += 4 + alignment(current_alignment, 4);
546
547
        size_t calculated_size {current_alignment - initial_alignment};
548
        calculated_size += calculate_array_serialized_size(data.data(), data.size(), current_alignment);
549
550
        if (CdrVersion::XCDRv2 == cdr_version_)
551
        {
552
            // Inform DHEADER can be joined with NEXTINT
553
            serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
554
        }
555
556
        return calculated_size;
557
    }
558
559
    /*!
560
     * @brief Specific template which calculates the encoded size of an instance of a sequence of primitives.
561
     * @param[in] data Reference to the instance.
562
     * @param[inout] current_alignment Current alignment in the encoding.
563
     * @return Encoded size of the instance.
564
     */
565
    template<class _T, typename std::enable_if<std::is_enum<_T>::value ||
566
            std::is_arithmetic<_T>::value>::type* = nullptr>
567
    size_t calculate_serialized_size(
568
            const std::vector<_T>& data,
569
            size_t& current_alignment)
570
    {
571
        size_t initial_alignment {current_alignment};
572
573
        current_alignment += 4 + alignment(current_alignment, 4);
574
575
        size_t calculated_size {current_alignment - initial_alignment};
576
        calculated_size += calculate_array_serialized_size(data.data(), data.size(), current_alignment);
577
578
        if (CdrVersion::XCDRv2 == cdr_version_)
579
        {
580
            serialized_member_size_ = get_serialized_member_size<_T>();
581
        }
582
583
        return calculated_size;
584
    }
585
586
    /*!
587
     * @brief Specific template which calculates the encoded size of an instance of a sequence of bool.
588
     * @param[in] data Reference to the instance.
589
     * @param[inout] current_alignment Current alignment in the encoding.
590
     * @return Encoded size of the instance.
591
     */
592
    TEMPLATE_SPEC
593
    size_t calculate_serialized_size(
594
            const std::vector<bool>& data,
595
            size_t& current_alignment)
596
0
    {
597
0
        size_t calculated_size {data.size() + 4 + alignment(current_alignment, 4)};
598
0
        current_alignment += calculated_size;
599
0
600
0
        return calculated_size;
601
0
    }
602
603
    /*!
604
     * @brief Specific template which calculates the encoded size of an instance of an array.
605
     * @param[in] data Reference to the instance.
606
     * @param[inout] current_alignment Current alignment in the encoding.
607
     * @return Encoded size of the instance.
608
     */
609
    template<class _T, size_t _Size>
610
    size_t calculate_serialized_size(
611
            const std::array<_T, _Size>& data,
612
            size_t& current_alignment)
613
    {
614
        size_t initial_alignment {current_alignment};
615
616
        if (CdrVersion::XCDRv2 == cdr_version_ &&
617
                !is_multi_array_primitive(&data))
618
        {
619
            // DHEADER
620
            current_alignment += 4 + alignment(current_alignment, 4);
621
        }
622
623
        size_t calculated_size {current_alignment - initial_alignment};
624
        calculated_size += calculate_array_serialized_size(data.data(), data.size(), current_alignment);
625
626
        if (CdrVersion::XCDRv2 == cdr_version_ &&
627
                !is_multi_array_primitive(&data))
628
        {
629
            // Inform DHEADER can be joined with NEXTINT
630
            serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
631
        }
632
633
        return calculated_size;
634
    }
635
636
    /*!
637
     * @brief Specific template which calculates the encoded size of an instance of a map of non-primitives.
638
     * @param[in] data Reference to the instance.
639
     * @param[inout] current_alignment Current alignment in the encoding.
640
     * @return Encoded size of the instance.
641
     */
642
    template<class _K, class _V, typename std::enable_if<!std::is_enum<_V>::value &&
643
            !std::is_arithmetic<_V>::value>::type* = nullptr>
644
    size_t calculate_serialized_size(
645
            const std::map<_K, _V>& data,
646
            size_t& current_alignment)
647
    {
648
        size_t initial_alignment {current_alignment};
649
650
        if (CdrVersion::XCDRv2 == cdr_version_)
651
        {
652
            // DHEADER
653
            current_alignment += 4 + alignment(current_alignment, 4);
654
        }
655
656
        current_alignment += 4 + alignment(current_alignment, 4);
657
658
        size_t calculated_size {current_alignment - initial_alignment};
659
        for (auto it = data.begin(); it != data.end(); ++it)
660
        {
661
            calculated_size += calculate_serialized_size(it->first, current_alignment);
662
            calculated_size += calculate_serialized_size(it->second, current_alignment);
663
        }
664
665
        if (CdrVersion::XCDRv2 == cdr_version_)
666
        {
667
            // Inform DHEADER can be joined with NEXTINT
668
            serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
669
        }
670
671
        return calculated_size;
672
    }
673
674
    /*!
675
     * @brief Specific template which calculates the encoded size of an instance of a map of primitives.
676
     * @param[in] data Reference to the instance.
677
     * @param[inout] current_alignment Current alignment in the encoding.
678
     * @return Encoded size of the instance.
679
     */
680
    template<class _K, class _V, typename std::enable_if<std::is_enum<_V>::value ||
681
            std::is_arithmetic<_V>::value>::type* = nullptr>
682
    size_t calculate_serialized_size(
683
            const std::map<_K, _V>& data,
684
            size_t& current_alignment)
685
    {
686
        size_t initial_alignment {current_alignment};
687
688
        current_alignment += 4 + alignment(current_alignment, 4);
689
690
        size_t calculated_size {current_alignment - initial_alignment};
691
        for (auto it = data.begin(); it != data.end(); ++it)
692
        {
693
            calculated_size += calculate_serialized_size(it->first, current_alignment);
694
            calculated_size += calculate_serialized_size(it->second, current_alignment);
695
        }
696
697
        return calculated_size;
698
    }
699
700
    /*!
701
     * @brief Specific template which calculates the encoded size of an instance of a bitset of 8bits.
702
     * @param[in] data Reference to the instance.
703
     * @param[inout] current_alignment Current alignment in the encoding.
704
     * @return Encoded size of the instance.
705
     */
706
    template<size_t N, typename std::enable_if < (N < 9) > ::type* = nullptr>
707
    size_t calculate_serialized_size(
708
            const std::bitset<N>& data,
709
            size_t& current_alignment)
710
    {
711
        static_cast<void>(data);
712
        ++current_alignment;
713
        return 1;
714
    }
715
716
    /*!
717
     * @brief Specific template which calculates the encoded size of an instance of a bitset of 16bits.
718
     * @param[in] data Reference to the instance.
719
     * @param[inout] current_alignment Current alignment in the encoding.
720
     * @return Encoded size of the instance.
721
     */
722
    template<size_t N, typename std::enable_if < (8 < N && N < 17) > ::type* = nullptr>
723
    size_t calculate_serialized_size(
724
            const std::bitset<N>& data,
725
            size_t& current_alignment)
726
    {
727
        static_cast<void>(data);
728
        size_t calculated_size {2 + alignment(current_alignment, 2)};
729
        current_alignment += calculated_size;
730
        return calculated_size;
731
    }
732
733
    /*!
734
     * @brief Specific template which calculates the encoded size of an instance of a bitset of 32bits.
735
     * @param[in] data Reference to the instance.
736
     * @param[inout] current_alignment Current alignment in the encoding.
737
     * @return Encoded size of the instance.
738
     */
739
    template<size_t N, typename std::enable_if < (16 < N && N < 33) > ::type* = nullptr>
740
    size_t calculate_serialized_size(
741
            const std::bitset<N>& data,
742
            size_t& current_alignment)
743
    {
744
        static_cast<void>(data);
745
        size_t calculated_size {4 + alignment(current_alignment, 4)};
746
        current_alignment += calculated_size;
747
        return calculated_size;
748
    }
749
750
    /*!
751
     * @brief Specific template which calculates the encoded size of an instance of a bitset of 64bits.
752
     * @param[in] data Reference to the instance.
753
     * @param[inout] current_alignment Current alignment in the encoding.
754
     * @return Encoded size of the instance.
755
     */
756
    template<size_t N, typename std::enable_if < (32 < N && N < 65) > ::type* = nullptr>
757
    size_t calculate_serialized_size(
758
            const std::bitset<N>& data,
759
            size_t& current_alignment)
760
    {
761
        static_cast<void>(data);
762
        size_t calculated_size {8 + alignment(current_alignment, align64_)};
763
        current_alignment += calculated_size;
764
        return calculated_size;
765
    }
766
767
    /*!
768
     * @brief Specific template which calculates the encoded size of an instance of an optional type.
769
     * @param[in] data Reference to the instance.
770
     * @param[inout] current_alignment Current alignment in the encoding.
771
     * @return Encoded size of the instance.
772
     */
773
    template<class _T>
774
    size_t calculate_serialized_size(
775
            const optional<_T>& data,
776
            size_t& current_alignment)
777
    {
778
        size_t initial_alignment = current_alignment;
779
780
        if (CdrVersion::XCDRv2 == cdr_version_ &&
781
                EncodingAlgorithmFlag::PL_CDR2 != current_encoding_)
782
        {
783
            // Take into account the boolean is_present;
784
            ++current_alignment;
785
        }
786
787
        size_t calculated_size {current_alignment - initial_alignment};
788
789
        if (data.has_value())
790
        {
791
            calculated_size += calculate_serialized_size(data.value(), current_alignment);
792
        }
793
794
        return calculated_size;
795
    }
796
797
    /*!
798
     * @brief Specific template which calculates the encoded size of an instance of an external type.
799
     * @param[in] data Reference to the instance.
800
     * @param[inout] current_alignment Current alignment in the encoding.
801
     * @exception exception::BadParamException This exception is thrown when the external is null.
802
     * @return Encoded size of the instance.
803
     */
804
    template<class _T>
805
    size_t calculate_serialized_size(
806
            const external<_T>& data,
807
            size_t& current_alignment)
808
    {
809
        if (!data)
810
        {
811
            throw exception::BadParamException("External member is null");
812
        }
813
814
        return calculate_serialized_size(*data, current_alignment);
815
    }
816
817
    /*!
818
     * @brief Specific template which calculates the encoded size of an instance of an array of unknown type.
819
     * @tparam _T Array's type.
820
     * @param[in] data Reference to the array's instance.
821
     * @param[in] num_elements Number of elements in the array.
822
     * @param[inout] current_alignment Current alignment in the encoding.
823
     * @return Encoded size of the instance.
824
     */
825
    template<class _T>
826
    size_t calculate_array_serialized_size(
827
            const _T* data,
828
            size_t num_elements,
829
            size_t& current_alignment)
830
    {
831
        size_t calculated_size {0};
832
833
        for (size_t count = 0; count < num_elements; ++count)
834
        {
835
            calculated_size += calculate_serialized_size(data[count], current_alignment);
836
        }
837
838
        return calculated_size;
839
    }
840
841
    /*!
842
     * @brief Specific template which calculates the encoded size of an instance of an array of int8_t.
843
     * @param[in] data Reference to the array's instance.
844
     * @param[in] num_elements Number of elements in the array.
845
     * @param[inout] current_alignment Current alignment in the encoding.
846
     * @return Encoded size of the instance.
847
     */
848
    TEMPLATE_SPEC
849
    size_t calculate_array_serialized_size(
850
            const int8_t* data,
851
            size_t num_elements,
852
            size_t& current_alignment)
853
0
    {
854
0
        static_cast<void>(data);
855
0
        current_alignment += num_elements;
856
0
        return num_elements;
857
0
    }
858
859
    /*!
860
     * @brief Specific template which calculates the encoded size of an instance of an array of uint8_t.
861
     * @param[in] data Reference to the array's instance.
862
     * @param[in] num_elements Number of elements in the array.
863
     * @param[inout] current_alignment Current alignment in the encoding.
864
     * @return Encoded size of the instance.
865
     */
866
    TEMPLATE_SPEC
867
    size_t calculate_array_serialized_size(
868
            const uint8_t* data,
869
            size_t num_elements,
870
            size_t& current_alignment)
871
0
    {
872
0
        static_cast<void>(data);
873
0
        current_alignment += num_elements;
874
0
        return num_elements;
875
0
    }
876
877
    /*!
878
     * @brief Specific template which calculates the encoded size of an instance of an array of char.
879
     * @param[in] data Reference to the array's instance.
880
     * @param[in] num_elements Number of elements in the array.
881
     * @param[inout] current_alignment Current alignment in the encoding.
882
     * @return Encoded size of the instance.
883
     */
884
    TEMPLATE_SPEC
885
    size_t calculate_array_serialized_size(
886
            const char* data,
887
            size_t num_elements,
888
            size_t& current_alignment)
889
0
    {
890
0
        static_cast<void>(data);
891
0
        current_alignment += num_elements;
892
0
        return num_elements;
893
0
    }
894
895
    /*!
896
     * @brief Specific template which calculates the encoded size of an instance of an array of wchar.
897
     * @param[in] data Reference to the array's instance.
898
     * @param[in] num_elements Number of elements in the array.
899
     * @param[inout] current_alignment Current alignment in the encoding.
900
     * @return Encoded size of the instance.
901
     */
902
    TEMPLATE_SPEC
903
    size_t calculate_array_serialized_size(
904
            const wchar_t* data,
905
            size_t num_elements,
906
            size_t& current_alignment)
907
0
    {
908
0
        static_cast<void>(data);
909
0
        size_t calculated_size {num_elements* 2 + alignment(current_alignment, 2)};
910
0
        current_alignment += calculated_size;
911
0
        return calculated_size;
912
0
    }
913
914
    /*!
915
     * @brief Specific template which calculates the encoded size of an instance of an array of int16_t.
916
     * @param[in] data Reference to the array's instance.
917
     * @param[in] num_elements Number of elements in the array.
918
     * @param[inout] current_alignment Current alignment in the encoding.
919
     * @return Encoded size of the instance.
920
     */
921
    TEMPLATE_SPEC
922
    size_t calculate_array_serialized_size(
923
            const int16_t* data,
924
            size_t num_elements,
925
            size_t& current_alignment)
926
0
    {
927
0
        static_cast<void>(data);
928
0
        size_t calculated_size {num_elements* 2 + alignment(current_alignment, 2)};
929
0
        current_alignment += calculated_size;
930
0
        return calculated_size;
931
0
    }
932
933
    /*!
934
     * @brief Specific template which calculates the encoded size of an instance of an array of uint16_t.
935
     * @param[in] data Reference to the array's instance.
936
     * @param[in] num_elements Number of elements in the array.
937
     * @param[inout] current_alignment Current alignment in the encoding.
938
     * @return Encoded size of the instance.
939
     */
940
    TEMPLATE_SPEC
941
    size_t calculate_array_serialized_size(
942
            const uint16_t* data,
943
            size_t num_elements,
944
            size_t& current_alignment)
945
0
    {
946
0
        static_cast<void>(data);
947
0
        size_t calculated_size {num_elements* 2 + alignment(current_alignment, 2)};
948
0
        current_alignment += calculated_size;
949
0
        return calculated_size;
950
0
    }
951
952
    /*!
953
     * @brief Specific template which calculates the encoded size of an instance of an array of int32_t.
954
     * @param[in] data Reference to the array's instance.
955
     * @param[in] num_elements Number of elements in the array.
956
     * @param[inout] current_alignment Current alignment in the encoding.
957
     * @return Encoded size of the instance.
958
     */
959
    TEMPLATE_SPEC
960
    size_t calculate_array_serialized_size(
961
            const int32_t* data,
962
            size_t num_elements,
963
            size_t& current_alignment)
964
0
    {
965
0
        static_cast<void>(data);
966
0
        size_t calculated_size {num_elements* 4 + alignment(current_alignment, 4)};
967
0
        current_alignment += calculated_size;
968
0
        return calculated_size;
969
0
    }
970
971
    /*!
972
     * @brief Specific template which calculates the encoded size of an instance of an array of uint32_t.
973
     * @param[in] data Reference to the array's instance.
974
     * @param[in] num_elements Number of elements in the array.
975
     * @param[inout] current_alignment Current alignment in the encoding.
976
     * @return Encoded size of the instance.
977
     */
978
    TEMPLATE_SPEC
979
    size_t calculate_array_serialized_size(
980
            const uint32_t* data,
981
            size_t num_elements,
982
            size_t& current_alignment)
983
0
    {
984
0
        static_cast<void>(data);
985
0
        size_t calculated_size {num_elements* 4 + alignment(current_alignment, 4)};
986
0
        current_alignment += calculated_size;
987
0
        return calculated_size;
988
0
    }
989
990
    /*!
991
     * @brief Specific template which calculates the encoded size of an instance of an array of int64_t.
992
     * @param[in] data Reference to the array's instance.
993
     * @param[in] num_elements Number of elements in the array.
994
     * @param[inout] current_alignment Current alignment in the encoding.
995
     * @return Encoded size of the instance.
996
     */
997
    TEMPLATE_SPEC
998
    size_t calculate_array_serialized_size(
999
            const int64_t* data,
1000
            size_t num_elements,
1001
            size_t& current_alignment)
1002
0
    {
1003
0
        static_cast<void>(data);
1004
0
        size_t calculated_size {num_elements* 8 + alignment(current_alignment, align64_)};
1005
0
        current_alignment += calculated_size;
1006
0
        return calculated_size;
1007
0
    }
1008
1009
    /*!
1010
     * @brief Specific template which calculates the encoded size of an instance of an array of uint64_t.
1011
     * @param[in] data Reference to the array's instance.
1012
     * @param[in] num_elements Number of elements in the array.
1013
     * @param[inout] current_alignment Current alignment in the encoding.
1014
     * @return Encoded size of the instance.
1015
     */
1016
    TEMPLATE_SPEC
1017
    size_t calculate_array_serialized_size(
1018
            const uint64_t* data,
1019
            size_t num_elements,
1020
            size_t& current_alignment)
1021
0
    {
1022
0
        static_cast<void>(data);
1023
0
        size_t calculated_size {num_elements* 8 + alignment(current_alignment, align64_)};
1024
0
        current_alignment += calculated_size;
1025
0
        return calculated_size;
1026
0
    }
1027
1028
    /*!
1029
     * @brief Specific template which calculates the encoded size of an instance of an array of float.
1030
     * @param[in] data Reference to the array's instance.
1031
     * @param[in] num_elements Number of elements in the array.
1032
     * @param[inout] current_alignment Current alignment in the encoding.
1033
     * @return Encoded size of the instance.
1034
     */
1035
    TEMPLATE_SPEC
1036
    size_t calculate_array_serialized_size(
1037
            const float* data,
1038
            size_t num_elements,
1039
            size_t& current_alignment)
1040
0
    {
1041
0
        static_cast<void>(data);
1042
0
        size_t calculated_size {num_elements* 4 + alignment(current_alignment, 4)};
1043
0
        current_alignment += calculated_size;
1044
0
        return calculated_size;
1045
0
    }
1046
1047
    /*!
1048
     * @brief Specific template which calculates the encoded size of an instance of an array of double.
1049
     * @param[in] data Reference to the array's instance.
1050
     * @param[in] num_elements Number of elements in the array.
1051
     * @param[inout] current_alignment Current alignment in the encoding.
1052
     * @return Encoded size of the instance.
1053
     */
1054
    TEMPLATE_SPEC
1055
    size_t calculate_array_serialized_size(
1056
            const double* data,
1057
            size_t num_elements,
1058
            size_t& current_alignment)
1059
0
    {
1060
0
        static_cast<void>(data);
1061
0
        size_t calculated_size {num_elements* 8 + alignment(current_alignment, align64_)};
1062
0
        current_alignment += calculated_size;
1063
0
        return calculated_size;
1064
0
    }
1065
1066
    /*!
1067
     * @brief Specific template which calculates the encoded size of an instance of an array of long double.
1068
     * @param[in] data Reference to the array's instance.
1069
     * @param[in] num_elements Number of elements in the array.
1070
     * @param[inout] current_alignment Current alignment in the encoding.
1071
     * @return Encoded size of the instance.
1072
     */
1073
    TEMPLATE_SPEC
1074
    size_t calculate_array_serialized_size(
1075
            const long double* data,
1076
            size_t num_elements,
1077
            size_t& current_alignment)
1078
0
    {
1079
0
        static_cast<void>(data);
1080
0
        size_t calculated_size {num_elements* 16 + alignment(current_alignment, align64_)};
1081
0
        current_alignment += calculated_size;
1082
0
        return calculated_size;
1083
0
    }
1084
1085
    /*!
1086
     * @brief Specific template which calculates the encoded size of an instance of a multi-dimensional array.
1087
     * @param[in] data Reference to the array's instance.
1088
     * @param[in] num_elements Number of elements in the array.
1089
     * @param[inout] current_alignment Current alignment in the encoding.
1090
     * @return Encoded size of the instance.
1091
     */
1092
    template<class _T, size_t _N>
1093
    size_t calculate_array_serialized_size(
1094
            const std::array<_T, _N>* data,
1095
            size_t num_elements,
1096
            size_t& current_alignment)
1097
    {
1098
        if (num_elements == 0 || data == nullptr)
1099
        {
1100
            return 0;
1101
        }
1102
        return calculate_array_serialized_size(data->data(), num_elements * _N, current_alignment);
1103
    }
1104
1105
    /*!
1106
     * @brief Specific template which calculates the encoded size of an std::vector of primitives as an array.
1107
     * @param[in] data Reference to the instance.
1108
     * @param[inout] current_alignment Current alignment in the encoding.
1109
     * @return Encoded size of the instance.
1110
     */
1111
    template<class _T, typename std::enable_if<std::is_enum<_T>::value ||
1112
            std::is_arithmetic<_T>::value>::type* = nullptr>
1113
    size_t calculate_array_serialized_size(
1114
            const std::vector<_T>& data,
1115
            size_t& current_alignment)
1116
    {
1117
        return calculate_array_serialized_size(data.data(), data.size(), current_alignment);
1118
    }
1119
1120
    /*!
1121
     * @brief Specific template which calculates the encoded size of an std::vector of non-primitives as an array.
1122
     * @param[in] data Reference to the instance.
1123
     * @param[inout] current_alignment Current alignment in the encoding.
1124
     * @return Encoded size of the instance.
1125
     */
1126
    template<class _T, typename std::enable_if<!std::is_enum<_T>::value &&
1127
            !std::is_arithmetic<_T>::value>::type* = nullptr>
1128
    size_t calculate_array_serialized_size(
1129
            const std::vector<_T>& data,
1130
            size_t& current_alignment)
1131
    {
1132
        size_t initial_alignment {current_alignment};
1133
1134
        if (CdrVersion::XCDRv2 == cdr_version_)
1135
        {
1136
            // DHEADER
1137
            current_alignment += 4 + alignment(current_alignment, 4);
1138
        }
1139
1140
        size_t calculated_size {current_alignment - initial_alignment};
1141
        calculated_size += calculate_array_serialized_size(data.data(), data.size(), current_alignment);
1142
1143
        if (CdrVersion::XCDRv2 == cdr_version_)
1144
        {
1145
            // Inform DHEADER can be joined with NEXTINT
1146
            serialized_member_size_ = SERIALIZED_MEMBER_SIZE;
1147
        }
1148
1149
        return calculated_size;
1150
    }
1151
1152
    /*!
1153
     * @brief Specific template which calculates the encoded size of an std::vector of bool as an array.
1154
     * @param[in] data Reference to the instance.
1155
     * @param[inout] current_alignment Current alignment in the encoding.
1156
     * @return Encoded size of the instance.
1157
     */
1158
    TEMPLATE_SPEC
1159
    size_t calculate_array_serialized_size(
1160
            const std::vector<bool>& data,
1161
            size_t& current_alignment)
1162
0
    {
1163
0
        current_alignment += data.size();
1164
0
        return data.size();
1165
0
    }
1166
1167
    /*!
1168
     * @brief Generic template which calculates the encoded size of the constructed type's member of a unknown type.
1169
     * @tparam _T Member's type.
1170
     * @param[in] id Member's identifier.
1171
     * @param[in] data Reference to the member's instance.
1172
     * @param[inout] current_alignment Current alignment in the encoding.
1173
     * @return Encoded size of the member's instance.
1174
     */
1175
    template<class _T>
1176
    size_t calculate_member_serialized_size(
1177
            const MemberId& id,
1178
            const _T& data,
1179
            size_t& current_alignment)
1180
    {
1181
        size_t initial_alignment {current_alignment};
1182
1183
        if (EncodingAlgorithmFlag::PL_CDR == current_encoding_ ||
1184
                EncodingAlgorithmFlag::PL_CDR2 == current_encoding_)
1185
        {
1186
            // Align to 4 for the XCDR header before calculating the data serialized size.
1187
            current_alignment += alignment(current_alignment, 4);
1188
        }
1189
1190
        size_t prev_size {current_alignment - initial_alignment};
1191
        size_t extra_size {0};
1192
1193
        if (EncodingAlgorithmFlag::PL_CDR == current_encoding_)
1194
        {
1195
            current_alignment = 0;
1196
        }
1197
1198
        size_t calculated_size {calculate_serialized_size(data, current_alignment)};
1199
1200
        if (CdrVersion::XCDRv2 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR2 == current_encoding_ &&
1201
                0 < calculated_size)
1202
        {
1203
1204
            if (8 < calculated_size ||
1205
                    (1 != calculated_size && 2 != calculated_size && 4 != calculated_size &&
1206
                    8 != calculated_size))
1207
            {
1208
                extra_size = 8; // Long EMHEADER.
1209
                if (NO_SERIALIZED_MEMBER_SIZE != serialized_member_size_)
1210
                {
1211
                    calculated_size -= 4; // Join NEXTINT and DHEADER.
1212
                }
1213
            }
1214
            else
1215
            {
1216
                extra_size = 4; // EMHEADER;
1217
            }
1218
        }
1219
        else if (CdrVersion::XCDRv1 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR == current_encoding_ &&
1220
                0 < calculated_size)
1221
        {
1222
            extra_size = 4; // ShortMemberHeader
1223
1224
            if (0x3F00 < id.id || calculated_size > std::numeric_limits<uint16_t>::max())
1225
            {
1226
                extra_size += 8; // LongMemberHeader
1227
            }
1228
1229
        }
1230
1231
        calculated_size += prev_size + extra_size;
1232
        if (EncodingAlgorithmFlag::PL_CDR != current_encoding_)
1233
        {
1234
            current_alignment += extra_size;
1235
        }
1236
1237
        serialized_member_size_ = NO_SERIALIZED_MEMBER_SIZE;
1238
1239
        return calculated_size;
1240
    }
1241
1242
    /*!
1243
     * @brief Generic template which calculates the encoded size of the constructed type's member of type optional.
1244
     * @tparam _T Member's optional type.
1245
     * @param[in] id Member's identifier.
1246
     * @param[in] data Reference to the member's instance.
1247
     * @param[inout] current_alignment Current alignment in the encoding.
1248
     * @return Encoded size of the member's instance.
1249
     */
1250
    template<class _T>
1251
    size_t calculate_member_serialized_size(
1252
            const MemberId& id,
1253
            const optional<_T>& data,
1254
            size_t& current_alignment)
1255
    {
1256
        size_t initial_alignment = current_alignment;
1257
1258
        if (CdrVersion::XCDRv2 != cdr_version_ ||
1259
                EncodingAlgorithmFlag::PL_CDR2 == current_encoding_)
1260
        {
1261
            if (data.has_value() || EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_)
1262
            {
1263
                // Align to 4 for the XCDR header before calculating the data serialized size.
1264
                current_alignment += alignment(current_alignment, 4);
1265
            }
1266
        }
1267
1268
        size_t prev_size = {current_alignment - initial_alignment};
1269
        size_t extra_size {0};
1270
1271
        if (CdrVersion::XCDRv1 == cdr_version_ &&
1272
                (data.has_value() || EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_))
1273
        {
1274
            current_alignment = 0;
1275
        }
1276
1277
        size_t calculated_size {calculate_serialized_size(data, current_alignment)};
1278
1279
        if (CdrVersion::XCDRv2 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR2 == current_encoding_ &&
1280
                0 < calculated_size)
1281
        {
1282
            if (8 < calculated_size ||
1283
                    (1 != calculated_size && 2 != calculated_size && 4 != calculated_size &&
1284
                    8 != calculated_size))
1285
            {
1286
                extra_size = 8; // Long EMHEADER.
1287
                if (NO_SERIALIZED_MEMBER_SIZE != serialized_member_size_)
1288
                {
1289
                    calculated_size -= 4; // Join NEXTINT and DHEADER.
1290
                }
1291
            }
1292
            else
1293
            {
1294
                extra_size = 4; // EMHEADER;
1295
            }
1296
        }
1297
        else if (CdrVersion::XCDRv1 == cdr_version_ &&
1298
                (0 < calculated_size || EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_))
1299
        {
1300
            extra_size = 4; // ShortMemberHeader
1301
1302
            if (0x3F00 < id.id || calculated_size > std::numeric_limits<uint16_t>::max())
1303
            {
1304
                extra_size += 8; // LongMemberHeader
1305
            }
1306
1307
        }
1308
1309
        calculated_size += prev_size + extra_size;
1310
        if (CdrVersion::XCDRv1 != cdr_version_)
1311
        {
1312
            current_alignment += extra_size;
1313
        }
1314
1315
1316
        return calculated_size;
1317
    }
1318
1319
    /*!
1320
     * @brief Indicates a new constructed type will be calculated.
1321
     * @param[in] new_encoding New encoding algorithm used for the constructed type.
1322
     * @param[inout] current_alignment Current alignment in the encoding.
1323
     * @return If new encoding algorithm encodes a header, return the encoded size of it.
1324
     */
1325
    Cdr_DllAPI size_t begin_calculate_type_serialized_size(
1326
            EncodingAlgorithmFlag new_encoding,
1327
            size_t& current_alignment);
1328
1329
    /*!
1330
     * @brief Indicates the ending of a constructed type.
1331
     * @param[in] new_encoding New encoding algorithm used after the constructed type.
1332
     * @param[inout] current_alignment Current alignment in the encoding.
1333
     * @return If current encoding algorithm encodes a final mark, return the encoded size of it.
1334
     */
1335
    Cdr_DllAPI size_t end_calculate_type_serialized_size(
1336
            EncodingAlgorithmFlag new_encoding,
1337
            size_t& current_alignment);
1338
1339
private:
1340
1341
    CdrSizeCalculator() = delete;
1342
1343
    CdrVersion cdr_version_ {CdrVersion::XCDRv2};
1344
1345
    EncodingAlgorithmFlag current_encoding_ {EncodingAlgorithmFlag::PLAIN_CDR2};
1346
1347
    enum SerializedMemberSizeForNextInt
1348
    {
1349
        NO_SERIALIZED_MEMBER_SIZE,
1350
        SERIALIZED_MEMBER_SIZE,
1351
        SERIALIZED_MEMBER_SIZE_4,
1352
        SERIALIZED_MEMBER_SIZE_8
1353
    }
1354
    //! Specifies if a DHEADER was serialized. Used to calculate XCDRv2 member headers.
1355
    serialized_member_size_ {NO_SERIALIZED_MEMBER_SIZE};
1356
1357
    //! Align for types equal or greater than 64bits.
1358
    size_t align64_ {4};
1359
1360
    //! Custom serialization context.
1361
    std::shared_ptr<CdrContext> context_;
1362
1363
    inline size_t alignment(
1364
            size_t current_alignment,
1365
            size_t data_size) const
1366
0
    {
1367
0
        return (data_size - (current_alignment % data_size)) & (data_size - 1);
1368
0
    }
1369
1370
    template<class _T, typename std::enable_if<std::is_enum<_T>::value ||
1371
            std::is_arithmetic<_T>::value>::type* = nullptr>
1372
    constexpr SerializedMemberSizeForNextInt get_serialized_member_size() const
1373
    {
1374
        return (1 == sizeof(_T) ? SERIALIZED_MEMBER_SIZE :
1375
               (4 == sizeof(_T) ? SERIALIZED_MEMBER_SIZE_4 :
1376
               (8 == sizeof(_T) ? SERIALIZED_MEMBER_SIZE_8 :  NO_SERIALIZED_MEMBER_SIZE)));
1377
    }
1378
1379
};
1380
1381
}        // namespace fastcdr
1382
}        // namespace eprosima
1383
1384
#endif // _FASTCDR_CDRSIZECALCULATOR_HPP_