GCC Code Coverage Report


Directory: libs/url/
File: libs/url/src/authority_view.cpp
Date: 2024-02-29 20:02:56
Exec Total Coverage
Lines: 137 161 85.1%
Functions: 20 22 90.9%
Branches: 54 88 61.4%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/url
8 //
9
10 #ifndef BOOST_URL_IMPL_AUTHORITY_VIEW_IPP
11 #define BOOST_URL_IMPL_AUTHORITY_VIEW_IPP
12
13 #include <boost/url/detail/config.hpp>
14 #include <boost/url/authority_view.hpp>
15 #include "detail/normalize.hpp"
16 #include <boost/url/grammar/parse.hpp>
17 #include <boost/url/rfc/authority_rule.hpp>
18 #include <boost/url/rfc/pct_encoded_rule.hpp>
19 #include <array>
20 #include <ostream>
21
22 namespace boost {
23 namespace urls {
24
25 //------------------------------------------------
26
27 namespace detail {
28
29 authority_view
30 2247 url_impl::
31 construct_authority() const noexcept
32 {
33 2247 return authority_view(*this);
34 }
35
36 } // detail
37
38 //------------------------------------------------
39
40 2247 authority_view::
41 authority_view(
42 2247 detail::url_impl const& u) noexcept
43 2247 : u_(u)
44 {
45 2247 }
46
47 //------------------------------------------------
48
49 23018 authority_view::
50 23018 ~authority_view()
51 {
52 23018 }
53
54 3591 authority_view::
55 3591 authority_view() noexcept
56 3591 : u_(from::authority)
57 {
58 3591 }
59
60 1 authority_view::
61 authority_view(
62 1 core::string_view s)
63 : authority_view(
64 1 parse_authority(s
65
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 ).value(BOOST_URL_POS))
66 {
67 1 }
68
69 authority_view::
70 authority_view(
71 authority_view const&) noexcept = default;
72
73 authority_view&
74 authority_view::
75 operator=(
76 authority_view const&) noexcept = default;
77
78 //------------------------------------------------
79 //
80 // Userinfo
81 //
82 //------------------------------------------------
83
84 bool
85 447 authority_view::
86 has_userinfo() const noexcept
87 {
88 447 auto n = u_.len(id_pass);
89
2/2
✓ Branch 0 taken 355 times.
✓ Branch 1 taken 92 times.
447 if(n == 0)
90 355 return false;
91
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 92 times.
92 BOOST_ASSERT(u_.get(
92 id_pass).ends_with('@'));
93 92 return true;
94 }
95
96 pct_string_view
97 50 authority_view::
98 encoded_userinfo() const noexcept
99 {
100 auto s = u_.get(
101 50 id_user, id_host);
102
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
50 if(s.empty())
103 return s;
104
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
50 BOOST_ASSERT(
105 s.ends_with('@'));
106 50 s.remove_suffix(1);
107 return make_pct_string_view_unsafe(
108 s.data(),
109 s.size(),
110 50 u_.decoded_[id_user] +
111 50 u_.decoded_[id_pass] +
112 50 has_password());
113 }
114
115 pct_string_view
116 73 authority_view::
117 encoded_user() const noexcept
118 {
119 73 auto s = u_.get(id_user);
120 return make_pct_string_view_unsafe(
121 s.data(),
122 s.size(),
123 73 u_.decoded_[id_user]);
124 }
125
126 bool
127 112 authority_view::
128 has_password() const noexcept
129 {
130 112 auto const n = u_.len(id_pass);
131
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 33 times.
112 if(n > 1)
132 {
133
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 79 times.
79 BOOST_ASSERT(u_.get(id_pass
134 ).starts_with(':'));
135
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 79 times.
79 BOOST_ASSERT(u_.get(id_pass
136 ).ends_with('@'));
137 79 return true;
138 }
139
2/4
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 33 times.
33 BOOST_ASSERT(n == 0 || u_.get(
140 id_pass).ends_with('@'));
141 33 return false;
142 }
143
144 pct_string_view
145 57 authority_view::
146 encoded_password() const noexcept
147 {
148 57 auto s = u_.get(id_pass);
149
2/3
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
57 switch(s.size())
150 {
151 8 case 1:
152
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 BOOST_ASSERT(
153 s.starts_with('@'));
154 8 s.remove_prefix(1);
155 BOOST_FALLTHROUGH;
156 8 case 0:
157 return make_pct_string_view_unsafe(
158 8 s.data(), s.size(), 0);
159 49 default:
160 49 break;
161 }
162
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
49 BOOST_ASSERT(s.ends_with('@'));
163
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
49 BOOST_ASSERT(s.starts_with(':'));
164 return make_pct_string_view_unsafe(
165 49 s.data() + 1,
166 49 s.size() - 2,
167 49 u_.decoded_[id_pass]);
168 }
169
170 //------------------------------------------------
171 //
172 // Host
173 //
174 //------------------------------------------------
175 /*
176 host_type host_type() // ipv4, ipv6, ipvfuture, name
177
178 std::string host() // return encoded_host().decode()
179 pct_string_view encoded_host() // return host part, as-is
180 std::string host_address() // return encoded_host_address().decode()
181 pct_string_view encoded_host_address() // ipv4, ipv6, ipvfut, or encoded name, no brackets
182
183 ipv4_address host_ipv4_address() // return ipv4_address or {}
184 ipv6_address host_ipv6_address() // return ipv6_address or {}
185 core::string_view host_ipvfuture() // return ipvfuture or {}
186 std::string host_name() // return decoded name or ""
187 pct_string_view encoded_host_name() // return encoded host name or ""
188 */
189
190 pct_string_view
191 250 authority_view::
192 encoded_host() const noexcept
193 {
194 250 return u_.pct_get(id_host);
195 }
196
197 pct_string_view
198 authority_view::
199 encoded_host_address() const noexcept
200 {
201 core::string_view s = u_.get(id_host);
202 std::size_t n;
203 switch(u_.host_type_)
204 {
205 default:
206 case urls::host_type::none:
207 BOOST_ASSERT(s.empty());
208 n = 0;
209 break;
210
211 case urls::host_type::name:
212 case urls::host_type::ipv4:
213 n = u_.decoded_[id_host];
214 break;
215
216 case urls::host_type::ipv6:
217 case urls::host_type::ipvfuture:
218 {
219 BOOST_ASSERT(
220 u_.decoded_[id_host] ==
221 s.size());
222 BOOST_ASSERT(s.size() >= 2);
223 BOOST_ASSERT(s.front() == '[');
224 BOOST_ASSERT(s.back() == ']');
225 s = s.substr(1, s.size() - 2);
226 n = u_.decoded_[id_host] - 2;
227 break;
228 }
229 }
230 return make_pct_string_view_unsafe(
231 s.data(), s.size(), n);
232 }
233
234 urls::ipv4_address
235 2 authority_view::
236 host_ipv4_address() const noexcept
237 {
238
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(u_.host_type_ !=
239 urls::host_type::ipv4)
240 1 return {};
241 1 ipv4_address::bytes_type b{{}};
242 1 std::memcpy(
243 1 &b[0], &u_.ip_addr_[0], b.size());
244 1 return urls::ipv4_address(b);
245 }
246
247 urls::ipv6_address
248 2 authority_view::
249 host_ipv6_address() const noexcept
250 {
251
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(u_.host_type_ !=
252 urls::host_type::ipv6)
253 1 return {};
254 1 ipv6_address::bytes_type b{{}};
255 1 std::memcpy(
256 1 &b[0], &u_.ip_addr_[0], b.size());
257 1 return urls::ipv6_address(b);
258 }
259
260 core::string_view
261 2 authority_view::
262 host_ipvfuture() const noexcept
263 {
264
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(u_.host_type_ !=
265 urls::host_type::ipvfuture)
266 1 return {};
267 1 core::string_view s = u_.get(id_host);
268
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 BOOST_ASSERT(s.size() >= 6);
269
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 BOOST_ASSERT(s.front() == '[');
270
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 BOOST_ASSERT(s.back() == ']');
271 1 s = s.substr(1, s.size() - 2);
272 1 return s;
273 }
274
275 pct_string_view
276 authority_view::
277 encoded_host_name() const noexcept
278 {
279 if(u_.host_type_ !=
280 urls::host_type::name)
281 return {};
282 return u_.pct_get(id_host);
283 }
284
285 //------------------------------------------------
286 //
287 // Port
288 //
289 //------------------------------------------------
290
291 bool
292 371 authority_view::
293 has_port() const noexcept
294 {
295 371 auto const n = u_.len(id_port);
296
2/2
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 95 times.
371 if(n == 0)
297 276 return false;
298
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 95 times.
95 BOOST_ASSERT(
299 u_.get(id_port).starts_with(':'));
300 95 return true;
301 }
302
303 core::string_view
304 36 authority_view::
305 port() const noexcept
306 {
307 36 auto s = u_.get(id_port);
308
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 32 times.
36 if(s.empty())
309 4 return s;
310
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
32 BOOST_ASSERT(has_port());
311 32 return s.substr(1);
312 }
313
314 std::uint16_t
315 20 authority_view::
316 port_number() const noexcept
317 {
318
3/4
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
20 BOOST_ASSERT(
319 has_port() ||
320 u_.port_number_ == 0);
321 20 return u_.port_number_;
322 }
323
324 pct_string_view
325 10 authority_view::
326 encoded_host_and_port() const noexcept
327 {
328 10 return u_.get(id_host, id_end);
329 }
330
331 //------------------------------------------------
332 //
333 // Parsing
334 //
335 //------------------------------------------------
336
337 system::result<authority_view>
338 42 parse_authority(
339 core::string_view s) noexcept
340 {
341 42 return grammar::parse(s, authority_rule);
342 }
343
344 //------------------------------------------------
345 //
346 // Comparisons
347 //
348 //------------------------------------------------
349
350 int
351 142 authority_view::
352 compare(const authority_view& other) const noexcept
353 {
354 142 auto comp = static_cast<int>(has_userinfo()) -
355 142 static_cast<int>(other.has_userinfo());
356
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 141 times.
142 if ( comp != 0 )
357 1 return comp;
358
359
2/2
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 118 times.
141 if (has_userinfo())
360 {
361 46 comp = detail::compare_encoded(
362 23 encoded_user(),
363 23 other.encoded_user());
364
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 16 times.
23 if ( comp != 0 )
365 7 return comp;
366
367 16 comp = static_cast<int>(has_password()) -
368 16 static_cast<int>(other.has_password());
369
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 15 times.
16 if ( comp != 0 )
370 1 return comp;
371
372
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 if (has_password())
373 {
374 30 comp = detail::compare_encoded(
375 15 encoded_password(),
376 15 other.encoded_password());
377
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 1 times.
15 if ( comp != 0 )
378 14 return comp;
379 }
380 }
381
382 238 comp = detail::ci_compare_encoded(
383 119 encoded_host(),
384 119 other.encoded_host());
385
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 102 times.
119 if ( comp != 0 )
386 17 return comp;
387
388 102 comp = static_cast<int>(has_port()) -
389 102 static_cast<int>(other.has_port());
390
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 95 times.
102 if ( comp != 0 )
391 7 return comp;
392
393
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 87 times.
95 if (has_port())
394 {
395 8 comp = detail::compare(
396 port(),
397 other.port());
398
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 if ( comp != 0 )
399 7 return comp;
400 }
401
402 88 return 0;
403 }
404
405 } // urls
406 } // boost
407
408 #endif
409