include/boost/url/impl/authority_view.hpp

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