/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 |