GCC Code Coverage Report


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