Line data 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 593 : if(n == 0)
62 501 : return false;
63 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 53 : if(s.empty())
76 2 : return s;
77 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 113 : if(n > 1)
107 : {
108 80 : BOOST_ASSERT(u_.get(id_pass
109 : ).starts_with(':'));
110 80 : BOOST_ASSERT(u_.get(id_pass
111 : ).ends_with('@'));
112 80 : return true;
113 : }
114 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 58 : switch(s.size())
126 : {
127 8 : case 1:
128 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 50 : BOOST_ASSERT(s.ends_with('@'));
139 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 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 2 : BOOST_ASSERT(
178 : u_.decoded_[id_host] ==
179 : s.size());
180 2 : BOOST_ASSERT(s.size() >= 2);
181 2 : BOOST_ASSERT(s.front() == '[');
182 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 : 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 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 : 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 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 : if(u_.host_type_ !=
235 : urls::host_type::ipvfuture)
236 1 : return {};
237 1 : core::string_view s = u_.get(id_host);
238 1 : BOOST_ASSERT(s.size() >= 6);
239 1 : BOOST_ASSERT(s.front() == '[');
240 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 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 593 : if(n == 0)
269 306 : return false;
270 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 114 : if(s.empty())
282 4 : return s;
283 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 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 190 : if ( comp != 0 )
320 1 : return comp;
321 :
322 189 : if (has_userinfo())
323 : {
324 46 : comp = detail::compare_encoded(
325 23 : encoded_user(),
326 23 : other.encoded_user());
327 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 16 : if ( comp != 0 )
333 1 : return comp;
334 :
335 15 : if (has_password())
336 : {
337 30 : comp = detail::compare_encoded(
338 15 : encoded_password(),
339 15 : other.encoded_password());
340 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 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 150 : if ( comp != 0 )
354 7 : return comp;
355 :
356 143 : if (has_port())
357 : {
358 46 : comp = detail::compare(
359 : port(),
360 : other.port());
361 46 : if ( comp != 0 )
362 42 : return comp;
363 : }
364 :
365 101 : return 0;
366 : }
367 :
368 : } // urls
369 : } // boost
370 :
371 : #endif
|