Coverage Report

Created: 2026-04-01 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Fast-DDS/include/fastdds/rtps/common/CDRMessage_t.hpp
Line
Count
Source
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
/**
16
 * @file CDRMessage_t.hpp
17
 */
18
19
#ifndef FASTDDS_RTPS_COMMON__CDRMESSAGE_T_HPP
20
#define FASTDDS_RTPS_COMMON__CDRMESSAGE_T_HPP
21
#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
22
23
#include <fastdds/rtps/common/SerializedPayload.hpp>
24
#include <fastdds/rtps/common/Types.hpp>
25
#include <cassert>
26
#include <cstdlib>
27
#include <cstring>
28
29
namespace eprosima {
30
namespace fastdds {
31
namespace rtps {
32
33
//!Max size of RTPS message in bytes.
34
0
#define RTPSMESSAGE_DEFAULT_SIZE 10500  //max size of rtps message in bytes
35
0
#define RTPSMESSAGE_COMMON_RTPS_PAYLOAD_SIZE 536 //common payload a rtps message has TODO(Ricardo) It is necessary?
36
#define RTPSMESSAGE_COMMON_DATA_PAYLOAD_SIZE 10000 //common data size
37
5.04k
#define RTPSMESSAGE_HEADER_SIZE 20  //header size in bytes
38
0
#define RTPSMESSAGE_SUBMESSAGEHEADER_SIZE 4
39
0
#define RTPSMESSAGE_DATA_EXTRA_INLINEQOS_SIZE 4
40
#define RTPSMESSAGE_INFOTS_SIZE 12
41
42
0
#define RTPSMESSAGE_OCTETSTOINLINEQOS_DATASUBMSG 16 //may change in future versions
43
0
#define RTPSMESSAGE_OCTETSTOINLINEQOS_DATAFRAGSUBMSG 28 //may change in future versions
44
52
#define RTPSMESSAGE_DATA_MIN_LENGTH 24
45
46
/**
47
 * @brief Structure CDRMessage_t, contains a serialized message.
48
 * @ingroup COMMON_MODULE
49
 */
50
struct FASTDDS_EXPORTED_API CDRMessage_t final
51
{
52
    // TODO(Miguel C): Deprecate when not used in mocks
53
    CDRMessage_t()
54
0
        : CDRMessage_t(
55
0
                RTPSMESSAGE_DEFAULT_SIZE)
56
0
    {
57
0
    }
58
59
    ~CDRMessage_t()
60
1.66k
    {
61
1.66k
        if (buffer != nullptr && !wraps)
62
0
        {
63
0
            free(buffer);
64
0
        }
65
1.66k
    }
66
67
    /**
68
     * Constructor with maximum size
69
     * @param size Maximum size
70
     */
71
    explicit CDRMessage_t(
72
            uint32_t size)
73
1.66k
    {
74
1.66k
        wraps = false;
75
1.66k
        pos = 0;
76
1.66k
        length = 0;
77
78
1.66k
        if (size != 0)
79
0
        {
80
0
            buffer = (octet*)malloc(size);
81
0
        }
82
1.66k
        else
83
1.66k
        {
84
1.66k
            buffer = nullptr;
85
1.66k
        }
86
87
1.66k
        max_size = size;
88
1.66k
        reserved_size = size;
89
1.66k
        msg_endian = DEFAULT_ENDIAN;
90
1.66k
    }
91
92
    /**
93
     * Constructor to wrap a serialized payload
94
     * @param payload Payload to wrap
95
     */
96
    explicit CDRMessage_t(
97
            const SerializedPayload_t& payload)
98
0
        : wraps(true)
99
0
    {
100
0
        msg_endian = LITTLEEND;
101
0
        if (payload.encapsulation == PL_CDR_BE || payload.encapsulation == CDR_BE)
102
0
        {
103
0
            msg_endian = BIGEND;
104
0
        }
105
0
        pos = payload.pos;
106
0
        length = payload.length;
107
0
        buffer = payload.data;
108
0
        max_size = payload.max_size;
109
0
        reserved_size = payload.max_size;
110
0
    }
111
112
    /**
113
     * @brief Wraps a portion of a CDRMessage_t into a new CDRMessage_t.
114
     *
115
     * @param other                         The CDRMessage_t to wrap from.
116
     * @param length_from_current_position  The length of the portion to wrap,
117
                                            starting from the current position of `other`.
118
     *
119
     * @return A new CDRMessage_t wrapping the specified portion.
120
     *
121
     * Note: If the specified length exceeds the available data in `other`,
122
     * the returned CDRMessage_t will have length zero and buffer set to nullptr.
123
     */
124
    static CDRMessage_t wrap_from_other_message(
125
            const CDRMessage_t& other,
126
            uint32_t length_from_current_position)
127
0
    {
128
0
        CDRMessage_t msg(0);
129
        // Fail if length exceeds available data
130
0
        if (other.length - other.pos < length_from_current_position)
131
0
        {
132
            // Error is indicated by length being zero and buffer being nullptr
133
0
        }
134
0
        else
135
0
        {
136
0
            msg.wraps = true;
137
0
            msg.pos = 0;
138
0
            msg.length = length_from_current_position;
139
0
            msg.max_size = length_from_current_position;
140
0
            msg.reserved_size = other.reserved_size;
141
0
            msg.msg_endian = other.msg_endian;
142
0
            msg.buffer = &other.buffer[other.pos];
143
0
        }
144
0
        return msg;
145
0
    }
146
147
    CDRMessage_t(
148
            const CDRMessage_t& message)
149
0
    {
150
0
        wraps = false;
151
0
        pos = 0;
152
0
        length = message.length;
153
0
        max_size = message.max_size;
154
0
        msg_endian = message.msg_endian;
155
0
156
0
        reserved_size = max_size;
157
0
        if (max_size != 0)
158
0
        {
159
0
            buffer =  (octet*)malloc(max_size);
160
0
            memcpy(buffer, message.buffer, length);
161
0
        }
162
0
        else
163
0
        {
164
0
            buffer = nullptr;
165
0
        }
166
0
    }
167
168
    CDRMessage_t(
169
            CDRMessage_t&& message)
170
0
    {
171
0
        wraps = message.wraps;
172
0
        message.wraps = false;
173
0
        pos = message.pos;
174
0
        message.pos = 0;
175
0
        length = message.length;
176
0
        message.length = 0;
177
0
        max_size = message.max_size;
178
0
        message.max_size = 0;
179
0
        reserved_size = message.reserved_size;
180
0
        message.reserved_size = 0;
181
0
        msg_endian = message.msg_endian;
182
0
        message.msg_endian = DEFAULT_ENDIAN;
183
0
        buffer = message.buffer;
184
0
        message.buffer = nullptr;
185
0
    }
186
187
    CDRMessage_t& operator =(
188
            CDRMessage_t&& message)
189
0
    {
190
0
        wraps = message.wraps;
191
0
        message.wraps = false;
192
0
        pos = message.pos;
193
0
        message.pos = 0;
194
0
        length = message.length;
195
0
        message.length = 0;
196
0
        max_size = message.max_size;
197
0
        message.max_size = 0;
198
0
        reserved_size = message.reserved_size;
199
0
        message.reserved_size = 0;
200
0
        msg_endian = message.msg_endian;
201
0
        message.msg_endian = DEFAULT_ENDIAN;
202
0
        buffer = message.buffer;
203
0
        message.buffer = nullptr;
204
0
205
0
        return *(this);
206
0
    }
207
208
    void init(
209
            octet* buffer_ptr,
210
            uint32_t size)
211
0
    {
212
0
        assert(buffer == nullptr);
213
0
        wraps = true;
214
0
        pos = 0;
215
0
        length = 0;
216
0
        buffer = buffer_ptr;
217
0
        max_size = size;
218
0
        reserved_size = size;
219
0
        msg_endian = DEFAULT_ENDIAN;
220
0
    }
221
222
    void reserve(
223
            uint32_t size)
224
0
    {
225
0
        assert(wraps == false);
226
0
        if (size > reserved_size)
227
0
        {
228
0
            octet* new_buffer = (octet*) realloc(buffer, size);
229
0
            if (new_buffer == nullptr)
230
0
            {
231
                // TODO: Exception? Assertion?
232
0
            }
233
0
            else
234
0
            {
235
0
                buffer = new_buffer;
236
0
                reserved_size = size;
237
0
            }
238
0
        }
239
240
0
        max_size = size;
241
0
    }
242
243
    //!Pointer to the buffer where the data is stored.
244
    octet* buffer;
245
    //!Read or write position.
246
    uint32_t pos;
247
    //!Max size of the message.
248
    uint32_t max_size;
249
    //!Size allocated on buffer. May be higher than max_size.
250
    uint32_t reserved_size;
251
    //!Current length of the message.
252
    uint32_t length;
253
    //!Endianness of the message.
254
    Endianness_t msg_endian;
255
    //Whether this message is wrapping a buffer managed elsewhere.
256
    bool wraps;
257
};
258
259
}  // namespace rtps
260
}  // namespace fastdds
261
}  // namespace eprosima
262
263
#endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
264
#endif // FASTDDS_RTPS_COMMON__CDRMESSAGE_T_HPP