include/boost/url/impl/authority_view.hpp

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