Coverage Report

Created: 2022-08-24 06:19

/src/Fast-DDS/include/fastdds/rtps/messages/CDRMessage.hpp
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
#ifndef DOXYGEN_SHOULD_SKIP_THIS
16
17
/**
18
 * @file CDRMessage.hpp
19
 *
20
 */
21
22
#include <cassert>
23
#include <cstring>
24
#include <algorithm>
25
#include <limits>
26
#include <vector>
27
28
#include <fastdds/dds/core/policy/ParameterTypes.hpp>
29
30
namespace eprosima {
31
namespace fastrtps {
32
namespace rtps {
33
34
inline bool CDRMessage::initCDRMsg(
35
        CDRMessage_t* msg,
36
        uint32_t payload_size)
37
0
{
38
0
    if (msg->buffer == nullptr)
39
0
    {
40
0
        msg->buffer = (octet*)malloc(payload_size + RTPSMESSAGE_COMMON_RTPS_PAYLOAD_SIZE);
41
0
        msg->max_size = payload_size + RTPSMESSAGE_COMMON_RTPS_PAYLOAD_SIZE;
42
0
    }
43
0
    msg->pos = 0;
44
0
    msg->length = 0;
45
0
    msg->msg_endian = DEFAULT_ENDIAN;
46
0
    return true;
47
0
}
48
49
inline bool CDRMessage::wrapVector(
50
        CDRMessage_t* msg,
51
        std::vector<octet>& vectorToWrap)
52
0
{
53
0
    if (msg->buffer && !msg->wraps)
54
0
    {
55
0
        free(msg->buffer);
56
0
    }
57
0
58
0
    msg->wraps = true;
59
0
    msg->buffer = vectorToWrap.data();
60
0
    msg->length = (uint32_t)vectorToWrap.size();
61
0
    msg->max_size = (uint32_t)vectorToWrap.capacity();
62
0
    msg->msg_endian = DEFAULT_ENDIAN;
63
0
    return true;
64
0
}
65
66
inline bool CDRMessage::appendMsg(
67
        CDRMessage_t* first,
68
        CDRMessage_t* second)
69
0
{
70
0
    return(CDRMessage::addData(first, second->buffer, second->length));
71
0
}
72
73
inline bool CDRMessage::readEntityId(
74
        CDRMessage_t* msg,
75
        EntityId_t* id)
76
54.1k
{
77
54.1k
    if (msg->pos + 4 > msg->length)
78
282
    {
79
282
        return false;
80
282
    }
81
53.8k
    memcpy(id->value, &msg->buffer[msg->pos], id->size);
82
53.8k
    msg->pos += 4;
83
53.8k
    return true;
84
54.1k
}
85
86
inline bool CDRMessage::readData(
87
        CDRMessage_t* msg,
88
        octet* o,
89
        uint32_t length)
90
5.63k
{
91
5.63k
    if (msg->pos + length > msg->length)
92
50
    {
93
50
        return false;
94
50
    }
95
5.58k
    memcpy(o, &msg->buffer[msg->pos], length);
96
5.58k
    msg->pos += length;
97
5.58k
    return true;
98
5.63k
}
99
100
inline bool CDRMessage::read_array_with_max_size(
101
        CDRMessage_t* msg,
102
        octet* arr,
103
        size_t max_size)
104
0
{
105
0
    if (msg->pos + 4 > msg->length)
106
0
    {
107
0
        return false;
108
0
    }
109
0
    uint32_t datasize;
110
0
    bool valid = CDRMessage::readUInt32(msg, &datasize);
111
0
    if (max_size < datasize)
112
0
    {
113
0
        return false;
114
0
    }
115
0
    valid &= CDRMessage::readData(msg, arr, datasize);
116
0
    msg->pos = (msg->pos + 3u) & ~3u;
117
0
    return valid;
118
0
}
119
120
inline bool CDRMessage::readDataReversed(
121
        CDRMessage_t* msg,
122
        octet* o,
123
        uint32_t length)
124
126k
{
125
631k
    for (uint32_t i = 0; i < length; i++)
126
505k
    {
127
505k
        *(o + i) = *(msg->buffer + msg->pos + length - 1 - i);
128
505k
    }
129
126k
    msg->pos += length;
130
126k
    return true;
131
126k
}
132
133
inline bool CDRMessage::readInt32(
134
        CDRMessage_t* msg,
135
        int32_t* lo)
136
47.9k
{
137
47.9k
    if (msg->pos + 4 > msg->length)
138
37
    {
139
37
        return false;
140
37
    }
141
47.8k
    octet* dest = (octet*)lo;
142
47.8k
    if (msg->msg_endian == DEFAULT_ENDIAN)
143
11.6k
    {
144
58.0k
        for (uint8_t i = 0; i < 4; i++)
145
46.4k
        {
146
46.4k
            dest[i] = msg->buffer[msg->pos + i];
147
46.4k
        }
148
11.6k
        msg->pos += 4;
149
11.6k
    }
150
36.2k
    else
151
36.2k
    {
152
36.2k
        readDataReversed(msg, dest, 4);
153
36.2k
    }
154
47.8k
    return true;
155
47.9k
}
156
157
inline bool CDRMessage::readUInt32(
158
        CDRMessage_t* msg,
159
        uint32_t* ulo)
160
113k
{
161
113k
    if (msg->pos + 4 > msg->length)
162
1.76k
    {
163
1.76k
        return false;
164
1.76k
    }
165
112k
    octet* dest = (octet*)ulo;
166
112k
    if (msg->msg_endian == DEFAULT_ENDIAN)
167
22.1k
    {
168
110k
        for (uint8_t i = 0; i < 4; i++)
169
88.4k
        {
170
88.4k
            dest[i] = msg->buffer[msg->pos + i];
171
88.4k
        }
172
22.1k
        msg->pos += 4;
173
22.1k
    }
174
90.0k
    else
175
90.0k
    {
176
90.0k
        readDataReversed(msg, dest, 4);
177
90.0k
    }
178
112k
    return true;
179
113k
}
180
181
inline bool CDRMessage::readInt64(
182
        CDRMessage_t* msg,
183
        int64_t* lolo)
184
0
{
185
0
    if (msg->pos + 8 > msg->length)
186
0
    {
187
0
        return false;
188
0
    }
189
0
190
0
    octet* dest = (octet*)lolo;
191
0
    if (msg->msg_endian == DEFAULT_ENDIAN)
192
0
    {
193
0
        for (uint8_t i = 0; i < 8; ++i)
194
0
        {
195
0
            dest[i] = msg->buffer[msg->pos + i];
196
0
        }
197
0
198
0
        msg->pos += 8;
199
0
    }
200
0
    else
201
0
    {
202
0
        readDataReversed(msg, dest, 8);
203
0
    }
204
0
205
0
    return true;
206
0
}
207
208
inline bool CDRMessage::readUInt64(
209
        CDRMessage_t* msg,
210
        uint64_t* ulolo)
211
0
{
212
0
    if (msg->pos + 8 > msg->length)
213
0
    {
214
0
        return false;
215
0
    }
216
0
217
0
    octet* dest = (octet*)ulolo;
218
0
    if (msg->msg_endian == DEFAULT_ENDIAN)
219
0
    {
220
0
        for (uint8_t i = 0; i < 8; ++i)
221
0
        {
222
0
            dest[i] = msg->buffer[msg->pos + i];
223
0
        }
224
0
225
0
        msg->pos += 8;
226
0
    }
227
0
    else
228
0
    {
229
0
        readDataReversed(msg, dest, 8);
230
0
    }
231
0
232
0
    return true;
233
0
}
234
235
inline bool CDRMessage::readSequenceNumber(
236
        CDRMessage_t* msg,
237
        SequenceNumber_t* sn)
238
46.7k
{
239
46.7k
    if (msg->pos + 8 > msg->length)
240
1.23k
    {
241
1.23k
        return false;
242
1.23k
    }
243
45.4k
    bool valid = readInt32(msg, &sn->high);
244
45.4k
    valid &= readUInt32(msg, &sn->low);
245
45.4k
    return true;
246
46.7k
}
247
248
inline SequenceNumberSet_t CDRMessage::readSequenceNumberSet(
249
        CDRMessage_t* msg)
250
14.7k
{
251
14.7k
    bool valid = true;
252
253
14.7k
    SequenceNumber_t seqNum;
254
14.7k
    valid &= CDRMessage::readSequenceNumber(msg, &seqNum);
255
14.7k
    uint32_t numBits = 0;
256
14.7k
    valid &= CDRMessage::readUInt32(msg, &numBits);
257
14.7k
    valid &= (numBits <= 256u);
258
14.7k
    valid &= (seqNum.high >= 0);
259
14.7k
    if (valid && std::numeric_limits<int32_t>::max() == seqNum.high)
260
539
    {
261
539
        numBits = (std::min)(numBits, std::numeric_limits<uint32_t>::max() - seqNum.low);
262
539
    }
263
264
14.7k
    uint32_t n_longs = (numBits + 31u) / 32u;
265
14.7k
    uint32_t bitmap[8];
266
45.4k
    for (uint32_t i = 0; valid && (i < n_longs); ++i)
267
30.6k
    {
268
30.6k
        valid &= CDRMessage::readUInt32(msg, &bitmap[i]);
269
30.6k
    }
270
271
14.7k
    if (valid)
272
8.34k
    {
273
8.34k
        SequenceNumberSet_t sns(seqNum, numBits);
274
8.34k
        sns.bitmap_set(numBits, bitmap);
275
8.34k
        return sns;
276
8.34k
    }
277
278
6.45k
    return SequenceNumberSet_t (c_SequenceNumber_Unknown);
279
14.7k
}
280
281
inline bool CDRMessage::readFragmentNumberSet(
282
        CDRMessage_t* msg,
283
        FragmentNumberSet_t* fns)
284
252
{
285
252
    bool valid = true;
286
287
252
    FragmentNumber_t base = 0ul;
288
252
    valid &= CDRMessage::readUInt32(msg, &base);
289
252
    uint32_t numBits = 0;
290
252
    valid &= CDRMessage::readUInt32(msg, &numBits);
291
252
    valid &= (numBits <= 256u);
292
293
252
    uint32_t n_longs = (numBits + 31u) / 32u;
294
252
    uint32_t bitmap[8];
295
1.04k
    for (uint32_t i = 0; valid && (i < n_longs); ++i)
296
797
    {
297
797
        valid &= CDRMessage::readUInt32(msg, &bitmap[i]);
298
797
    }
299
300
252
    if (valid)
301
40
    {
302
40
        fns->base(base);
303
40
        fns->bitmap_set(numBits, bitmap);
304
40
    }
305
306
252
    return valid;
307
252
}
308
309
inline bool CDRMessage::readTimestamp(
310
        CDRMessage_t* msg,
311
        rtps::Time_t* ts)
312
2.41k
{
313
2.41k
    bool valid = true;
314
2.41k
    valid &= CDRMessage::readInt32(msg, &ts->seconds());
315
2.41k
    uint32_t frac(0);
316
2.41k
    valid &= CDRMessage::readUInt32(msg, &frac);
317
2.41k
    ts->fraction(frac);
318
2.41k
    return valid;
319
2.41k
}
320
321
inline bool CDRMessage::readLocator(
322
        CDRMessage_t* msg,
323
        Locator_t* loc)
324
0
{
325
0
    if (msg->pos + 24 > msg->length)
326
0
    {
327
0
        return false;
328
0
    }
329
0
330
0
    bool valid = readInt32(msg, &loc->kind);
331
0
    valid &= readUInt32(msg, &loc->port);
332
0
    valid &= readData(msg, loc->address, 16);
333
0
334
0
    return valid;
335
0
}
336
337
inline bool CDRMessage::readInt16(
338
        CDRMessage_t* msg,
339
        int16_t* i16)
340
84
{
341
84
    if (msg->pos + 2 > msg->length)
342
0
    {
343
0
        return false;
344
0
    }
345
84
    octet* o = (octet*)i16;
346
84
    if (msg->msg_endian == DEFAULT_ENDIAN)
347
30
    {
348
30
        *o = msg->buffer[msg->pos];
349
30
        *(o + 1) = msg->buffer[msg->pos + 1];
350
30
    }
351
54
    else
352
54
    {
353
54
        *o = msg->buffer[msg->pos + 1];
354
54
        *(o + 1) = msg->buffer[msg->pos];
355
54
    }
356
84
    msg->pos += 2;
357
84
    return true;
358
84
}
359
360
inline bool CDRMessage::readUInt16(
361
        CDRMessage_t* msg,
362
        uint16_t* i16)
363
42.1k
{
364
42.1k
    if (msg->pos + 2 > msg->length)
365
0
    {
366
0
        return false;
367
0
    }
368
42.1k
    octet* o = (octet*)i16;
369
42.1k
    if (msg->msg_endian == DEFAULT_ENDIAN)
370
10.1k
    {
371
10.1k
        *o = msg->buffer[msg->pos];
372
10.1k
        *(o + 1) = msg->buffer[msg->pos + 1];
373
10.1k
    }
374
31.9k
    else
375
31.9k
    {
376
31.9k
        *o = msg->buffer[msg->pos + 1];
377
31.9k
        *(o + 1) = msg->buffer[msg->pos];
378
31.9k
    }
379
42.1k
    msg->pos += 2;
380
42.1k
    return true;
381
42.1k
}
382
383
inline bool CDRMessage::readOctet(
384
        CDRMessage_t* msg,
385
        octet* o)
386
2.76k
{
387
2.76k
    if (msg->pos + 1 > msg->length)
388
0
    {
389
0
        return false;
390
0
    }
391
2.76k
    *o = msg->buffer[msg->pos];
392
2.76k
    msg->pos++;
393
2.76k
    return true;
394
2.76k
}
395
396
inline bool CDRMessage::readOctetVector(
397
        CDRMessage_t* msg,
398
        std::vector<octet>* ocvec)
399
0
{
400
0
    if (msg->pos + 4 > msg->length)
401
0
    {
402
0
        return false;
403
0
    }
404
0
    uint32_t vecsize;
405
0
    bool valid = CDRMessage::readUInt32(msg, &vecsize);
406
0
    ocvec->resize(vecsize);
407
0
    valid &= CDRMessage::readData(msg, ocvec->data(), vecsize);
408
0
    msg->pos = (msg->pos + 3u) & ~3u;
409
0
    return valid;
410
0
}
411
412
inline bool CDRMessage::readString(
413
        CDRMessage_t* msg,
414
        std::string* stri)
415
0
{
416
0
    uint32_t str_size = 1;
417
0
    bool valid = true;
418
0
    valid &= CDRMessage::readUInt32(msg, &str_size);
419
0
    if (msg->pos + str_size > msg->length)
420
0
    {
421
0
        return false;
422
0
    }
423
0
424
0
    stri->clear();
425
0
    if (str_size > 1)
426
0
    {
427
0
        stri->resize(str_size - 1);
428
0
        for (uint32_t i = 0; i < str_size - 1; i++)
429
0
        {
430
0
            stri->at(i) = static_cast<char>(msg->buffer[msg->pos + i]);
431
0
        }
432
0
    }
433
0
    msg->pos += str_size;
434
0
    msg->pos = (msg->pos + 3u) & ~3u;
435
0
436
0
    return valid;
437
0
}
438
439
inline bool CDRMessage::readString(
440
        CDRMessage_t* msg,
441
        string_255* stri)
442
0
{
443
0
    uint32_t str_size = 1;
444
0
    bool valid = true;
445
0
    valid &= CDRMessage::readUInt32(msg, &str_size);
446
0
    if (msg->pos + str_size > msg->length)
447
0
    {
448
0
        return false;
449
0
    }
450
0
451
0
    *stri = "";
452
0
    if (str_size > 1)
453
0
    {
454
0
        *stri = (const char*) &(msg->buffer[msg->pos]);
455
0
    }
456
0
    msg->pos += str_size;
457
0
    msg->pos = (msg->pos + 3u) & ~3u;
458
0
459
0
    return valid;
460
0
}
461
462
inline bool CDRMessage::addData(
463
        CDRMessage_t* msg,
464
        const octet* data,
465
        const uint32_t length)
466
0
{
467
0
    if (msg->pos + length > msg->max_size)
468
0
    {
469
0
        return false;
470
0
    }
471
472
0
    memcpy(&msg->buffer[msg->pos], data, length);
473
0
    msg->pos += length;
474
0
    msg->length += length;
475
0
    return true;
476
0
}
477
478
inline bool CDRMessage::addDataReversed(
479
        CDRMessage_t* msg,
480
        const octet* data,
481
        const uint32_t length)
482
0
{
483
0
    if (msg->pos + length > msg->max_size)
484
0
    {
485
0
        return false;
486
0
    }
487
0
    for (uint32_t i = 0; i < length; i++)
488
0
    {
489
0
        msg->buffer[msg->pos + i] = *(data + length - 1 - i);
490
0
    }
491
0
    msg->pos += length;
492
0
    msg->length += length;
493
0
    return true;
494
0
}
495
496
inline bool CDRMessage::addOctet(
497
        CDRMessage_t* msg,
498
        octet O)
499
0
{
500
0
    if (msg->pos + 1 > msg->max_size)
501
0
    {
502
0
        return false;
503
0
    }
504
    //const void* d = (void*)&O;
505
0
    msg->buffer[msg->pos] = O;
506
0
    msg->pos++;
507
0
    msg->length++;
508
0
    return true;
509
0
}
510
511
inline bool CDRMessage::addUInt16(
512
        CDRMessage_t* msg,
513
        uint16_t us)
514
0
{
515
0
    if (msg->pos + 2 > msg->max_size)
516
0
    {
517
0
        return false;
518
0
    }
519
0
    octet* o = (octet*)&us;
520
0
    if (msg->msg_endian == DEFAULT_ENDIAN)
521
0
    {
522
0
        msg->buffer[msg->pos] = *(o);
523
0
        msg->buffer[msg->pos + 1] = *(o + 1);
524
0
    }
525
0
    else
526
0
    {
527
0
        msg->buffer[msg->pos] = *(o + 1);
528
0
        msg->buffer[msg->pos + 1] = *(o);
529
0
    }
530
0
    msg->pos += 2;
531
0
    msg->length += 2;
532
0
    return true;
533
0
}
534
535
inline bool CDRMessage::addInt32(
536
        CDRMessage_t* msg,
537
        int32_t lo)
538
0
{
539
0
    octet* o = (octet*)&lo;
540
0
    if (msg->pos + 4 > msg->max_size)
541
0
    {
542
0
        return false;
543
0
    }
544
0
    if (msg->msg_endian == DEFAULT_ENDIAN)
545
0
    {
546
0
        for (uint8_t i = 0; i < 4; i++)
547
0
        {
548
0
            msg->buffer[msg->pos + i] = *(o + i);
549
0
        }
550
0
    }
551
0
    else
552
0
    {
553
0
        for (uint8_t i = 0; i < 4; i++)
554
0
        {
555
0
            msg->buffer[msg->pos + i] = *(o + 3 - i);
556
0
        }
557
0
    }
558
0
    msg->pos += 4;
559
0
    msg->length += 4;
560
0
    return true;
561
0
}
562
563
inline bool CDRMessage::addUInt32(
564
        CDRMessage_t* msg,
565
        uint32_t ulo)
566
0
{
567
0
    octet* o = (octet*)&ulo;
568
0
    if (msg->pos + 4 > msg->max_size)
569
0
    {
570
0
        return false;
571
0
    }
572
0
    if (msg->msg_endian == DEFAULT_ENDIAN)
573
0
    {
574
0
        for (uint8_t i = 0; i < 4; i++)
575
0
        {
576
0
            msg->buffer[msg->pos + i] = *(o + i);
577
0
        }
578
0
    }
579
0
    else
580
0
    {
581
0
        for (uint8_t i = 0; i < 4; i++)
582
0
        {
583
0
            msg->buffer[msg->pos + i] = *(o + 3 - i);
584
0
        }
585
0
    }
586
0
    msg->pos += 4;
587
0
    msg->length += 4;
588
0
    return true;
589
0
}
590
591
inline bool CDRMessage::addInt64(
592
        CDRMessage_t* msg,
593
        int64_t lolo)
594
0
{
595
0
    octet* o = (octet*)&lolo;
596
0
    if (msg->pos + 8 > msg->max_size)
597
0
    {
598
0
        return false;
599
0
    }
600
0
    if (msg->msg_endian == DEFAULT_ENDIAN)
601
0
    {
602
0
        for (uint8_t i = 0; i < 8; i++)
603
0
        {
604
0
            msg->buffer[msg->pos + i] = *(o + i);
605
0
        }
606
0
    }
607
0
    else
608
0
    {
609
0
        for (uint8_t i = 0; i < 8; i++)
610
0
        {
611
0
            msg->buffer[msg->pos + i] = *(o + 7 - i);
612
0
        }
613
0
    }
614
0
    msg->pos += 8;
615
0
    msg->length += 8;
616
0
    return true;
617
0
}
618
619
inline bool CDRMessage::addUInt64(
620
        CDRMessage_t* msg,
621
        uint64_t ulolo)
622
0
{
623
0
    octet* o = (octet*)&ulolo;
624
0
    if (msg->pos + 8 > msg->max_size)
625
0
    {
626
0
        return false;
627
0
    }
628
0
    if (msg->msg_endian == DEFAULT_ENDIAN)
629
0
    {
630
0
        for (uint8_t i = 0; i < 8; i++)
631
0
        {
632
0
            msg->buffer[msg->pos + i] = *(o + i);
633
0
        }
634
0
    }
635
0
    else
636
0
    {
637
0
        for (uint8_t i = 0; i < 8; i++)
638
0
        {
639
0
            msg->buffer[msg->pos + i] = *(o + 7 - i);
640
0
        }
641
0
    }
642
0
    msg->pos += 8;
643
0
    msg->length += 8;
644
0
    return true;
645
0
}
646
647
inline bool CDRMessage::addOctetVector(
648
        CDRMessage_t* msg,
649
        const std::vector<octet>* ocvec,
650
        bool add_final_padding)
651
0
{
652
0
    // TODO Calculate without padding
653
0
    auto final_size = msg->pos + ocvec->size();
654
0
    if (add_final_padding)
655
0
    {
656
0
        final_size += 4;
657
0
    }
658
0
    if (final_size >= msg->max_size)
659
0
    {
660
0
        return false;
661
0
    }
662
0
    bool valid = CDRMessage::addUInt32(msg, (uint32_t)ocvec->size());
663
0
    valid &= CDRMessage::addData(msg, (octet*)ocvec->data(), (uint32_t)ocvec->size());
664
0
665
0
    if (add_final_padding)
666
0
    {
667
0
        int rest = ocvec->size() % 4;
668
0
        if (rest != 0)
669
0
        {
670
0
            rest = 4 - rest; //how many you have to add
671
0
672
0
            octet oc = '\0';
673
0
            for (int i = 0; i < rest; i++)
674
0
            {
675
0
                valid &= CDRMessage::addOctet(msg, oc);
676
0
            }
677
0
        }
678
0
    }
679
0
680
0
    return valid;
681
0
}
682
683
inline bool CDRMessage::addEntityId(
684
        CDRMessage_t* msg,
685
        const EntityId_t* ID)
686
0
{
687
0
    if (msg->pos + 4 >= msg->max_size)
688
0
    {
689
0
        return false;
690
0
    }
691
0
    memcpy(&msg->buffer[msg->pos], ID->value, ID->size);
692
0
    msg->pos += 4;
693
0
    msg->length += 4;
694
0
    return true;
695
0
}
696
697
inline bool CDRMessage::addSequenceNumber(
698
        CDRMessage_t* msg,
699
        const SequenceNumber_t* sn)
700
0
{
701
0
    addInt32(msg, sn->high);
702
0
    addUInt32(msg, sn->low);
703
704
0
    return true;
705
0
}
706
707
inline bool CDRMessage::addSequenceNumberSet(
708
        CDRMessage_t* msg,
709
        const SequenceNumberSet_t* sns)
710
0
{
711
0
    SequenceNumber_t base = sns->base();
712
0
    CDRMessage::addSequenceNumber(msg, &base);
713
714
    //Add set
715
0
    if (sns->empty())
716
0
    {
717
0
        addUInt32(msg, 0); //numbits 0
718
0
        return true;
719
0
    }
720
721
0
    uint32_t numBits;
722
0
    uint32_t n_longs;
723
0
    std::array<uint32_t, 8> bitmap;
724
0
    sns->bitmap_get(numBits, bitmap, n_longs);
725
726
0
    addUInt32(msg, numBits);
727
728
0
    for (uint32_t i = 0; i < n_longs; i++)
729
0
    {
730
0
        addUInt32(msg, bitmap[i]);
731
0
    }
732
733
0
    return true;
734
0
}
735
736
inline bool CDRMessage::addFragmentNumberSet(
737
        CDRMessage_t* msg,
738
        FragmentNumberSet_t* fns)
739
0
{
740
0
    FragmentNumber_t base = fns->base();
741
0
    if (base == 0)
742
0
    {
743
0
        return false;
744
0
    }
745
746
0
    CDRMessage::addUInt32(msg, base);
747
748
    //Add set
749
0
    if (fns->empty())
750
0
    {
751
0
        addUInt32(msg, 0); //numbits 0
752
0
        return true;
753
0
    }
754
755
0
    uint32_t numBits;
756
0
    uint32_t n_longs;
757
0
    std::array<uint32_t, 8> bitmap;
758
0
    fns->bitmap_get(numBits, bitmap, n_longs);
759
760
0
    addUInt32(msg, numBits);
761
762
0
    for (uint32_t i = 0; i < n_longs; i++)
763
0
    {
764
0
        addUInt32(msg, bitmap[i]);
765
0
    }
766
767
0
    return true;
768
0
}
769
770
inline bool CDRMessage::addLocator(
771
        CDRMessage_t* msg,
772
        const Locator_t& loc)
773
0
{
774
0
    addInt32(msg, loc.kind);
775
0
    addUInt32(msg, loc.port);
776
0
    addData(msg, loc.address, 16);
777
0
    return true;
778
0
}
779
780
inline bool CDRMessage::add_string(
781
        CDRMessage_t* msg,
782
        const char* in_str)
783
0
{
784
0
    uint32_t str_siz = static_cast<uint32_t>(strlen(in_str) + 1);
785
0
    bool valid = CDRMessage::addUInt32(msg, str_siz);
786
0
    valid &= CDRMessage::addData(msg, (unsigned char*) in_str, str_siz);
787
0
    octet oc = '\0';
788
0
    for (; str_siz& 3; ++str_siz)
789
0
    {
790
0
        valid &= CDRMessage::addOctet(msg, oc);
791
0
    }
792
0
    return valid;
793
0
}
794
795
inline bool CDRMessage::add_string(
796
        CDRMessage_t* msg,
797
        const std::string& in_str)
798
0
{
799
0
    return add_string(msg, in_str.c_str());
800
0
}
801
802
inline bool CDRMessage::add_string(
803
        CDRMessage_t* msg,
804
        const string_255& in_str)
805
0
{
806
0
    return add_string(msg, in_str.c_str());
807
0
}
808
809
inline bool CDRMessage::addProperty(
810
        CDRMessage_t* msg,
811
        const Property& property)
812
0
{
813
0
    assert(msg);
814
0
815
0
    if (property.propagate())
816
0
    {
817
0
        if (!CDRMessage::add_string(msg, property.name()))
818
0
        {
819
0
            return false;
820
0
        }
821
0
        if (!CDRMessage::add_string(msg, property.value()))
822
0
        {
823
0
            return false;
824
0
        }
825
0
    }
826
0
827
0
    return true;
828
0
}
829
830
inline bool CDRMessage::readProperty(
831
        CDRMessage_t* msg,
832
        Property& property)
833
0
{
834
0
    assert(msg);
835
0
836
0
    if (!CDRMessage::readString(msg, &property.name()))
837
0
    {
838
0
        return false;
839
0
    }
840
0
    if (!CDRMessage::readString(msg, &property.value()))
841
0
    {
842
0
        return false;
843
0
    }
844
0
845
0
    return true;
846
0
}
847
848
inline bool CDRMessage::addBinaryProperty(
849
        CDRMessage_t* msg,
850
        const BinaryProperty& binary_property,
851
        bool add_final_padding)
852
0
{
853
0
    assert(msg);
854
0
855
0
    if (binary_property.propagate())
856
0
    {
857
0
        if (!CDRMessage::add_string(msg, binary_property.name()))
858
0
        {
859
0
            return false;
860
0
        }
861
0
        if (!CDRMessage::addOctetVector(msg, &binary_property.value(), add_final_padding))
862
0
        {
863
0
            return false;
864
0
        }
865
0
    }
866
0
867
0
    return true;
868
0
}
869
870
inline bool CDRMessage::readBinaryProperty(
871
        CDRMessage_t* msg,
872
        BinaryProperty& binary_property)
873
0
{
874
0
    assert(msg);
875
0
876
0
    if (!CDRMessage::readString(msg, &binary_property.name()))
877
0
    {
878
0
        return false;
879
0
    }
880
0
    if (!CDRMessage::readOctetVector(msg, &binary_property.value()))
881
0
    {
882
0
        return false;
883
0
    }
884
0
    binary_property.propagate(true);
885
0
886
0
    return true;
887
0
}
888
889
inline bool CDRMessage::addPropertySeq(
890
        CDRMessage_t* msg,
891
        const PropertySeq& properties)
892
0
{
893
0
    assert(msg);
894
0
895
0
    bool returnedValue = false;
896
0
897
0
    if (msg->pos + 4 <=  msg->max_size)
898
0
    {
899
0
        uint32_t number_to_serialize = 0;
900
0
        for (auto it = properties.begin(); it != properties.end(); ++it)
901
0
        {
902
0
            if (it->propagate())
903
0
            {
904
0
                ++number_to_serialize;
905
0
            }
906
0
        }
907
0
908
0
        if (CDRMessage::addUInt32(msg, number_to_serialize))
909
0
        {
910
0
            returnedValue = true;
911
0
            for (auto it = properties.begin(); returnedValue && it != properties.end(); ++it)
912
0
            {
913
0
                if (it->propagate())
914
0
                {
915
0
                    returnedValue = CDRMessage::addProperty(msg, *it);
916
0
                }
917
0
            }
918
0
        }
919
0
    }
920
0
921
0
    return returnedValue;
922
0
}
923
924
inline bool CDRMessage::readPropertySeq(
925
        CDRMessage_t* msg,
926
        PropertySeq& properties)
927
0
{
928
0
    assert(msg);
929
0
930
0
    uint32_t length = 0;
931
0
    if (!CDRMessage::readUInt32(msg, &length))
932
0
    {
933
0
        return false;
934
0
    }
935
0
936
0
    properties.resize(length);
937
0
    bool returnedValue = true;
938
0
    for (uint32_t i = 0; returnedValue && i < length; ++i)
939
0
    {
940
0
        returnedValue = CDRMessage::readProperty(msg, properties.at(i));
941
0
    }
942
0
943
0
    return returnedValue;
944
0
945
0
}
946
947
inline bool CDRMessage::addBinaryPropertySeq(
948
        CDRMessage_t* msg,
949
        const BinaryPropertySeq& binary_properties,
950
        bool add_final_padding)
951
0
{
952
0
    assert(msg);
953
0
954
0
    bool returnedValue = false;
955
0
956
0
    if (msg->pos + 4 <=  msg->max_size)
957
0
    {
958
0
        uint32_t number_to_serialize = 0;
959
0
        for (auto it = binary_properties.begin(); it != binary_properties.end(); ++it)
960
0
        {
961
0
            if (it->propagate())
962
0
            {
963
0
                ++number_to_serialize;
964
0
            }
965
0
        }
966
0
967
0
        if (CDRMessage::addUInt32(msg, number_to_serialize))
968
0
        {
969
0
            returnedValue = true;
970
0
            for (auto it = binary_properties.begin(); returnedValue && it != binary_properties.end(); ++it)
971
0
            {
972
0
                if (it->propagate())
973
0
                {
974
0
                    --number_to_serialize;
975
0
                    returnedValue =
976
0
                            CDRMessage::addBinaryProperty(msg, *it,
977
0
                                    add_final_padding || (number_to_serialize != 0));
978
0
                }
979
0
            }
980
0
        }
981
0
    }
982
0
983
0
    return returnedValue;
984
0
}
985
986
inline bool CDRMessage::addBinaryPropertySeq(
987
        CDRMessage_t* msg,
988
        const BinaryPropertySeq& binary_properties,
989
        const std::string& name_start,
990
        bool add_final_padding)
991
0
{
992
0
    assert(msg);
993
0
994
0
    bool returnedValue = false;
995
0
996
0
    if (msg->pos + 4 <=  msg->max_size)
997
0
    {
998
0
        uint32_t number_to_serialize = 0;
999
0
        for (auto it = binary_properties.begin(); it != binary_properties.end(); ++it)
1000
0
        {
1001
0
            if (it->name().find(name_start) == 0)
1002
0
            {
1003
0
                ++number_to_serialize;
1004
0
            }
1005
0
        }
1006
0
1007
0
        if (CDRMessage::addUInt32(msg, number_to_serialize))
1008
0
        {
1009
0
            returnedValue = true;
1010
0
            for (auto it = binary_properties.begin(); returnedValue && it != binary_properties.end(); ++it)
1011
0
            {
1012
0
                if (it->name().find(name_start) == 0)
1013
0
                {
1014
0
                    --number_to_serialize;
1015
0
                    returnedValue =
1016
0
                            CDRMessage::addBinaryProperty(msg, *it,
1017
0
                                    add_final_padding || (number_to_serialize != 0));
1018
0
                }
1019
0
            }
1020
0
        }
1021
0
    }
1022
0
1023
0
    return returnedValue;
1024
0
}
1025
1026
inline bool CDRMessage::readBinaryPropertySeq(
1027
        CDRMessage_t* msg,
1028
        BinaryPropertySeq& binary_properties)
1029
0
{
1030
0
    assert(msg);
1031
0
1032
0
    uint32_t length = 0;
1033
0
    if (!CDRMessage::readUInt32(msg, &length))
1034
0
    {
1035
0
        return false;
1036
0
    }
1037
0
1038
0
    binary_properties.resize(length);
1039
0
    bool returnedValue = true;
1040
0
    for (uint32_t i = 0; returnedValue && i < length; ++i)
1041
0
    {
1042
0
        returnedValue = CDRMessage::readBinaryProperty(msg, binary_properties.at(i));
1043
0
    }
1044
0
1045
0
    return returnedValue;
1046
0
}
1047
1048
inline bool CDRMessage::addDataHolder(
1049
        CDRMessage_t* msg,
1050
        const DataHolder& data_holder)
1051
0
{
1052
0
    assert(msg);
1053
0
1054
0
    if (!CDRMessage::add_string(msg, data_holder.class_id()))
1055
0
    {
1056
0
        return false;
1057
0
    }
1058
0
    if (!CDRMessage::addPropertySeq(msg, data_holder.properties()))
1059
0
    {
1060
0
        return false;
1061
0
    }
1062
0
    if (!CDRMessage::addBinaryPropertySeq(msg, data_holder.binary_properties(), true))
1063
0
    {
1064
0
        return false;
1065
0
    }
1066
0
1067
0
    return true;
1068
0
}
1069
1070
inline bool CDRMessage::readDataHolder(
1071
        CDRMessage_t* msg,
1072
        DataHolder& data_holder)
1073
0
{
1074
0
    assert(msg);
1075
0
1076
0
    if (!CDRMessage::readString(msg, &data_holder.class_id()))
1077
0
    {
1078
0
        return false;
1079
0
    }
1080
0
    if (!CDRMessage::readPropertySeq(msg, data_holder.properties()))
1081
0
    {
1082
0
        return false;
1083
0
    }
1084
0
    if (!CDRMessage::readBinaryPropertySeq(msg, data_holder.binary_properties()))
1085
0
    {
1086
0
        return false;
1087
0
    }
1088
0
1089
0
    return true;
1090
0
1091
0
}
1092
1093
inline bool CDRMessage::addDataHolderSeq(
1094
        CDRMessage_t* msg,
1095
        const DataHolderSeq& data_holders)
1096
0
{
1097
0
    assert(msg);
1098
0
1099
0
    bool returnedValue = false;
1100
0
1101
0
    if (msg->pos + 4 <=  msg->max_size)
1102
0
    {
1103
0
        if (CDRMessage::addUInt32(msg, static_cast<uint32_t>(data_holders.size())))
1104
0
        {
1105
0
            returnedValue = true;
1106
0
            for (auto data_holder = data_holders.begin(); returnedValue && data_holder != data_holders.end();
1107
0
                    ++data_holder)
1108
0
            {
1109
0
                returnedValue = CDRMessage::addDataHolder(msg, *data_holder);
1110
0
            }
1111
0
        }
1112
0
    }
1113
0
1114
0
    return returnedValue;
1115
0
}
1116
1117
inline bool CDRMessage::readDataHolderSeq(
1118
        CDRMessage_t* msg,
1119
        DataHolderSeq& data_holders)
1120
0
{
1121
0
    assert(msg);
1122
0
1123
0
    uint32_t length = 0;
1124
0
    if (!CDRMessage::readUInt32(msg, &length))
1125
0
    {
1126
0
        return false;
1127
0
    }
1128
0
1129
0
    data_holders.resize(length);
1130
0
    bool returnedValue = true;
1131
0
    for (uint32_t i = 0; returnedValue && i < length; ++i)
1132
0
    {
1133
0
        returnedValue = CDRMessage::readDataHolder(msg, data_holders.at(i));
1134
0
    }
1135
0
1136
0
    return returnedValue;
1137
0
}
1138
1139
inline bool CDRMessage::addMessageIdentity(
1140
        CDRMessage_t* msg,
1141
        const security::MessageIdentity& message_identity)
1142
0
{
1143
0
    assert(msg);
1144
0
1145
0
    if (!CDRMessage::addData(msg, message_identity.source_guid().guidPrefix.value, GuidPrefix_t::size))
1146
0
    {
1147
0
        return false;
1148
0
    }
1149
0
    if (!CDRMessage::addData(msg, message_identity.source_guid().entityId.value, EntityId_t::size))
1150
0
    {
1151
0
        return false;
1152
0
    }
1153
0
    if (!CDRMessage::addInt64(msg, message_identity.sequence_number()))
1154
0
    {
1155
0
        return false;
1156
0
    }
1157
0
1158
0
    return true;
1159
0
}
1160
1161
inline bool CDRMessage::readMessageIdentity(
1162
        CDRMessage_t* msg,
1163
        security::MessageIdentity& message_identity)
1164
0
{
1165
0
    assert(msg);
1166
0
1167
0
    if (!CDRMessage::readData(msg, message_identity.source_guid().guidPrefix.value, GuidPrefix_t::size))
1168
0
    {
1169
0
        return false;
1170
0
    }
1171
0
    if (!CDRMessage::readData(msg, message_identity.source_guid().entityId.value, EntityId_t::size))
1172
0
    {
1173
0
        return false;
1174
0
    }
1175
0
    if (!CDRMessage::readInt64(msg, &message_identity.sequence_number()))
1176
0
    {
1177
0
        return false;
1178
0
    }
1179
0
1180
0
    return true;
1181
0
}
1182
1183
inline bool CDRMessage::addParticipantGenericMessage(
1184
        CDRMessage_t* msg,
1185
        const security::ParticipantGenericMessage& message)
1186
0
{
1187
0
    assert(msg);
1188
0
1189
0
    if (!CDRMessage::addMessageIdentity(msg, message.message_identity()))
1190
0
    {
1191
0
        return false;
1192
0
    }
1193
0
    if (!CDRMessage::addMessageIdentity(msg, message.related_message_identity()))
1194
0
    {
1195
0
        return false;
1196
0
    }
1197
0
    if (!CDRMessage::addData(msg, message.destination_participant_key().guidPrefix.value, GuidPrefix_t::size))
1198
0
    {
1199
0
        return false;
1200
0
    }
1201
0
    if (!CDRMessage::addData(msg, message.destination_participant_key().entityId.value, EntityId_t::size))
1202
0
    {
1203
0
        return false;
1204
0
    }
1205
0
    if (!CDRMessage::addData(msg, message.destination_endpoint_key().guidPrefix.value, GuidPrefix_t::size))
1206
0
    {
1207
0
        return false;
1208
0
    }
1209
0
    if (!CDRMessage::addData(msg, message.destination_endpoint_key().entityId.value, EntityId_t::size))
1210
0
    {
1211
0
        return false;
1212
0
    }
1213
0
    if (!CDRMessage::addData(msg, message.source_endpoint_key().guidPrefix.value, GuidPrefix_t::size))
1214
0
    {
1215
0
        return false;
1216
0
    }
1217
0
    if (!CDRMessage::addData(msg, message.source_endpoint_key().entityId.value, EntityId_t::size))
1218
0
    {
1219
0
        return false;
1220
0
    }
1221
0
    if (!CDRMessage::add_string(msg, message.message_class_id()))
1222
0
    {
1223
0
        return false;
1224
0
    }
1225
0
    if (!CDRMessage::addDataHolderSeq(msg, message.message_data()))
1226
0
    {
1227
0
        return false;
1228
0
    }
1229
0
1230
0
    return true;
1231
0
}
1232
1233
inline bool CDRMessage::readParticipantGenericMessage(
1234
        CDRMessage_t* msg,
1235
        security::ParticipantGenericMessage& message)
1236
0
{
1237
0
    assert(msg);
1238
0
1239
0
    if (!CDRMessage::readMessageIdentity(msg, message.message_identity()))
1240
0
    {
1241
0
        return false;
1242
0
    }
1243
0
    if (!CDRMessage::readMessageIdentity(msg, message.related_message_identity()))
1244
0
    {
1245
0
        return false;
1246
0
    }
1247
0
    if (!CDRMessage::readData(msg, message.destination_participant_key().guidPrefix.value, GuidPrefix_t::size))
1248
0
    {
1249
0
        return false;
1250
0
    }
1251
0
    if (!CDRMessage::readData(msg, message.destination_participant_key().entityId.value, EntityId_t::size))
1252
0
    {
1253
0
        return false;
1254
0
    }
1255
0
    if (!CDRMessage::readData(msg, message.destination_endpoint_key().guidPrefix.value, GuidPrefix_t::size))
1256
0
    {
1257
0
        return false;
1258
0
    }
1259
0
    if (!CDRMessage::readData(msg, message.destination_endpoint_key().entityId.value, EntityId_t::size))
1260
0
    {
1261
0
        return false;
1262
0
    }
1263
0
    if (!CDRMessage::readData(msg, message.source_endpoint_key().guidPrefix.value, GuidPrefix_t::size))
1264
0
    {
1265
0
        return false;
1266
0
    }
1267
0
    if (!CDRMessage::readData(msg, message.source_endpoint_key().entityId.value, EntityId_t::size))
1268
0
    {
1269
0
        return false;
1270
0
    }
1271
0
    if (!CDRMessage::readString(msg, &message.message_class_id()))
1272
0
    {
1273
0
        return false;
1274
0
    }
1275
0
    if (!CDRMessage::readDataHolderSeq(msg, message.message_data()))
1276
0
    {
1277
0
        return false;
1278
0
    }
1279
0
1280
0
    return true;
1281
0
}
1282
1283
} // namespace rtps
1284
} // namespace fastrtps
1285
} // namespace eprosima
1286
1287
#endif /* DOXYGEN_SHOULD_SKIP_THIS */