Coverage Report

Created: 2025-06-13 06:46

/src/Fast-DDS/include/fastdds/rtps/common/Property.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 Property.hpp
17
 */
18
#ifndef FASTDDS_RTPS_COMMON__PROPERTY_HPP
19
#define FASTDDS_RTPS_COMMON__PROPERTY_HPP
20
21
#include <functional>
22
#include <stdexcept>
23
#include <string>
24
#include <vector>
25
26
namespace eprosima {
27
namespace fastdds {
28
namespace rtps {
29
30
class Property
31
{
32
public:
33
34
    Property()
35
0
    {
36
0
    }
37
38
    Property(
39
            const Property& property)
40
15
        : name_(property.name_)
41
15
        , value_(property.value_)
42
15
        , propagate_(property.propagate_)
43
15
    {
44
15
    }
45
46
    Property(
47
            Property&& property)
48
0
        : name_(std::move(property.name_))
49
0
        , value_(std::move(property.value_))
50
0
        , propagate_(property.propagate_)
51
0
    {
52
0
    }
53
54
    Property(
55
            const std::string& name,
56
            const std::string& value,
57
            bool propagate = false)
58
        : name_(name)
59
        , value_(value)
60
        , propagate_(propagate)
61
0
    {
62
0
    }
63
64
    Property(
65
            std::string&& name,
66
            std::string&& value,
67
            bool propagate = false)
68
20
        : name_(std::move(name))
69
20
        , value_(std::move(value))
70
20
        , propagate_(propagate)
71
20
    {
72
20
    }
73
74
    Property& operator =(
75
            const Property& property)
76
0
    {
77
0
        name_ = property.name_;
78
0
        value_ = property.value_;
79
0
        propagate_ = property.propagate_;
80
0
        return *this;
81
0
    }
82
83
    Property& operator =(
84
            Property&& property)
85
0
    {
86
0
        name_ = std::move(property.name_);
87
0
        value_ = std::move(property.value_);
88
0
        propagate_ = property.propagate_;
89
0
        return *this;
90
0
    }
91
92
    bool operator ==(
93
            const Property& b) const
94
0
    {
95
0
        return (this->name_ == b.name_) &&
96
0
               (this->value_ == b.value_);
97
0
    }
98
99
    void name(
100
            const std::string& name)
101
0
    {
102
0
        name_ = name;
103
0
    }
104
105
    void name(
106
            std::string&& name)
107
0
    {
108
0
        name_ = std::move(name);
109
0
    }
110
111
    const std::string& name() const
112
0
    {
113
0
        return name_;
114
0
    }
115
116
    std::string& name()
117
0
    {
118
0
        return name_;
119
0
    }
120
121
    void value(
122
            const std::string& value)
123
0
    {
124
0
        value_ = value;
125
0
    }
126
127
    void value(
128
            std::string&& value)
129
0
    {
130
0
        value_ = std::move(value);
131
0
    }
132
133
    const std::string& value() const
134
0
    {
135
0
        return value_;
136
0
    }
137
138
    std::string& value()
139
0
    {
140
0
        return value_;
141
0
    }
142
143
    void propagate(
144
            bool propagate)
145
0
    {
146
0
        propagate_ = propagate;
147
0
    }
148
149
    bool propagate() const
150
0
    {
151
0
        return propagate_;
152
0
    }
153
154
    bool& propagate()
155
0
    {
156
0
        return propagate_;
157
0
    }
158
159
private:
160
161
    std::string name_;
162
163
    std::string value_;
164
165
    bool propagate_ = false;
166
};
167
168
typedef std::vector<Property> PropertySeq;
169
170
class PropertyHelper
171
{
172
public:
173
174
    static size_t serialized_size(
175
            const Property& property,
176
            size_t current_alignment = 0)
177
0
    {
178
0
        if (property.propagate())
179
0
        {
180
0
            size_t initial_alignment = current_alignment;
181
0
182
0
            current_alignment += 4 + alignment(current_alignment, 4) + property.name().size() + 1;
183
0
            current_alignment += 4 + alignment(current_alignment, 4) + property.value().size() + 1;
184
0
185
0
            return current_alignment - initial_alignment;
186
0
        }
187
0
        else
188
0
        {
189
0
            return 0;
190
0
        }
191
0
    }
192
193
    static size_t serialized_size(
194
            const PropertySeq& properties,
195
            size_t current_alignment = 0)
196
0
    {
197
0
        size_t initial_alignment = current_alignment;
198
0
199
0
        current_alignment += 4 + alignment(current_alignment, 4);
200
0
        for (auto property = properties.begin(); property != properties.end(); ++property)
201
0
        {
202
0
            current_alignment += serialized_size(*property, current_alignment);
203
0
        }
204
0
205
0
        return current_alignment - initial_alignment;
206
0
    }
207
208
private:
209
210
    inline static size_t alignment(
211
            size_t current_alignment,
212
            size_t dataSize)
213
0
    {
214
0
        return (dataSize - (current_alignment % dataSize)) & (dataSize - 1);
215
0
    }
216
217
};
218
219
struct PropertyParser
220
{
221
222
    /**
223
     * @brief Parse a property value as an integer
224
     * @param property Property to parse
225
     * @param check_upper_bound If true, check that the value is lower than upper_bound
226
     * @param upper_bound Upper bound to check
227
     * @param check_lower_bound If true, check that the value is greater than lower_bound
228
     * @param lower_bound Lower bound to check
229
     * @param exception Exception to throw if the value is not a valid integer or if it is out of bounds
230
     * @return The parsed integer value
231
     *
232
     * @warning May throw an exception_t if the value is not a valid integer
233
     *  or if it is out of bounds.
234
     */
235
    template<typename exception_t>
236
    inline static int as_int(
237
            const Property& property,
238
            const bool& check_upper_bound,
239
            const int& upper_bound,
240
            const bool& check_lower_bound,
241
            const int& lower_bound,
242
            const exception_t& exception)
243
    {
244
        return parse_value(
245
            std::function<int(const Property& property)>(
246
                [](const Property& property)
247
                {
248
                    return std::stoi(property.value());
249
                }
250
                ),
251
            property,
252
            check_upper_bound,
253
            upper_bound,
254
            check_lower_bound,
255
            lower_bound,
256
            exception);
257
    }
258
259
    /**
260
     * @brief Parse a property value as a double
261
     * @param property Property to parse
262
     * @param check_upper_bound If true, check that the value is lower than upper_bound
263
     * @param upper_bound Upper bound to check
264
     * @param check_lower_bound If true, check that the value is greater than lower_bound
265
     * @param lower_bound Lower bound to check
266
     * @param exception Exception to throw if the value is not a valid double or if it is out of bounds
267
     * @return The parsed double value
268
     *
269
     * @warning May throw an exception_t if the value is not a valid double
270
     *  or if it is out of bounds.
271
     */
272
    template<typename exception_t>
273
    inline static double as_double(
274
            const Property& property,
275
            const bool& check_upper_bound,
276
            const double& upper_bound,
277
            const bool& check_lower_bound,
278
            const double& lower_bound,
279
            const exception_t& exception)
280
    {
281
        return parse_value(
282
            std::function<double(const Property& property)>(
283
                [](const Property& property)
284
                {
285
                    return std::stod(property.value());
286
                }
287
                ),
288
            property,
289
            check_upper_bound,
290
            upper_bound,
291
            check_lower_bound,
292
            lower_bound,
293
            exception);
294
    }
295
296
    /**
297
     * @brief Parse a property value as a boolean
298
     * @param property Property to parse
299
     * @return The parsed boolean value
300
     *
301
     */
302
    inline static bool as_bool(
303
            const Property& property)
304
0
    {
305
0
        bool ret = false;
306
0
        const std::string& value = property.value();
307
0
        if (value == "true" || value == "TRUE" || value == "True" || value == "1")
308
0
        {
309
0
            ret = true;
310
0
        }
311
0
        return ret;
312
0
    }
313
314
private:
315
316
    template <typename value_t,
317
            typename exception_t>
318
    inline static value_t parse_value(
319
            const std::function<value_t(const Property&)>& conversor,
320
            const Property& property,
321
            const bool& check_upper_bound,
322
            const value_t& upper_bound,
323
            const bool& check_lower_bound,
324
            const value_t& lower_bound,
325
            const exception_t& exception)
326
    {
327
        try
328
        {
329
            value_t converted_value = conversor(property);
330
331
            if (check_lower_bound && converted_value < lower_bound)
332
            {
333
                throw exception_t("Value '" + property.value() +
334
                              "' for " + property.name() + " must be greater or equal to " +
335
                              std::to_string(lower_bound));
336
            }
337
338
            if (check_upper_bound && converted_value > upper_bound)
339
            {
340
                throw exception_t("Value '" + property.value() +
341
                              "' for " + property.name() + " must be lower or equal to " +
342
                              std::to_string(upper_bound));
343
            }
344
345
            return converted_value;
346
        }
347
        catch (const std::invalid_argument&)
348
        {
349
            throw exception;
350
        }
351
        catch (const std::out_of_range&)
352
        {
353
            throw exception;
354
        }
355
    }
356
357
};
358
359
} //namespace eprosima
360
} //namespace fastdds
361
} //namespace rtps
362
363
#endif // FASTDDS_RTPS_COMMON__PROPERTY_HPP