Coverage Report

Created: 2025-06-13 06:46

/src/Fast-DDS/include/fastdds/rtps/common/InstanceHandle.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
/**
16
 * @file InstanceHandle.hpp
17
 */
18
19
#ifndef FASTDDS_RTPS_COMMON__INSTANCEHANDLE_HPP
20
#define FASTDDS_RTPS_COMMON__INSTANCEHANDLE_HPP
21
22
#include <array>
23
24
#include <fastdds/fastdds_dll.hpp>
25
#include <fastdds/rtps/common/Types.hpp>
26
#include <fastdds/rtps/common/Guid.hpp>
27
28
namespace eprosima {
29
namespace fastdds {
30
namespace rtps {
31
32
constexpr const uint8_t RTPS_KEY_HASH_SIZE = 16;
33
34
using KeyHash_t = std::array<octet, RTPS_KEY_HASH_SIZE>;
35
36
struct FASTDDS_EXPORTED_API InstanceHandleValue_t
37
{
38
    /**
39
     * Write access indexing operator.
40
     *
41
     * Provides a reference to the byte value at position @c i.
42
     *
43
     * @param [in] i index of the byte to return.
44
     *
45
     * @post Method has_been_set() returns @c true.
46
     *
47
     * @remark Do not use this method to check if this value has been set.
48
     *         Use method has_been_set() instead.
49
     */
50
    template<typename T>
51
    octet& operator [] (
52
            T i) noexcept
53
0
    {
54
0
        has_been_set_ = true;
55
0
        return value_[i];
56
0
    }
Unexecuted instantiation: unsigned char& eprosima::fastdds::rtps::InstanceHandleValue_t::operator[]<unsigned int>(unsigned int)
Unexecuted instantiation: unsigned char& eprosima::fastdds::rtps::InstanceHandleValue_t::operator[]<unsigned char>(unsigned char)
Unexecuted instantiation: unsigned char& eprosima::fastdds::rtps::InstanceHandleValue_t::operator[]<int>(int)
57
58
    /**
59
     * Read access indexing operator.
60
     *
61
     * Provides the byte value at position @c i.
62
     *
63
     * @param [in] i index of the byte to return.
64
     *
65
     * @remark Do not use this method to check if this value has been set.
66
     *         Use method has_been_set() instead.
67
     */
68
    template<typename T>
69
    octet operator [] (
70
            T i) const noexcept
71
0
    {
72
0
        return value_[i];
73
0
    }
Unexecuted instantiation: unsigned char eprosima::fastdds::rtps::InstanceHandleValue_t::operator[]<unsigned char>(unsigned char) const
Unexecuted instantiation: unsigned char eprosima::fastdds::rtps::InstanceHandleValue_t::operator[]<unsigned int>(unsigned int) const
74
75
    /**
76
     * Write access pointer cast operator.
77
     *
78
     * Provides a pointer to the start of the raw data.
79
     *
80
     * @post Method has_been_set() returns @c true.
81
     *
82
     * @remark Do not use this method to check if this value has been set.
83
     *         Use method has_been_set() instead.
84
     */
85
    operator octet* () noexcept
86
0
    {
87
0
        has_been_set_ = true;
88
0
        return value_.data();
89
0
    }
90
91
    /**
92
     * Read access pointer cast operator.
93
     *
94
     * Provides a pointer to the start of the raw data.
95
     *
96
     * @remark Do not use this method to check if this value has been set.
97
     *         Use method has_been_set() instead.
98
     */
99
    operator const octet* () const noexcept
100
0
    {
101
0
        return value_.data();
102
0
    }
103
104
    /**
105
     * Return whether any of the write access operators of this value has been used.
106
     */
107
    bool has_been_set() const noexcept
108
0
    {
109
0
        return has_been_set_;
110
0
    }
111
112
    void clear() noexcept
113
0
    {
114
0
        value_.fill(0);
115
0
        has_been_set_ = false;
116
0
    }
117
118
    /**
119
     * Equality comparison operator.
120
     */
121
    bool operator == (
122
            const InstanceHandleValue_t& other) const noexcept
123
0
    {
124
0
        return (has_been_set_ == other.has_been_set_) && (value_ == other.value_);
125
0
    }
126
127
    /**
128
     * Less than comparisor operator.
129
     */
130
    bool operator < (
131
            const InstanceHandleValue_t& other) const noexcept
132
0
    {
133
0
        if (has_been_set_)
134
0
        {
135
0
            return other.has_been_set_ && value_ < other.value_;
136
0
        }
137
138
0
        return other.has_been_set_;
139
0
    }
140
141
private:
142
143
    //! Hash value
144
    KeyHash_t value_ {};
145
    //! Flag indicating if value_ has been modified since the creation of this object
146
    bool has_been_set_ = false;
147
};
148
149
/**
150
 * Struct InstanceHandle_t, used to contain the key for WITH_KEY topics.
151
 * @ingroup COMMON_MODULE
152
 */
153
struct FASTDDS_EXPORTED_API InstanceHandle_t
154
{
155
    //!Value
156
    InstanceHandleValue_t value;
157
158
0
    InstanceHandle_t() noexcept = default;
159
160
    InstanceHandle_t(
161
            const InstanceHandle_t& ihandle) noexcept = default;
162
163
    InstanceHandle_t(
164
            const GUID_t& guid) noexcept
165
0
    {
166
0
        *this = guid;
167
0
    }
168
169
    /**
170
     * Assignment operator
171
     * @param ihandle Instance handle to copy the data from
172
     */
173
    InstanceHandle_t& operator =(
174
            const InstanceHandle_t& ihandle) noexcept = default;
175
176
    /**
177
     * Assignment operator
178
     * @param guid GUID to copy the data from
179
     */
180
    InstanceHandle_t& operator =(
181
            const GUID_t& guid) noexcept
182
0
    {
183
0
        octet* dst = value;
184
0
        memcpy(dst, guid.guidPrefix.value, 12);
185
0
        memcpy(&dst[12], guid.entityId.value, 4);
186
0
        return *this;
187
0
    }
188
189
    /**
190
     * Know if the instance handle is defined
191
     * @return True if the values are not zero.
192
     */
193
    bool isDefined() const noexcept
194
0
    {
195
0
        return value.has_been_set();
196
0
    }
197
198
    void clear() noexcept
199
0
    {
200
0
        value.clear();
201
0
    }
202
203
    // TODO Review this conversion once InstanceHandle_t is implemented as DDS standard defines
204
    explicit operator const GUID_t&() const noexcept
205
0
    {
206
0
        return *reinterpret_cast<const GUID_t*>(this);
207
0
    }
208
209
};
210
211
const InstanceHandle_t c_InstanceHandle_Unknown;
212
213
#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
214
215
/**
216
 * Comparison operator
217
 * @param ihandle1 First InstanceHandle_t to compare
218
 * @param ihandle2 Second InstanceHandle_t to compare
219
 * @return True if equal
220
 */
221
inline bool operator ==(
222
        const InstanceHandle_t& ihandle1,
223
        const InstanceHandle_t& ihandle2) noexcept
224
0
{
225
0
    return ihandle1.value == ihandle2.value;
226
0
}
227
228
/**
229
 * @brief Comparison operator
230
 *
231
 * @param ihandle1 First InstanceHandle_t to compare
232
 * @param ihandle2 Second InstanceHandle_t to compare
233
 * @return True if not equal
234
 */
235
inline bool operator !=(
236
        const InstanceHandle_t& ihandle1,
237
        const InstanceHandle_t& ihandle2) noexcept
238
0
{
239
0
    return !(ihandle1 == ihandle2);
240
0
}
241
242
#endif // ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
243
244
/**
245
 * Convert InstanceHandle_t to GUID
246
 * @param guid GUID to store the results
247
 * @param ihandle InstanceHandle_t to copy
248
 */
249
inline void iHandle2GUID(
250
        GUID_t& guid,
251
        const InstanceHandle_t& ihandle) noexcept
252
0
{
253
0
    const octet* value = ihandle.value;
254
0
    memcpy(guid.guidPrefix.value, value, 12);
255
0
    memcpy(guid.entityId.value, &value[12], 4);
256
0
}
257
258
/**
259
 * Convert GUID to InstanceHandle_t
260
 * @param ihandle InstanceHandle_t to store the results
261
 * @return GUID_t
262
 */
263
inline GUID_t iHandle2GUID(
264
        const InstanceHandle_t& ihandle) noexcept
265
0
{
266
0
    GUID_t guid;
267
0
    iHandle2GUID(guid, ihandle);
268
0
    return guid;
269
0
}
270
271
/**
272
 * @brief Comparison operator: checks if a InstanceHandle_t is less than another.
273
 *
274
 * @param h1 First InstanceHandle_t to compare.
275
 * @param h2 Second InstanceHandle_t to compare.
276
 * @return True if the first InstanceHandle_t is less than the second.
277
 */
278
inline bool operator <(
279
        const InstanceHandle_t& h1,
280
        const InstanceHandle_t& h2) noexcept
281
0
{
282
0
    return h1.value < h2.value;
283
0
}
284
285
#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
286
287
/**
288
 * Stream operator: print an InstanceHandle_t.
289
 *
290
 * @param output Output stream.
291
 * @param iHandle InstanceHandle_t to print.
292
 * @return Stream operator.
293
 */
294
inline std::ostream& operator <<(
295
        std::ostream& output,
296
        const InstanceHandle_t& iHandle)
297
0
{
298
0
    std::stringstream ss;
299
0
    ss << std::hex;
300
0
    for (uint8_t i = 0; i < 15; ++i)
301
0
    {
302
0
        ss << (int)iHandle.value[i] << ".";
303
0
    }
304
0
    ss << (int)iHandle.value[15u] << std::dec;
305
0
    return output << ss.str();
306
0
}
307
308
/**
309
 * Stream operator: retrieve an InstanceHandle_t.
310
 *
311
 * @param input Input stream.
312
 * @param iHandle InstanceHandle_t that will receive the input as its new value.
313
 * @return Stream operator.
314
 */
315
inline std::istream& operator >>(
316
        std::istream& input,
317
        InstanceHandle_t& iHandle)
318
0
{
319
0
    std::istream::sentry s(input);
320
321
0
    if (s)
322
0
    {
323
0
        char point;
324
0
        unsigned short hex;
325
0
        std::ios_base::iostate excp_mask = input.exceptions();
326
327
0
        try
328
0
        {
329
0
            input.exceptions(excp_mask | std::ios_base::failbit | std::ios_base::badbit);
330
0
            input >> std::hex >> hex;
331
332
0
            if (hex > 255)
333
0
            {
334
0
                input.setstate(std::ios_base::failbit);
335
0
            }
336
337
0
            iHandle.value[0u] = static_cast<octet>(hex);
338
339
0
            for (uint8_t i = 1; i < 16; ++i)
340
0
            {
341
0
                input >> point >> hex;
342
0
                if ( point != '.' || hex > 255 )
343
0
                {
344
0
                    input.setstate(std::ios_base::failbit);
345
0
                }
346
0
                iHandle.value[i] = static_cast<octet>(hex);
347
0
            }
348
349
0
            input >> std::dec;
350
0
        }
351
0
        catch (std::ios_base::failure& )
352
0
        {
353
0
        }
354
355
0
        input.exceptions(excp_mask);
356
0
    }
357
358
0
    return input;
359
0
}
360
361
#endif // ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
362
363
} // namespace rtps
364
} // namespace fastdds
365
} // namespace eprosima
366
367
#endif // FASTDDS_RTPS_COMMON__INSTANCEHANDLE_HPP