• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

igor-krechetov / hsmcpp / 4957453907

pending completion
4957453907

push

github

igor-krechetov
[0.37.0][r] fix early delete issue

74 of 74 new or added lines in 5 files covered. (100.0%)

2291 of 2482 relevant lines covered (92.3%)

1739.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.54
/src/variant.cpp
1
// Copyright (C) 2021 Igor Krechetov
2
// Distributed under MIT license. See file LICENSE for details
3

4
#include "hsmcpp/variant.hpp"
5

6
#include <cstring>
7

8
#include "hsmcpp/os/os.hpp"
9

10
// These macroses can't be converted to 'constexpr' template functions
11
// NOLINTBEGIN(cppcoreguidelines-macro-usage)
12

13
// cppcheck-suppress misra-c2012-20.7 ; parentheses are not needed
14
#define IMPL_CONSTRUCTOR(_val_type, _internal_type) \
15
  Variant::Variant(const _val_type v) {             \
16
    assign(v, _internal_type);                      \
17
  }
18

19
// cppcheck-suppress misra-c2012-20.7 ; parentheses are not needed
20
#define IMPL_OPERATOR_ASSIGN(_val_type, _internal_type) \
21
  Variant& Variant::operator=(const _val_type v) {      \
22
    assign(v, _internal_type);                          \
23
    return *this;                                       \
24
  }
25

26
// cppcheck-suppress misra-c2012-20.7 ; parentheses are not needed
27
#define IMPL_MAKE(_val_type)                 \
28
  Variant Variant::make(const _val_type v) { \
29
    return Variant(v);                       \
30
  }
31

32
// NOLINTEND(cppcoreguidelines-macro-usage)
33

34
namespace hsmcpp {
35

36
// =================================================================================================================
37
// make()
38
IMPL_MAKE(int8_t)
130✔
39
IMPL_MAKE(int16_t)
160✔
40
IMPL_MAKE(int32_t)
750✔
41
IMPL_MAKE(int64_t)
130✔
42
IMPL_MAKE(uint8_t)
130✔
43
IMPL_MAKE(uint16_t)
130✔
44
IMPL_MAKE(uint32_t)
130✔
45
IMPL_MAKE(uint64_t)
130✔
46
IMPL_MAKE(double)
160✔
47
IMPL_MAKE(bool)
270✔
48
IMPL_MAKE(std::string&)
220✔
49
IMPL_MAKE(ByteArray_t&)
120✔
50
IMPL_MAKE(VariantVector_t&)
130✔
51
IMPL_MAKE(VariantList_t&)
250✔
52
IMPL_MAKE(VariantMap_t&)
130✔
53
IMPL_MAKE(VariantPair_t&)
130✔
54
IMPL_MAKE(Variant&)
10✔
55

56
Variant Variant::make(const char* v) {
280✔
57
    return Variant(v);
280✔
58
}
59

60
Variant Variant::make(const char* binaryData, const size_t bytesCount) {
10✔
61
    return Variant(binaryData, bytesCount);
10✔
62
}
63

64
// =================================================================================================================
65
// Constructors
66
Variant::Variant(std::shared_ptr<void> d, const Type t)
80✔
67
    : data(std::move(d))
80✔
68
    , type(t) {}
80✔
69

70
Variant::~Variant() {
36,410✔
71
    freeMemory();
36,410✔
72
}
36,410✔
73

74
Variant::Variant(const Variant& v) {
27,180✔
75
    *this = v;
27,180✔
76
}
27,180✔
77

78
Variant::Variant(Variant&& v) noexcept
2,430✔
79
    : data(std::move(v.data))
2,430✔
80
    , type(v.type)
2,430✔
81
    , memoryAllocator(std::move(v.memoryAllocator))
2,430✔
82
    , compareOperator(std::move(v.compareOperator)) {
2,430✔
83
    v.type = Type::UNKNOWN;
2,430✔
84
}
2,430✔
85

86
IMPL_CONSTRUCTOR(int8_t, Type::BYTE_1)
230✔
87
IMPL_CONSTRUCTOR(int16_t, Type::BYTE_2)
210✔
88
IMPL_CONSTRUCTOR(int32_t, Type::BYTE_4)
1,350✔
89
IMPL_CONSTRUCTOR(int64_t, Type::BYTE_8)
200✔
90
IMPL_CONSTRUCTOR(uint8_t, Type::UBYTE_1)
180✔
91
IMPL_CONSTRUCTOR(uint16_t, Type::UBYTE_2)
180✔
92
IMPL_CONSTRUCTOR(uint32_t, Type::UBYTE_4)
250✔
93
IMPL_CONSTRUCTOR(uint64_t, Type::UBYTE_8)
200✔
94
IMPL_CONSTRUCTOR(double, Type::DOUBLE)
240✔
95
IMPL_CONSTRUCTOR(bool, Type::BOOL)
430✔
96
IMPL_CONSTRUCTOR(std::string&, Type::STRING)
1,210✔
97
IMPL_CONSTRUCTOR(ByteArray_t&, Type::BYTEARRAY)
210✔
98
IMPL_CONSTRUCTOR(VariantVector_t&, Type::VECTOR)
190✔
99
IMPL_CONSTRUCTOR(VariantList_t&, Type::LIST)
380✔
100
IMPL_CONSTRUCTOR(VariantMap_t&, Type::MAP)
220✔
101
IMPL_CONSTRUCTOR(VariantPair_t&, Type::PAIR)
260✔
102

103
Variant::Variant(const char* v)
890✔
104
    // cppcheck-suppress misra-c2012-10.4 : false-positive. thinks that ':' is arithmetic operation
105
    : Variant(std::string(v)) {}
1,780✔
106

107
Variant::Variant(const char* binaryData, const size_t bytesCount)
20✔
108
    // cppcheck-suppress misra-c2012-10.4 : false-positive. thinks that ':' is arithmetic operation
109
    : Variant(ByteArray_t(binaryData, &binaryData[bytesCount])) {} // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
40✔
110

111
// =================================================================================================================
112
// Assign operators
113
IMPL_OPERATOR_ASSIGN(int8_t, Type::BYTE_1)
10✔
114
IMPL_OPERATOR_ASSIGN(int16_t, Type::BYTE_2)
10✔
115
IMPL_OPERATOR_ASSIGN(int32_t, Type::BYTE_4)
20✔
116
IMPL_OPERATOR_ASSIGN(int64_t, Type::BYTE_8)
10✔
117
IMPL_OPERATOR_ASSIGN(uint8_t, Type::UBYTE_1)
10✔
118
IMPL_OPERATOR_ASSIGN(uint16_t, Type::UBYTE_2)
10✔
119
IMPL_OPERATOR_ASSIGN(uint32_t, Type::UBYTE_4)
10✔
120
IMPL_OPERATOR_ASSIGN(uint64_t, Type::UBYTE_8)
10✔
121
IMPL_OPERATOR_ASSIGN(double, Type::DOUBLE)
10✔
122
IMPL_OPERATOR_ASSIGN(bool, Type::BOOL)
10✔
123
IMPL_OPERATOR_ASSIGN(std::string&, Type::STRING)
10✔
124
IMPL_OPERATOR_ASSIGN(ByteArray_t&, Type::BYTEARRAY)
10✔
125
IMPL_OPERATOR_ASSIGN(VariantVector_t&, Type::VECTOR)
10✔
126
IMPL_OPERATOR_ASSIGN(VariantList_t&, Type::LIST)
20✔
127
IMPL_OPERATOR_ASSIGN(VariantMap_t&, Type::MAP)
20✔
128
IMPL_OPERATOR_ASSIGN(VariantPair_t&, Type::PAIR)
10✔
129

130
Variant& Variant::operator=(const char* v) {
10✔
131
    assign(std::string(v), Type::STRING);
10✔
132
    return *this;
10✔
133
}
134

135
Variant& Variant::operator=(const Variant& v) {
27,440✔
136
    if (false == isSameObject(v)) {
27,440✔
137
        if ((Type::UNKNOWN != v.type) && (v.memoryAllocator)) {
27,440✔
138
            data = v.memoryAllocator(v.data.get());
27,470✔
139
            type = v.type;
27,430✔
140
            memoryAllocator = v.memoryAllocator;
27,430✔
141
            compareOperator = v.compareOperator;
27,430✔
142
        } else {
143
            freeMemory();
10✔
144
        }
145
    }
146

147
    return *this;
27,440✔
148
}
149

150
Variant& Variant::operator=(Variant&& v) noexcept {
2,290✔
151
    if (false == isSameObject(v)) {
2,290✔
152
        data = std::move(v.data);
2,290✔
153
        type = v.type;
2,290✔
154
        memoryAllocator = std::move(v.memoryAllocator);
2,290✔
155
        compareOperator = std::move(v.compareOperator);
2,290✔
156

157
        v.type = Type::UNKNOWN;
2,290✔
158
    }
159

160
    return *this;
2,290✔
161
}
162

163
// =================================================================================================================
164
Variant::operator bool() const {
10✔
165
    return (data && (Type::UNKNOWN != type));
10✔
166
}
167

168
bool Variant::operator!=(const Variant& val) const {
2,660✔
169
    return !(*this == val);
2,660✔
170
}
171

172
bool Variant::operator>(const Variant& val) const {
1,040✔
173
    bool isGreater = false;
1,040✔
174

175
    if ((data != val.data) && (data) && (val.data)) {
1,040✔
176
        if (isNumeric() && val.isNumeric()) {
1,040✔
177
            if ((Type::DOUBLE == type) || (Type::DOUBLE == val.type)) {
680✔
178
                isGreater = toDouble() > val.toDouble();
40✔
179
            } else if (isUnsignedNumeric() || val.isUnsignedNumeric()) {
640✔
180
                isGreater = toUInt64() > val.toUInt64();
180✔
181
            } else {
182
                isGreater = toInt64() > val.toInt64();
460✔
183
            }
184
        } else if (type == val.type) {
360✔
185
            isGreater = (1 == compareOperator(data.get(), val.data.get()));
720✔
186
        } else {
187
            // do nothing
188
        }
189
    }
190

191
    return isGreater;
1,040✔
192
}
193

194
bool Variant::operator>=(const Variant& val) const {
360✔
195
    return (*this == val) || (*this > val);
360✔
196
}
197

198
bool Variant::operator<(const Variant& val) const {
2,650✔
199
    return (*this != val) && !(*this > val);
2,650✔
200
}
201

202
bool Variant::operator<=(const Variant& val) const {
360✔
203
    return (*this == val) || !(*this > val);
360✔
204
}
205

206
bool Variant::operator==(const Variant& val) const {
4,520✔
207
    constexpr double comparePrecision = 0.00000001;
4,520✔
208
    bool equal = false;
4,520✔
209

210
    if (data != val.data) {
4,520✔
211
        if ((data) && (val.data)) {
4,510✔
212
            if (isNumeric() && val.isNumeric()) {
4,510✔
213
                if ((Type::DOUBLE == type) || (Type::DOUBLE == val.type)) {
2,380✔
214
                    // compare with precision for double
215
                    // cppcheck-suppress misra-c2012-10.4 : false positive. both operands have type double
216
                    equal = (std::abs(toDouble() - val.toDouble()) < comparePrecision);
70✔
217
                } else if (isUnsignedNumeric() || val.isUnsignedNumeric()) {
2,310✔
218
                    equal = (toUInt64() == val.toUInt64());
260✔
219
                } else {
220
                    equal = (toInt64() == val.toInt64());
2,050✔
221
                }
222
            } else if (val.type == type) {
2,130✔
223
                equal = (0 == compareOperator(data.get(), val.data.get()));
4,240✔
224
            } else {
225
                // do nothing
226
            }
227
        }
228
    } else {
229
        equal = true;
230
    }
231

232
    return equal;
4,520✔
233
}
234

235
void Variant::clear() {
50✔
236
    freeMemory();
50✔
237
}
50✔
238

239
bool Variant::isEmpty() const {
450✔
240
    return (type == Type::UNKNOWN);
450✔
241
}
242

243
bool Variant::isString() const {
440✔
244
    return (type == Type::STRING);
440✔
245
}
246

247
bool Variant::isByteArray() const {
300✔
248
    return (type == Type::BYTEARRAY);
300✔
249
}
250

251
bool Variant::isVector() const {
560✔
252
    return (type == Type::VECTOR);
560✔
253
}
254

255
bool Variant::isList() const {
610✔
256
    return (type == Type::LIST);
610✔
257
}
258

259
bool Variant::isMap() const {
570✔
260
    return (type == Type::MAP);
570✔
261
}
262

263
bool Variant::isPair() const {
530✔
264
    return (type == Type::PAIR);
530✔
265
}
266

267
bool Variant::isCustomType() const {
580✔
268
    return (type == Type::CUSTOM);
580✔
269
}
270

271
bool Variant::isNumeric() const {
9,260✔
272
    bool numeric = false;
9,260✔
273

274
    switch (type) {
9,260✔
275
        case Type::BYTE_1:
276
        case Type::BYTE_2:
277
        case Type::BYTE_4:
278
        case Type::BYTE_8:
279
        case Type::UBYTE_1:
280
        case Type::UBYTE_2:
281
        case Type::UBYTE_4:
282
        case Type::UBYTE_8:
283
        case Type::DOUBLE:
284
            numeric = true;
285
            break;
286

287
        case Type::BOOL:
2,590✔
288
        case Type::STRING:
2,590✔
289
        case Type::BYTEARRAY:
2,590✔
290
        case Type::VECTOR:
2,590✔
291
        case Type::LIST:
2,590✔
292
        case Type::MAP:
2,590✔
293
        case Type::PAIR:
2,590✔
294
        default:
2,590✔
295
            numeric = false;
2,590✔
296
            break;
2,590✔
297
    }
298

299
    return numeric;
9,260✔
300
}
301

302
bool Variant::isSignedNumeric() const {
430✔
303
    bool isSigned = false;
430✔
304

305
    switch (type) {
430✔
306
        case Type::BYTE_1:
307
        case Type::BYTE_2:
308
        case Type::BYTE_4:
309
        case Type::BYTE_8:
310
        case Type::DOUBLE:
311
            isSigned = true;
312
            break;
313

314
        default:
140✔
315
            isSigned = false;
140✔
316
            break;
140✔
317
    }
318

319
    return isSigned;
430✔
320
}
321

322
bool Variant::isUnsignedNumeric() const {
5,930✔
323
    bool isUnsigned = false;
5,930✔
324

325
    switch (type) {
5,930✔
326
        case Type::UBYTE_1:
327
        case Type::UBYTE_2:
328
        case Type::UBYTE_4:
329
        case Type::UBYTE_8:
330
            isUnsigned = true;
331
            break;
332

333
        default:
5,210✔
334
            isUnsigned = false;
5,210✔
335
            break;
5,210✔
336
    }
337

338
    return isUnsigned;
5,930✔
339
}
340

341
bool Variant::isBool() const {
390✔
342
    return (type == Type::BOOL);
390✔
343
}
344

345
std::string Variant::toString() const {
1,870✔
346
    std::string result;
1,870✔
347

348
    switch (getType()) {
1,870✔
349
        case Type::BYTE_1:
20✔
350
            result = std::to_string(*(value<int8_t>()));
20✔
351
            break;
20✔
352
        case Type::BYTE_2:
40✔
353
            result = std::to_string(*(value<int16_t>()));
40✔
354
            break;
40✔
355
        case Type::BYTE_4:
50✔
356
            result = std::to_string(*(value<int32_t>()));
50✔
357
            break;
50✔
358
        case Type::BYTE_8:
10✔
359
            result = std::to_string(*(value<int64_t>()));
10✔
360
            break;
10✔
361
        case Type::UBYTE_1:
10✔
362
            result = std::to_string(*(value<uint8_t>()));
10✔
363
            break;
10✔
364
        case Type::UBYTE_2:
10✔
365
            result = std::to_string(*(value<uint16_t>()));
10✔
366
            break;
10✔
367
        case Type::UBYTE_4:
10✔
368
            result = std::to_string(*(value<uint32_t>()));
10✔
369
            break;
10✔
370
        case Type::UBYTE_8:
10✔
371
            result = std::to_string(*(value<uint64_t>()));
10✔
372
            break;
10✔
373
        case Type::DOUBLE:
10✔
374
            result = std::to_string(*(value<double>()));
10✔
375
            break;
10✔
376
        case Type::BOOL:
10✔
377
            result = (*(value<bool>()) ? "true" : "false");
20✔
378
            break;
10✔
379
        case Type::STRING:
1,630✔
380
            result = *(value<std::string>());
3,260✔
381
            break;
1,630✔
382
        case Type::BYTEARRAY: {
10✔
383
            std::shared_ptr<ByteArray_t> val = value<ByteArray_t>();
10✔
384

385
            result.assign(val->begin(), val->end());
10✔
386
            break;
10✔
387
        }
10✔
388
        case Type::VECTOR: {
10✔
389
            std::shared_ptr<VariantVector_t> val = value<VariantVector_t>();
10✔
390

391
            // cppcheck-suppress misra-c2012-14.4 ; false-positive. std::shared_ptr has a bool() operator
392
            if (val) {
10✔
393
                for (const Variant& item: *val) {
40✔
394
                    if (false == result.empty()) {
30✔
395
                        result.append(", ");
20✔
396
                    }
397

398
                    result += item.toString();
60✔
399
                }
400
            }
401
            break;
10✔
402
        }
10✔
403
        case Type::LIST: {
10✔
404
            std::shared_ptr<VariantList_t> val = value<VariantList_t>();
10✔
405

406
            // cppcheck-suppress misra-c2012-14.4 ; false-positive. std::shared_ptr has a bool() operator
407
            if (val) {
10✔
408
                for (const Variant& item: *val) {
40✔
409
                    if (false == result.empty()) {
30✔
410
                        result.append(", ");
20✔
411
                    }
412

413
                    result += item.toString();
60✔
414
                }
415
            }
416
            break;
10✔
417
        }
10✔
418
        case Type::MAP: {
10✔
419
            std::shared_ptr<VariantMap_t> val = value<VariantMap_t>();
10✔
420

421
            // cppcheck-suppress misra-c2012-14.4 ; false-positive. std::shared_ptr has a bool() operator
422
            if (val) {
10✔
423
                for (const auto& item: *val) {
40✔
424
                    if (false == result.empty()) {
30✔
425
                        result.append(", ");
20✔
426
                    }
427
                    result += item.first.toString().append("=[").append(item.second.toString()).append("]");
90✔
428
                }
429
            }
430
            break;
10✔
431
        }
10✔
432
        case Type::PAIR:
10✔
433
            result = std::string("(") + value<VariantPair_t>()->first.toString() + std::string(", ") +
50✔
434
                     value<VariantPair_t>()->second.toString() + std::string(")");
50✔
435
            break;
10✔
436
        default:
437
            break;
438
    }
439

440
    return result;
1,870✔
441
}
×
442

443
int64_t Variant::toInt64() const {
6,520✔
444
    int64_t result = 0;
6,520✔
445

446
    switch (type) {
6,520✔
447
        case Type::BYTE_1:
230✔
448
            result = static_cast<int64_t>(*value<int8_t>());
230✔
449
            break;
230✔
450
        case Type::BYTE_2:
210✔
451
            result = static_cast<int64_t>(*value<int16_t>());
210✔
452
            break;
210✔
453
        case Type::BYTE_4:
5,240✔
454
            result = static_cast<int64_t>(*value<int32_t>());
5,240✔
455
            break;
5,240✔
456
        case Type::BYTE_8:
280✔
457
            result = *value<int64_t>();
280✔
458
            break;
280✔
459

460
        case Type::UBYTE_1:
20✔
461
            result = static_cast<int64_t>(*value<uint8_t>());
20✔
462
            break;
20✔
463
        case Type::UBYTE_2:
20✔
464
            result = static_cast<int64_t>(*value<uint16_t>());
20✔
465
            break;
20✔
466
        case Type::UBYTE_4:
20✔
467
            result = static_cast<int64_t>(*value<uint32_t>());
20✔
468
            break;
20✔
469
        case Type::UBYTE_8:
20✔
470
            result = static_cast<int64_t>(*value<uint64_t>());
20✔
471
            break;
20✔
472

473
        case Type::DOUBLE:
20✔
474
            result = static_cast<int64_t>(*value<double>());
20✔
475
            break;
20✔
476

477
        case Type::BOOL:
10✔
478
            result = static_cast<int64_t>(*value<bool>());
10✔
479
            break;
10✔
480

481
        case Type::STRING:
330✔
482
            HSM_TRY {
330✔
483
                result = std::stoll(toString());
660✔
484
            }
485
            HSM_CATCH(...) {
320✔
486
                // return empty value
487
            }
320✔
488
            break;
489

490
        case Type::BYTEARRAY:
491
        case Type::VECTOR:
492
        case Type::LIST:
493
        case Type::MAP:
494
        case Type::PAIR:
495
        default:
496
            break;
497
    }
498

499
    return result;
6,520✔
500
}
501

502
uint64_t Variant::toUInt64() const {
1,620✔
503
    uint64_t result = 0;
1,620✔
504

505
    switch (type) {
1,620✔
506
        case Type::BYTE_1:
60✔
507
            result = static_cast<uint64_t>(*value<int8_t>());
60✔
508
            break;
60✔
509
        case Type::BYTE_2:
10✔
510
            result = static_cast<uint64_t>(*value<int16_t>());
10✔
511
            break;
10✔
512
        case Type::BYTE_4:
150✔
513
            result = static_cast<uint64_t>(*value<int32_t>());
150✔
514
            break;
150✔
515
        case Type::BYTE_8:
10✔
516
            result = static_cast<uint64_t>(*value<int64_t>());
10✔
517
            break;
10✔
518

519
        case Type::UBYTE_1:
200✔
520
            result = static_cast<uint64_t>(*value<uint8_t>());
200✔
521
            break;
200✔
522
        case Type::UBYTE_2:
200✔
523
            result = static_cast<uint64_t>(*value<uint16_t>());
200✔
524
            break;
200✔
525
        case Type::UBYTE_4:
310✔
526
            result = static_cast<uint64_t>(*value<uint32_t>());
310✔
527
            break;
310✔
528
        case Type::UBYTE_8:
270✔
529
            result = *value<uint64_t>();
270✔
530
            break;
270✔
531

532
        case Type::DOUBLE:
10✔
533
            result = static_cast<uint64_t>(*value<double>());
10✔
534
            break;
10✔
535

536
        case Type::BOOL:
10✔
537
            result = static_cast<int64_t>(*value<bool>());
10✔
538
            break;
10✔
539

540
        case Type::STRING:
330✔
541
            HSM_TRY {
330✔
542
                result = std::stoull(toString());
660✔
543
            }
544
            HSM_CATCH(...) {
320✔
545
                // return empty value
546
            }
320✔
547
            break;
548

549
        case Type::BYTEARRAY:
550
        case Type::VECTOR:
551
        case Type::LIST:
552
        case Type::MAP:
553
        case Type::PAIR:
554
        default:
555
            break;
556
    }
557

558
    return result;
1,620✔
559
}
560

561
double Variant::toDouble() const {
800✔
562
    double result = 0.0;
800✔
563

564
    switch (type) {
800✔
565
        case Type::BYTE_1:
20✔
566
            result = static_cast<double>(*value<int8_t>());
20✔
567
            break;
20✔
568
        case Type::BYTE_2:
10✔
569
            result = static_cast<double>(*value<int16_t>());
10✔
570
            break;
10✔
571
        case Type::BYTE_4:
10✔
572
            result = static_cast<double>(*value<int32_t>());
10✔
573
            break;
10✔
574
        case Type::BYTE_8:
10✔
575
            result = static_cast<double>(*value<int64_t>());
10✔
576
            break;
10✔
577

578
        case Type::UBYTE_1:
10✔
579
            result = static_cast<double>(*value<uint8_t>());
10✔
580
            break;
10✔
581
        case Type::UBYTE_2:
10✔
582
            result = static_cast<double>(*value<uint16_t>());
10✔
583
            break;
10✔
584
        case Type::UBYTE_4:
20✔
585
            result = static_cast<double>(*value<uint32_t>());
20✔
586
            break;
20✔
587
        case Type::UBYTE_8:
10✔
588
            result = static_cast<double>(*value<uint64_t>());
10✔
589
            break;
10✔
590

591
        case Type::DOUBLE:
300✔
592
            result = *value<double>();
300✔
593
            break;
300✔
594

595
        case Type::BOOL:
10✔
596
            result = static_cast<double>(toBool());
10✔
597
            break;
10✔
598

599
        case Type::STRING:
330✔
600
            HSM_TRY {
330✔
601
                result = std::stod(toString());
660✔
602
            }
603
            HSM_CATCH(...) {
320✔
604
                // return empty value
605
            }
320✔
606
            break;
607

608
        case Type::BYTEARRAY:
609
        case Type::VECTOR:
610
        case Type::LIST:
611
        case Type::MAP:
612
        case Type::PAIR:
613
        default:
614
            break;
615
    }
616

617
    return result;
800✔
618
}
619

620
bool Variant::toBool() const {
410✔
621
    bool result = false;
410✔
622

623
    if (Type::BOOL == type) {
410✔
624
        result = *value<bool>();
440✔
625
    } else if (Type::STRING == type) {
190✔
626
        const std::string strValue = toString();
30✔
627

628
        if (strValue != "true") {
30✔
629
            HSM_TRY {
20✔
630
                result = (0 != std::stoll(strValue));
20✔
631
            }
632
            HSM_CATCH(...) {
10✔
633
                // return empty value
634
            }
10✔
635
        } else {
636
            result = true;
637
        }
638
    } else {
30✔
639
        result = (0 != toInt64());
160✔
640
    }
641

642
    return result;
410✔
643
}
644

645
ByteArray_t Variant::toByteArray() const {
330✔
646
    ByteArray_t result;
330✔
647

648
    switch (getType()) {
330✔
649
        case Type::BYTE_1:
30✔
650
        case Type::UBYTE_1:
30✔
651
            result.resize(sizeof(int8_t));
30✔
652
            static_cast<void>(std::memcpy(result.data(), data.get(), sizeof(int8_t)));
30✔
653
            break;
654
        case Type::BYTE_2:
50✔
655
        case Type::UBYTE_2:
50✔
656
            result.resize(sizeof(int16_t));
50✔
657
            static_cast<void>(memcpy(result.data(), data.get(), sizeof(int16_t)));
50✔
658
            break;
659
        case Type::BYTE_4:
30✔
660
        case Type::UBYTE_4:
30✔
661
            result.resize(sizeof(int32_t));
30✔
662
            static_cast<void>(memcpy(result.data(), data.get(), sizeof(int32_t)));
30✔
663
            break;
664
        case Type::BYTE_8:
20✔
665
        case Type::UBYTE_8:
20✔
666
            result.resize(sizeof(int64_t));
20✔
667
            static_cast<void>(memcpy(result.data(), data.get(), sizeof(int64_t)));
20✔
668
            break;
669
        case Type::DOUBLE:
10✔
670
            result.resize(sizeof(double));
10✔
671
            static_cast<void>(memcpy(result.data(), data.get(), sizeof(double)));
10✔
672
            break;
673
        case Type::BOOL:
10✔
674
            result.push_back((toBool() == true) ? 0x01 : 0x00);
20✔
675
            break;
10✔
676
        case Type::STRING: {
70✔
677
            std::shared_ptr<std::string> val = value<std::string>();
70✔
678

679
            // cppcheck-suppress misra-c2012-14.4 ; false-positive. std::shared_ptr has a bool() operator
680
            if (val) {
70✔
681
                result.assign(val->begin(), val->end());
70✔
682
            }
683
            break;
70✔
684
        }
70✔
685
        case Type::BYTEARRAY:
60✔
686
            result = *(value<ByteArray_t>());
60✔
687
            break;
60✔
688
        case Type::VECTOR: {
10✔
689
            std::shared_ptr<VariantVector_t> data = value<VariantVector_t>();
10✔
690

691
            // cppcheck-suppress misra-c2012-14.4 ; false-positive. std::shared_ptr has a bool() operator
692
            if (data) {
10✔
693
                for (const Variant& item: *data) {
40✔
694
                    const ByteArray_t curValue = item.toByteArray();
30✔
695

696
                    (void)result.insert(result.end(), curValue.begin(), curValue.end());
30✔
697
                }
30✔
698
            }
699
            break;
10✔
700
        }
10✔
701
        case Type::LIST: {
10✔
702
            std::shared_ptr<VariantList_t> data = value<VariantList_t>();
10✔
703

704
            // cppcheck-suppress misra-c2012-14.4 ; false-positive. std::shared_ptr has a bool() operator
705
            if (data) {
10✔
706
                for (const Variant& item: *data) {
40✔
707
                    const ByteArray_t curValue = item.toByteArray();
30✔
708

709
                    (void)result.insert(result.end(), curValue.begin(), curValue.end());
30✔
710
                }
30✔
711
            }
712
            break;
10✔
713
        }
10✔
714
        case Type::PAIR: {
10✔
715
            // TODO: is this even needed?
716
            ByteArray_t secondValue = value<VariantPair_t>()->second.toByteArray();
10✔
717

718
            result = value<VariantPair_t>()->first.toByteArray();
20✔
719
            (void)result.insert(result.end(), secondValue.begin(), secondValue.end());
10✔
720
            break;
10✔
721
        }
10✔
722

723
        case Type::MAP:
724
        default:
725
            break;
726
    }
727

728
    return result;
330✔
729
}
×
730

731
std::shared_ptr<ByteArray_t> Variant::getByteArray() const {
40✔
732
    std::shared_ptr<ByteArray_t> result;
40✔
733

734
    if (true == isByteArray()) {
40✔
735
        result = value<ByteArray_t>();
30✔
736
    }
737

738
    return result;
40✔
739
}
×
740

741
std::shared_ptr<VariantVector_t> Variant::getVector() const {
260✔
742
    std::shared_ptr<VariantVector_t> result;
260✔
743

744
    if (true == isVector()) {
260✔
745
        result = value<VariantVector_t>();
70✔
746
    }
747

748
    return result;
260✔
749
}
×
750

751
std::shared_ptr<VariantList_t> Variant::getList() const {
260✔
752
    std::shared_ptr<VariantList_t> result;
260✔
753

754
    if (true == isList()) {
260✔
755
        result = value<VariantList_t>();
70✔
756
    }
757

758
    return result;
260✔
759
}
×
760

761
std::shared_ptr<VariantMap_t> Variant::getMap() const {
290✔
762
    std::shared_ptr<VariantMap_t> result;
290✔
763

764
    if (true == isMap()) {
290✔
765
        result = value<VariantMap_t>();
60✔
766
    }
767

768
    return result;
290✔
769
}
×
770

771
std::shared_ptr<VariantPair_t> Variant::getPair() const {
210✔
772
    std::shared_ptr<VariantPair_t> result;
210✔
773

774
    if (true == isPair()) {
210✔
775
        result = value<VariantPair_t>();
20✔
776
    }
777

778
    return result;
210✔
779
}
×
780

781
bool Variant::isSameObject(const Variant& val) const {
29,730✔
782
    return ((val.data.get() == data.get()) && data);
29,730✔
783
}
784

785
void Variant::freeMemory() {
42,860✔
786
    data.reset();
42,860✔
787
    type = Type::UNKNOWN;
42,860✔
788
    memoryAllocator = nullptr;
42,860✔
789
    compareOperator = nullptr;
42,860✔
790
}
42,860✔
791

792
}  // namespace hsmcpp
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc