Line data Source code
1 : //
2 : // Copyright (c) 2022 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_DETAIL_IMPL_URL_IMPL_HPP
12 : #define BOOST_URL_DETAIL_IMPL_URL_IMPL_HPP
13 :
14 : #include <boost/url/detail/config.hpp>
15 : #include <boost/url/detail/url_impl.hpp>
16 : #include <boost/url/authority_view.hpp>
17 : #include <boost/url/scheme.hpp>
18 : #include <boost/assert.hpp>
19 : #include <cstring>
20 :
21 : namespace boost {
22 : namespace urls {
23 : namespace detail {
24 :
25 : //------------------------------------------------
26 : //
27 : // url_impl
28 : //
29 : //------------------------------------------------
30 :
31 : inline BOOST_URL_CXX20_CONSTEXPR
32 : void
33 2430 : url_impl::
34 : apply_scheme(
35 : core::string_view s) noexcept
36 : {
37 2430 : scheme_ = string_to_scheme(s);
38 2430 : set_size(id_scheme, s.size() + 1);
39 2430 : }
40 :
41 : inline BOOST_URL_CXX20_CONSTEXPR
42 : void
43 405 : url_impl::
44 : apply_userinfo(
45 : pct_string_view const& user,
46 : pct_string_view const* pass) noexcept
47 : {
48 405 : BOOST_ASSERT(from_ == from::authority);
49 :
50 405 : set_size(id_user, user.size());
51 405 : decoded_[id_user] =
52 405 : detail::to_size_type(
53 : user.decoded_size());
54 405 : if(pass)
55 : {
56 270 : set_size(id_pass,
57 270 : pass->size() + 2);
58 270 : decoded_[id_pass] =
59 270 : detail::to_size_type(
60 : pass->decoded_size());
61 : }
62 : else
63 : {
64 135 : set_size(id_pass, 1 );
65 : }
66 405 : }
67 :
68 : inline BOOST_URL_CXX20_CONSTEXPR
69 : void
70 2021 : url_impl::
71 : apply_host(
72 : host_type ht,
73 : pct_string_view s,
74 : unsigned char const* addr) noexcept
75 : {
76 2021 : BOOST_ASSERT(from_ == from::authority);
77 :
78 2021 : host_type_ = ht;
79 2021 : set_size(id_host, s.size());
80 2021 : decoded_[id_host] =
81 2021 : detail::to_size_type(
82 : s.decoded_size());
83 2021 : for(std::size_t i = 0;
84 34357 : i < sizeof(ip_addr_); ++i)
85 32336 : ip_addr_[i] = addr[i];
86 2021 : }
87 :
88 : inline BOOST_URL_CXX20_CONSTEXPR
89 : void
90 284 : url_impl::
91 : apply_port(
92 : core::string_view s,
93 : unsigned short pn) noexcept
94 : {
95 284 : BOOST_ASSERT(from_ == from::authority);
96 :
97 284 : port_number_ = pn;
98 284 : set_size(id_port, 1 + s.size());
99 284 : }
100 :
101 : inline BOOST_URL_CXX20_CONSTEXPR
102 : void
103 1961 : url_impl::
104 : apply_authority(
105 : authority_view const& a) noexcept
106 : {
107 1961 : BOOST_ASSERT(from_ != from::authority);
108 :
109 1961 : set_size(id_user,
110 1961 : a.u_.len(id_user) +
111 1961 : (from_ == from::authority ? 0 : 2));
112 1961 : set_size(id_pass, a.u_.len(id_pass));
113 1961 : decoded_[id_user] = a.u_.decoded_[id_user];
114 1961 : decoded_[id_pass] = a.u_.decoded_[id_pass];
115 :
116 1961 : host_type_ = a.u_.host_type_;
117 1961 : port_number_ = a.u_.port_number_;
118 1961 : set_size(id_host, a.u_.len(id_host));
119 1961 : set_size(id_port, a.u_.len(id_port));
120 1961 : for(std::size_t i = 0;
121 33337 : i < sizeof(ip_addr_); ++i)
122 31376 : ip_addr_[i] = a.u_.ip_addr_[i];
123 1961 : decoded_[id_host] = a.u_.decoded_[id_host];
124 1961 : }
125 :
126 : inline BOOST_URL_CXX20_CONSTEXPR
127 : void
128 3729 : url_impl::
129 : apply_path(
130 : pct_string_view s,
131 : std::size_t nseg) noexcept
132 : {
133 3729 : set_size(id_path, s.size());
134 3729 : decoded_[id_path] =
135 3729 : detail::to_size_type(
136 : s.decoded_size());
137 : // inline path_segments logic
138 : // (original in src/detail/path.hpp)
139 3729 : auto const sz = s.size();
140 3729 : auto const p = s.data();
141 3729 : std::size_t adj = nseg;
142 3729 : switch(sz)
143 : {
144 1167 : case 0:
145 1167 : adj = 0;
146 1167 : break;
147 553 : case 1:
148 553 : adj = (p[0] == '/') ? 0 : 1;
149 553 : break;
150 176 : case 2:
151 176 : if(p[0] == '/')
152 139 : adj = nseg;
153 37 : else if(p[0] == '.' && p[1] == '/')
154 9 : adj = nseg - 1;
155 : else
156 28 : adj = nseg;
157 176 : break;
158 1833 : default:
159 1833 : if(p[0] == '/')
160 : {
161 990 : if(p[1] == '.' && p[2] == '/')
162 44 : adj = nseg - 1;
163 : else
164 946 : adj = nseg;
165 : }
166 843 : else if(p[0] == '.' && p[1] == '/')
167 37 : adj = nseg - 1;
168 : else
169 806 : adj = nseg;
170 1833 : break;
171 : }
172 3729 : nseg_ = detail::to_size_type(adj);
173 3729 : }
174 :
175 : inline BOOST_URL_CXX20_CONSTEXPR
176 : void
177 487 : url_impl::
178 : apply_query(
179 : pct_string_view s,
180 : std::size_t n) noexcept
181 : {
182 487 : nparam_ = detail::to_size_type(n);
183 487 : set_size(id_query, 1 + s.size());
184 487 : decoded_[id_query] =
185 487 : detail::to_size_type(
186 : s.decoded_size());
187 487 : }
188 :
189 : inline BOOST_URL_CXX20_CONSTEXPR
190 : void
191 244 : url_impl::
192 : apply_frag(
193 : pct_string_view s) noexcept
194 : {
195 244 : set_size(id_frag, s.size() + 1);
196 244 : decoded_[id_frag] =
197 244 : detail::to_size_type(
198 : s.decoded_size());
199 244 : }
200 :
201 : // return length of [first, last)
202 : inline BOOST_URL_CXX20_CONSTEXPR
203 : std::size_t
204 20955 : url_impl::
205 : len(
206 : int first,
207 : int last) const noexcept
208 : {
209 20955 : BOOST_ASSERT(first <= last);
210 20955 : BOOST_ASSERT(last <= id_end);
211 20955 : return offset(last) - offset(first);
212 : }
213 :
214 : // return length of part
215 : inline BOOST_URL_CXX20_CONSTEXPR
216 : std::size_t
217 276563 : url_impl::
218 : len(int id) const noexcept
219 : {
220 : return id == id_end
221 553126 : ? zero_
222 276563 : : ( offset(id + 1) -
223 553126 : offset(id) );
224 : }
225 :
226 : // return offset of id
227 : inline BOOST_URL_CXX20_CONSTEXPR
228 : std::size_t
229 723556 : url_impl::
230 : offset(int id) const noexcept
231 : {
232 : return
233 : id == id_scheme
234 723556 : ? zero_
235 723556 : : offset_[id];
236 : }
237 :
238 : // return id as string
239 : inline BOOST_URL_CXX20_CONSTEXPR
240 : core::string_view
241 49375 : url_impl::
242 : get(int id) const noexcept
243 : {
244 : return {
245 49375 : cs_ + offset(id), len(id) };
246 : }
247 :
248 : // return [first, last) as string
249 : inline BOOST_URL_CXX20_CONSTEXPR
250 : core::string_view
251 916 : url_impl::
252 : get(int first,
253 : int last) const noexcept
254 : {
255 916 : return { cs_ + offset(first),
256 916 : offset(last) - offset(first) };
257 : }
258 :
259 : // return id as pct-string
260 : inline BOOST_URL_CXX20_CONSTEXPR
261 : pct_string_view
262 2315 : url_impl::
263 : pct_get(
264 : int id) const noexcept
265 : {
266 2315 : return make_pct_string_view_unsafe(
267 2315 : cs_ + offset(id),
268 : len(id),
269 4630 : decoded_[id]);
270 : }
271 :
272 : // return [first, last) as pct-string
273 : inline BOOST_URL_CXX20_CONSTEXPR
274 : pct_string_view
275 130 : url_impl::
276 : pct_get(
277 : int first,
278 : int last) const noexcept
279 : {
280 130 : auto const pos = offset(first);
281 130 : std::size_t n = 0;
282 420 : for(auto i = first; i < last;)
283 290 : n += decoded_[i++];
284 130 : return make_pct_string_view_unsafe(
285 130 : cs_ + pos,
286 130 : offset(last) - pos,
287 130 : n);
288 : }
289 :
290 : //------------------------------------------------
291 :
292 : // change id to size n
293 : inline BOOST_URL_CXX20_CONSTEXPR
294 : void
295 20632 : url_impl::
296 : set_size(
297 : int id,
298 : std::size_t n) noexcept
299 : {
300 20632 : auto const cur = len(id);
301 20632 : if(n >= cur)
302 : {
303 20267 : auto const d = n - cur;
304 20267 : for(auto i = id + 1;
305 123646 : i <= id_end; ++i)
306 103379 : offset_[i] += detail::to_size_type(d);
307 20267 : return;
308 : }
309 365 : auto const d = cur - n;
310 365 : for(auto i = id + 1;
311 1794 : i <= id_end; ++i)
312 1429 : offset_[i] -= detail::to_size_type(d);
313 : }
314 :
315 : // trim id to size n,
316 : // moving excess into id+1
317 : inline BOOST_URL_CXX20_CONSTEXPR
318 : void
319 891 : url_impl::
320 : split(
321 : int id,
322 : std::size_t n) noexcept
323 : {
324 891 : BOOST_ASSERT(id < id_end - 1);
325 891 : offset_[id + 1] = detail::to_size_type(
326 891 : offset(id) + n);
327 891 : }
328 :
329 : // add n to [first, last]
330 : inline BOOST_URL_CXX20_CONSTEXPR
331 : void
332 979 : url_impl::
333 : adjust_right(
334 : int first,
335 : int last,
336 : std::size_t n) noexcept
337 : {
338 979 : for(int i = first;
339 5720 : i <= last; ++i)
340 4741 : offset_[i] += detail::to_size_type(n);
341 979 : }
342 :
343 : // remove n from [first, last]
344 : inline BOOST_URL_CXX20_CONSTEXPR
345 : void
346 721 : url_impl::
347 : adjust_left(
348 : int first,
349 : int last,
350 : std::size_t n) noexcept
351 : {
352 721 : for(int i = first;
353 3558 : i <= last; ++i)
354 2837 : offset_[i] -= detail::to_size_type(n);
355 721 : }
356 :
357 : // set [first, last) offset
358 : inline BOOST_URL_CXX20_CONSTEXPR
359 : void
360 1681 : url_impl::
361 : collapse(
362 : int first,
363 : int last,
364 : std::size_t n) noexcept
365 : {
366 1681 : for(int i = first + 1;
367 2228 : i < last; ++i)
368 547 : offset_[i] = detail::to_size_type(n);
369 1681 : }
370 :
371 : //------------------------------------------------
372 :
373 : inline BOOST_URL_CXX20_CONSTEXPR
374 : authority_view
375 2533 : url_impl::
376 : construct_authority() const noexcept
377 : {
378 2533 : return authority_view(*this);
379 : }
380 :
381 : // construct() is defined in url_view.hpp
382 : // after the url_view type is complete
383 :
384 : } // detail
385 : } // urls
386 : } // boost
387 :
388 : #endif
|