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