GCC Code Coverage Report


libs/base/src/base/
File: guid.cc
Date: 2025-03-19 20:55:25
Lines:
65/67
97.0%
Functions:
14/14
100.0%
Branches:
40/56
71.4%

Line Branch Exec Source
1 #include "base/guid.h"
2
3
4 #ifdef _WIN32
5 #include <objbase.h>
6 #else
7 #include <uuid/uuid.h>
8 #endif
9
10
11 namespace eu
12 {
13 #ifndef _WIN32
14 1 std::optional<Guid> Guid::generate()
15 {
16 1 Guid guid {};
17
1/2
✓ Branch 0 (4 → 5) taken 1 times.
✗ Branch 1 (4 → 8) not taken.
1 uuid_generate(guid.data.data());
18 2 return guid;
19 }
20 #else
21 std::optional<Guid> Guid::generate()
22 {
23 GUID g;
24
25 if (S_OK != CoCreateGuid(&g))
26 {
27 return std::nullopt;
28 }
29
30 std::array<uint8_t, 16> data
31 {
32 static_cast<std::uint8_t>((g.Data1 >> 24) & 0xff),
33 static_cast<std::uint8_t>((g.Data1 >> 16) & 0xff),
34 static_cast<std::uint8_t>((g.Data1 >> 8) & 0xff),
35 static_cast<std::uint8_t>((g.Data1 ) & 0xff),
36 static_cast<std::uint8_t>((g.Data2 >> 8 ) & 0xff),
37 static_cast<std::uint8_t>((g.Data2 ) & 0xff),
38 static_cast<std::uint8_t>((g.Data3 >> 8 ) & 0xff),
39 static_cast<std::uint8_t>((g.Data3 ) & 0xff),
40 static_cast<std::uint8_t>( g.Data4[0] ),
41 static_cast<std::uint8_t>( g.Data4[1] ),
42 static_cast<std::uint8_t>( g.Data4[2] ),
43 static_cast<std::uint8_t>( g.Data4[3] ),
44 static_cast<std::uint8_t>( g.Data4[4] ),
45 static_cast<std::uint8_t>( g.Data4[5] ),
46 static_cast<std::uint8_t>( g.Data4[6] ),
47 static_cast<std::uint8_t>( g.Data4[7] )
48 };
49
50 return Guid{data};
51 }
52 #endif
53
54 8 bool operator==(const Guid& lhs, const Guid& rhs)
55 {
56
2/2
✓ Branch 0 (8 → 3) taken 113 times.
✓ Branch 1 (8 → 9) taken 7 times.
120 for(int data_index=0; data_index<16; data_index+=1)
57 {
58
2/2
✓ Branch 0 (5 → 6) taken 1 times.
✓ Branch 1 (5 → 7) taken 112 times.
113 if (lhs.data[data_index] != rhs.data[data_index])
59 1 { return false; }
60 }
61 7 return true;
62 }
63
64 1 bool operator!=(const Guid& lhs, const Guid& rhs)
65 {
66 1 return !(lhs == rhs);
67 }
68
69 struct Parser
70 {
71 std::string_view str;
72
73 8 explicit Parser(const std::string_view s) : str(s) {}
74
75 912 [[nodiscard]] bool has_more() const
76 {
77 912 return str.empty() == false;
78 }
79
80 277 char read()
81 {
82
1/2
✗ Branch 0 (3 → 4) not taken.
✓ Branch 1 (3 → 5) taken 277 times.
277 if(has_more() == false)
83 { return '\0'; }
84 277 const char r = str[0];
85 277 str = str.substr(1);
86 277 return r;
87 }
88
89 522 [[nodiscard]] char peek() const
90 {
91
2/2
✓ Branch 0 (3 → 4) taken 12 times.
✓ Branch 1 (3 → 5) taken 510 times.
522 if(has_more() == false)
92 12 { return '\0'; }
93 510 return str[0];
94 }
95
96 357 void skip(char c)
97 {
98
2/2
✓ Branch 0 (5 → 3) taken 54 times.
✓ Branch 1 (5 → 6) taken 357 times.
411 while(peek() == c)
99 {
100 54 read();
101 }
102 357 }
103
104 238 void skip_spaces()
105 {
106 238 skip(' ');
107 238 }
108
109 223 static std::optional<uint8_t> as_hex(char c)
110 {
111
3/4
✓ Branch 0 (2 → 3) taken 223 times.
✗ Branch 1 (2 → 7) not taken.
✓ Branch 2 (3 → 4) taken 187 times.
✓ Branch 3 (3 → 7) taken 36 times.
223 if ('0' <= c && c <= '9') { return static_cast<uint8_t>(c - '0'); }
112
4/4
✓ Branch 0 (7 → 8) taken 26 times.
✓ Branch 1 (7 → 12) taken 10 times.
✓ Branch 2 (8 → 9) taken 25 times.
✓ Branch 3 (8 → 12) taken 1 times.
36 if ('a' <= c && c <= 'f') { return static_cast<uint8_t>(10 + (c - 'a')); }
113
3/4
✓ Branch 0 (12 → 13) taken 11 times.
✗ Branch 1 (12 → 17) not taken.
✓ Branch 2 (13 → 14) taken 10 times.
✓ Branch 3 (13 → 17) taken 1 times.
11 if ('A' <= c && c <= 'F') { return static_cast<uint8_t>(10 + (c - 'A')); }
114 1 return std::nullopt;
115 }
116
117 112 std::optional<uint8_t> read_hex()
118 {
119
1/2
✓ Branch 0 (2 → 3) taken 112 times.
✗ Branch 1 (2 → 22) not taken.
112 const auto first = as_hex(read());
120
2/2
✓ Branch 0 (5 → 6) taken 1 times.
✓ Branch 1 (5 → 9) taken 111 times.
112 if(first.has_value() == false) { return std::nullopt; }
121
122 111 const auto second = as_hex(peek());
123
1/2
✓ Branch 0 (12 → 13) taken 111 times.
✗ Branch 1 (12 → 19) not taken.
111 if(second.has_value())
124 {
125
1/2
✓ Branch 0 (13 → 14) taken 111 times.
✗ Branch 1 (13 → 22) not taken.
111 read();
126 111 return static_cast<uint8_t>((*first << 4) | *second);
127 }
128 else
129 {
130 return first;
131 }
132 }
133 };
134
135 8 std::optional<Guid> guid_from(const std::string& str)
136 {
137 8 auto parser = Parser{str};
138
1/2
✓ Branch 0 (4 → 5) taken 8 times.
✗ Branch 1 (4 → 27) not taken.
8 parser.skip_spaces();
139
1/2
✓ Branch 0 (5 → 6) taken 8 times.
✗ Branch 1 (5 → 27) not taken.
8 parser.skip('{');
140
1/2
✓ Branch 0 (6 → 7) taken 8 times.
✗ Branch 1 (6 → 27) not taken.
8 parser.skip_spaces();
141
142 8 Guid ret {};
143
2/2
✓ Branch 0 (22 → 8) taken 113 times.
✓ Branch 1 (22 → 23) taken 6 times.
119 for(int index=0; index<16; index+=1)
144 {
145
2/2
✓ Branch 0 (9 → 10) taken 1 times.
✓ Branch 1 (9 → 11) taken 112 times.
114 if(parser.has_more() == false) { return std::nullopt; }
146
147
1/2
✓ Branch 0 (11 → 12) taken 112 times.
✗ Branch 1 (11 → 26) not taken.
112 auto hex = parser.read_hex();
148
2/2
✓ Branch 0 (13 → 14) taken 1 times.
✓ Branch 1 (13 → 15) taken 111 times.
112 if(hex.has_value() == false) { return std::nullopt; }
149
150 111 ret.data[index] = *hex;
151
1/2
✓ Branch 0 (17 → 18) taken 111 times.
✗ Branch 1 (17 → 26) not taken.
111 parser.skip_spaces();
152
1/2
✓ Branch 0 (18 → 19) taken 111 times.
✗ Branch 1 (18 → 26) not taken.
111 parser.skip('-');
153
1/2
✓ Branch 0 (19 → 20) taken 111 times.
✗ Branch 1 (19 → 26) not taken.
111 parser.skip_spaces();
154 }
155
156 6 return ret;
157 }
158
159 13 std::string string_from(const Guid& x)
160 {
161 return fmt::format
162 (
163 "{:02x}{:02x}{:02x}{:02x}-"
164 "{:02x}{:02x}-"
165 "{:02x}{:02x}-"
166 "{:02x}{:02x}-"
167 "{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
168 13 x.data[0], x.data[1], x.data[2], x.data[3],
169 13 x.data[4], x.data[5],
170 13 x.data[6], x.data[7],
171 13 x.data[8], x.data[9],
172 13 x.data[10], x.data[11], x.data[12], x.data[13], x.data[14], x.data[15]
173 26 );
174 }
175
176
2/4
✓ Branch 0 (2 → 3) taken 2 times.
✗ Branch 1 (2 → 10) not taken.
✓ Branch 2 (3 → 4) taken 2 times.
✗ Branch 3 (3 → 8) not taken.
2 ADD_CATCH_FORMATTER_IMPL(Guid)
177 }
178