Coverage Report

Created: 2026-02-14 07:11

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.25k
#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
60
#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(RTPSMESSAGE_DEFAULT_SIZE)
55
0
    {
56
0
    }
57
58
    ~CDRMessage_t()
59
1.73k
    {
60
1.73k
        if (buffer != nullptr && !wraps)
61
0
        {
62
0
            free(buffer);
63
0
        }
64
1.73k
    }
65
66
    /**
67
     * Constructor with maximum size
68
     * @param size Maximum size
69
     */
70
    explicit CDRMessage_t(
71
            uint32_t size)
72
1.73k
    {
73
1.73k
        wraps = false;
74
1.73k
        pos = 0;
75
1.73k
        length = 0;
76
77
1.73k
        if (size != 0)
78
0
        {
79
0
            buffer = (octet*)malloc(size);
80
0
        }
81
1.73k
        else
82
1.73k
        {
83
1.73k
            buffer = nullptr;
84
1.73k
        }
85
86
1.73k
        max_size = size;
87
1.73k
        reserved_size = size;
88
1.73k
        msg_endian = DEFAULT_ENDIAN;
89
1.73k
    }
90
91
    /**
92
     * Constructor to wrap a serialized payload
93
     * @param payload Payload to wrap
94
     */
95
    explicit CDRMessage_t(
96
            const SerializedPayload_t& payload)
97
0
        : wraps(true)
98
0
    {
99
0
        msg_endian = LITTLEEND;
100
0
        if (payload.encapsulation == PL_CDR_BE || payload.encapsulation == CDR_BE)
101
0
        {
102
0
            msg_endian = BIGEND;
103
0
        }
104
0
        pos = payload.pos;
105
0
        length = payload.length;
106
0
        buffer = payload.data;
107
0
        max_size = payload.max_size;
108
0
        reserved_size = payload.max_size;
109
0
    }
110
111
    /**
112
     * @brief Wraps a portion of a CDRMessage_t into a new CDRMessage_t.
113
     *
114
     * @param other                         The CDRMessage_t to wrap from.
115
     * @param length_from_current_position  The length of the portion to wrap,
116
                                            starting from the current position of `other`.
117
     *
118
     * @return A new CDRMessage_t wrapping the specified portion.
119
     *
120
     * Note: If the specified length exceeds the available data in `other`,
121
     * the returned CDRMessage_t will have length zero and buffer set to nullptr.
122
     */
123
    static CDRMessage_t wrap_from_other_message(
124
            const CDRMessage_t& other,
125
            uint32_t length_from_current_position)
126
0
    {
127
0
        CDRMessage_t msg(0);
128
        // Fail if length exceeds available data
129
0
        if (other.length - other.pos < length_from_current_position)
130
0
        {
131
            // Error is indicated by length being zero and buffer being nullptr
132
0
        }
133
0
        else
134
0
        {
135
0
            msg.wraps = true;
136
0
            msg.pos = 0;
137
0
            msg.length = length_from_current_position;
138
0
            msg.max_size = length_from_current_position;
139
0
            msg.reserved_size = other.reserved_size;
140
0
            msg.msg_endian = other.msg_endian;
141
0
            msg.buffer = &other.buffer[other.pos];
142
0
        }
143
0
        return msg;
144
0
    }
145
146
    CDRMessage_t(
147
            const CDRMessage_t& message)
148
0
    {
149
0
        wraps = false;
150
0
        pos = 0;
151
0
        length = message.length;
152
0
        max_size = message.max_size;
153
0
        msg_endian = message.msg_endian;
154
0
155
0
        reserved_size = max_size;
156
0
        if (max_size != 0)
157
0
        {
158
0
            buffer =  (octet*)malloc(max_size);
159
0
            memcpy(buffer, message.buffer, length);
160
0
        }
161
0
        else
162
0
        {
163
0
            buffer = nullptr;
164
0
        }
165
0
    }
166
167
    CDRMessage_t(
168
            CDRMessage_t&& message)
169
0
    {
170
0
        wraps = message.wraps;
171
0
        message.wraps = false;
172
0
        pos = message.pos;
173
0
        message.pos = 0;
174
0
        length = message.length;
175
0
        message.length = 0;
176
0
        max_size = message.max_size;
177
0
        message.max_size = 0;
178
0
        reserved_size = message.reserved_size;
179
0
        message.reserved_size = 0;
180
0
        msg_endian = message.msg_endian;
181
0
        message.msg_endian = DEFAULT_ENDIAN;
182
0
        buffer = message.buffer;
183
0
        message.buffer = nullptr;
184
0
    }
185
186
    CDRMessage_t& operator =(
187
            CDRMessage_t&& message)
188
0
    {
189
0
        wraps = message.wraps;
190
0
        message.wraps = false;
191
0
        pos = message.pos;
192
0
        message.pos = 0;
193
0
        length = message.length;
194
0
        message.length = 0;
195
0
        max_size = message.max_size;
196
0
        message.max_size = 0;
197
0
        reserved_size = message.reserved_size;
198
0
        message.reserved_size = 0;
199
0
        msg_endian = message.msg_endian;
200
0
        message.msg_endian = DEFAULT_ENDIAN;
201
0
        buffer = message.buffer;
202
0
        message.buffer = nullptr;
203
0
204
0
        return *(this);
205
0
    }
206
207
    void init(
208
            octet* buffer_ptr,
209
            uint32_t size)
210
0
    {
211
0
        assert(buffer == nullptr);
212
0
        wraps = true;
213
0
        pos = 0;
214
0
        length = 0;
215
0
        buffer = buffer_ptr;
216
0
        max_size = size;
217
0
        reserved_size = size;
218
0
        msg_endian = DEFAULT_ENDIAN;
219
0
    }
220
221
    void reserve(
222
            uint32_t size)
223
0
    {
224
0
        assert(wraps == false);
225
0
        if (size > reserved_size)
226
0
        {
227
0
            octet* new_buffer = (octet*) realloc(buffer, size);
228
0
            if (new_buffer == nullptr)
229
0
            {
230
                // TODO: Exception? Assertion?
231
0
            }
232
0
            else
233
0
            {
234
0
                buffer = new_buffer;
235
0
                reserved_size = size;
236
0
            }
237
0
        }
238
239
0
        max_size = size;
240
0
    }
241
242
    //!Pointer to the buffer where the data is stored.
243
    octet* buffer;
244
    //!Read or write position.
245
    uint32_t pos;
246
    //!Max size of the message.
247
    uint32_t max_size;
248
    //!Size allocated on buffer. May be higher than max_size.
249
    uint32_t reserved_size;
250
    //!Current length of the message.
251
    uint32_t length;
252
    //!Endianness of the message.
253
    Endianness_t msg_endian;
254
    //Whether this message is wrapping a buffer managed elsewhere.
255
    bool wraps;
256
};
257
258
}  // namespace rtps
259
}  // namespace fastdds
260
}  // namespace eprosima
261
262
#endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
263
#endif // FASTDDS_RTPS_COMMON__CDRMESSAGE_T_HPP