Coverage Report

Created: 2025-07-03 06:58

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